From 9fe7ac3c07ff0dd64b3c4c4ef74dac361814bed1 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 4 Nov 2024 13:32:24 +0100 Subject: [PATCH 001/174] morph: fix regressions after Highway implementation (#4240) * morph: fix erode Highway path * morph: sync C-paths with the Highway implementation Previously, `seq->coff` was used both for storing offsets to clear values (zero values in masks) and as an array for non-128 mask coefficients. However, in commit 40e2884 (PR #3618), `seq->coff` was restricted to `guint8` values, making it incompatible for storing offsets. Fix this by syncing the C-paths with the Highway implementation. * morph: prefer bitwise NOT over bitwise XOR `~p` and `p ^ 255` produce the same result on uchar images, as XOR affects only the lowest 8 bits. --- ChangeLog | 2 + libvips/morphology/morph.c | 201 ++++++++++--------------------- libvips/morphology/morph_hwy.cpp | 13 +- 3 files changed, 72 insertions(+), 144 deletions(-) diff --git a/ChangeLog b/ChangeLog index fad4829179..98aab5a735 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,8 @@ - support multipage JXL - fix PFM byte order on little-endian machines [agoode] +- morph: fix erode Highway path [kleisauke] +- morph: fix C-paths with masks containing zero [kleisauke] 10/10/24 8.16.0 diff --git a/libvips/morphology/morph.c b/libvips/morphology/morph.c index c7637177cd..6f4570e6da 100644 --- a/libvips/morphology/morph.c +++ b/libvips/morphology/morph.c @@ -149,10 +149,9 @@ typedef struct { VipsMorph *morph; VipsRegion *ir; /* Input region */ - int *soff; /* Offsets we check for set */ - int ss; /* ... and number we check for set */ - guint8 *coff; /* Offsets we check for clear */ - int cs; /* ... and number we check for clear */ + int *off; /* Offsets for each non-128 matrix element */ + int nn128; /* Number of non-128 mask elements */ + guint8 *coeff; /* Array of non-128 mask coefficients */ int last_bpl; /* Avoid recalcing offsets, if we can */ @@ -212,10 +211,9 @@ vips_morph_start(VipsImage *out, void *a, void *b) */ seq->morph = morph; seq->ir = NULL; - seq->soff = NULL; - seq->ss = 0; - seq->coff = NULL; - seq->cs = 0; + seq->off = NULL; + seq->nn128 = 0; + seq->coeff = NULL; seq->last_bpl = -1; #ifdef HAVE_ORC seq->t1 = NULL; @@ -224,11 +222,11 @@ vips_morph_start(VipsImage *out, void *a, void *b) seq->ir = vips_region_new(in); - seq->soff = VIPS_ARRAY(out, morph->n_point, int); - seq->coff = VIPS_ARRAY(out, morph->n_point, guint8); + seq->off = VIPS_ARRAY(out, morph->n_point, int); + seq->coeff = VIPS_ARRAY(out, morph->n_point, guint8); - if (!seq->soff || - !seq->coff) { + if (!seq->off || + !seq->coeff) { vips_morph_stop(seq, in, morph); return NULL; } @@ -263,13 +261,8 @@ vips_dilate_vector_gen(VipsRegion *out_region, VipsImage *M = morph->M; VipsRegion *ir = seq->ir; - /* Offsets for each non-128 matrix element. - */ - int *soff = seq->soff; - - /* Array of non-128 mask coefficients. - */ - guint8 *coff = seq->coff; + int *off = seq->off; + guint8 *coeff = seq->coeff; VipsRect *r = &out_region->valid; int sz = VIPS_REGION_N_ELEMENTS(out_region); @@ -298,9 +291,7 @@ vips_dilate_vector_gen(VipsRegion *out_region, if (seq->last_bpl != VIPS_REGION_LSKIP(ir)) { seq->last_bpl = VIPS_REGION_LSKIP(ir); - /* Number of non-128 mask elements. - */ - seq->ss = 0; + seq->nn128 = 0; for (t = morph->coeff, y = 0; y < M->Ysize; y++) for (x = 0; x < M->Xsize; x++, t++) { /* Exclude don't-care elements. @@ -308,19 +299,18 @@ vips_dilate_vector_gen(VipsRegion *out_region, if (*t == 128) continue; - soff[seq->ss] = - VIPS_REGION_ADDR(ir, - x + r->left, y + r->top) - + off[seq->nn128] = + VIPS_REGION_ADDR(ir, x + r->left, y + r->top) - VIPS_REGION_ADDR(ir, r->left, r->top); - coff[seq->ss] = *t; - seq->ss++; + coeff[seq->nn128] = *t; + seq->nn128++; } } VIPS_GATE_START("vips_dilate_vector_gen: work"); vips_dilate_uchar_hwy(out_region, ir, r, - sz, seq->ss, soff, coff); + sz, seq->nn128, off, coeff); VIPS_GATE_STOP("vips_dilate_vector_gen: work"); @@ -338,13 +328,8 @@ vips_erode_vector_gen(VipsRegion *out_region, VipsImage *M = morph->M; VipsRegion *ir = seq->ir; - /* Offsets for each non-128 matrix element. - */ - int *soff = seq->soff; - - /* Array of non-128 mask coefficients. - */ - guint8 *coff = seq->coff; + int *off = seq->off; + guint8 *coeff = seq->coeff; VipsRect *r = &out_region->valid; int sz = VIPS_REGION_N_ELEMENTS(out_region); @@ -373,9 +358,7 @@ vips_erode_vector_gen(VipsRegion *out_region, if (seq->last_bpl != VIPS_REGION_LSKIP(ir)) { seq->last_bpl = VIPS_REGION_LSKIP(ir); - /* Number of non-128 mask elements. - */ - seq->ss = 0; + seq->nn128 = 0; for (t = morph->coeff, y = 0; y < M->Ysize; y++) for (x = 0; x < M->Xsize; x++, t++) { /* Exclude don't-care elements. @@ -383,19 +366,18 @@ vips_erode_vector_gen(VipsRegion *out_region, if (*t == 128) continue; - soff[seq->ss] = - VIPS_REGION_ADDR(ir, - x + r->left, y + r->top) - + off[seq->nn128] = + VIPS_REGION_ADDR(ir, x + r->left, y + r->top) - VIPS_REGION_ADDR(ir, r->left, r->top); - coff[seq->ss] = *t; - seq->ss++; + coeff[seq->nn128] = *t; + seq->nn128++; } } VIPS_GATE_START("vips_erode_vector_gen: work"); vips_erode_uchar_hwy(out_region, ir, r, - sz, seq->ss, soff, coff); + sz, seq->nn128, off, coeff); VIPS_GATE_STOP("vips_erode_vector_gen: work"); @@ -667,8 +649,8 @@ vips_dilate_gen(VipsRegion *out_region, VipsImage *M = morph->M; VipsRegion *ir = seq->ir; - int *soff = seq->soff; - guint8 *coff = seq->coff; + int *off = seq->off; + guint8 *coeff = seq->coeff; VipsRect *r = &out_region->valid; int le = r->left; @@ -701,37 +683,24 @@ vips_dilate_gen(VipsRegion *out_region, if (seq->last_bpl != VIPS_REGION_LSKIP(ir)) { seq->last_bpl = VIPS_REGION_LSKIP(ir); - seq->ss = 0; - seq->cs = 0; + seq->nn128 = 0; for (t = morph->coeff, y = 0; y < M->Ysize; y++) - for (x = 0; x < M->Xsize; x++, t++) - switch (*t) { - case 255: - soff[seq->ss++] = - VIPS_REGION_ADDR(ir, - x + le, y + to) - - VIPS_REGION_ADDR(ir, le, to); - break; - - case 128: - break; - - case 0: - coff[seq->cs++] = - VIPS_REGION_ADDR(ir, - x + le, y + to) - - VIPS_REGION_ADDR(ir, le, to); - break; - - default: - g_assert_not_reached(); - } + for (x = 0; x < M->Xsize; x++, t++) { + /* Exclude don't-care elements. + */ + if (*t == 128) + continue; + + off[seq->nn128] = + VIPS_REGION_ADDR(ir, x + le, y + to) - + VIPS_REGION_ADDR(ir, le, to); + coeff[seq->nn128] = *t; + seq->nn128++; + } } VIPS_GATE_START("vips_dilate_gen: work"); - /* Dilate! - */ for (y = to; y < bo; y++) { VipsPel *p = VIPS_REGION_ADDR(ir, le, y); VipsPel *q = VIPS_REGION_ADDR(out_region, le, y); @@ -739,28 +708,11 @@ vips_dilate_gen(VipsRegion *out_region, /* Loop along line. */ for (x = 0; x < sz; x++, q++, p++) { - /* Search for a hit on the set list. + /* Dilate! */ result = 0; - for (i = 0; i < seq->ss; i++) - if (p[soff[i]]) { - /* Found a match! - */ - result = 255; - break; - } - - /* No set pixels ... search for a hit in the clear - * pixels. - */ - if (!result) - for (i = 0; i < seq->cs; i++) - if (!p[coff[i]]) { - /* Found a match! - */ - result = 255; - break; - } + for (i = 0; i < seq->nn128; i++) + result |= !coeff[i] ? ~p[off[i]] : p[off[i]]; *q = result; } @@ -784,8 +736,8 @@ vips_erode_gen(VipsRegion *out_region, VipsImage *M = morph->M; VipsRegion *ir = seq->ir; - int *soff = seq->soff; - guint8 *coff = seq->coff; + int *off = seq->off; + guint8 *coeff = seq->coeff; VipsRect *r = &out_region->valid; int le = r->left; @@ -818,37 +770,24 @@ vips_erode_gen(VipsRegion *out_region, if (seq->last_bpl != VIPS_REGION_LSKIP(ir)) { seq->last_bpl = VIPS_REGION_LSKIP(ir); - seq->ss = 0; - seq->cs = 0; + seq->nn128 = 0; for (t = morph->coeff, y = 0; y < M->Ysize; y++) - for (x = 0; x < M->Xsize; x++, t++) - switch (*t) { - case 255: - soff[seq->ss++] = - VIPS_REGION_ADDR(ir, - x + le, y + to) - - VIPS_REGION_ADDR(ir, le, to); - break; - - case 128: - break; - - case 0: - coff[seq->cs++] = - VIPS_REGION_ADDR(ir, - x + le, y + to) - - VIPS_REGION_ADDR(ir, le, to); - break; - - default: - g_assert_not_reached(); - } + for (x = 0; x < M->Xsize; x++, t++) { + /* Exclude don't-care elements. + */ + if (*t == 128) + continue; + + off[seq->nn128] = + VIPS_REGION_ADDR(ir, x + le, y + to) - + VIPS_REGION_ADDR(ir, le, to); + coeff[seq->nn128] = *t; + seq->nn128++; + } } VIPS_GATE_START("vips_erode_gen: work"); - /* Erode! - */ for (y = to; y < bo; y++) { VipsPel *p = VIPS_REGION_ADDR(ir, le, y); VipsPel *q = VIPS_REGION_ADDR(out_region, le, y); @@ -856,25 +795,11 @@ vips_erode_gen(VipsRegion *out_region, /* Loop along line. */ for (x = 0; x < sz; x++, q++, p++) { - /* Check all set pixels are set. + /* Erode! */ result = 255; - for (i = 0; i < seq->ss; i++) - if (!p[soff[i]]) { - /* Found a mismatch! - */ - result = 0; - break; - } - - /* Check all clear pixels are clear. - */ - if (result) - for (i = 0; i < seq->cs; i++) - if (p[coff[i]]) { - result = 0; - break; - } + for (i = 0; i < seq->nn128; i++) + result &= !coeff[i] ? ~p[off[i]] : p[off[i]]; *q = result; } @@ -950,7 +875,7 @@ vips_morph_build(VipsObject *object) coeff[i]); return -1; } - morph->coeff[i] = coeff[i]; + morph->coeff[i] = (guint8) coeff[i]; } /* Try to make a vector path. diff --git a/libvips/morphology/morph_hwy.cpp b/libvips/morphology/morph_hwy.cpp index 1acdf2cb19..e8c64c8704 100644 --- a/libvips/morphology/morph_hwy.cpp +++ b/libvips/morphology/morph_hwy.cpp @@ -89,7 +89,7 @@ vips_dilate_uchar_hwy(VipsRegion *out_region, VipsRegion *ir, VipsRect *r, */ auto pix = LoadU(du8, p + offsets[i]); - pix = IfThenElse(Ne(mmk, one), Xor(pix, one), pix); + pix = IfThenElse(Ne(mmk, one), AndNot(pix, one), pix); sum = Or(sum, pix); } @@ -109,7 +109,7 @@ vips_dilate_uchar_hwy(VipsRegion *out_region, VipsRegion *ir, VipsRect *r, auto pix = LoadU(du8, p + offsets[i]); if (!coeff[i]) - pix = Xor(pix, one); + pix = AndNot(pix, one); sum = Or(sum, pix); } @@ -146,9 +146,8 @@ vips_erode_uchar_hwy(VipsRegion *out_region, VipsRegion *ir, VipsRect *r, */ auto pix = LoadU(du8, p + offsets[i]); - sum = IfThenElse(Ne(mmk, one), - AndNot(pix, one), - And(sum, pix)); + pix = IfThenElse(Ne(mmk, one), AndNot(pix, one), pix); + sum = And(sum, pix); } StoreU(sum, du8, q + x); @@ -166,7 +165,9 @@ vips_erode_uchar_hwy(VipsRegion *out_region, VipsRegion *ir, VipsRect *r, */ auto pix = LoadU(du8, p + offsets[i]); - sum = !coeff[i] ? AndNot(pix, one) : And(sum, pix); + if (!coeff[i]) + pix = AndNot(pix, one); + sum = And(sum, pix); } q[x] = GetLane(sum); From d91f7b06defc2ad4b64e164307dbcf728af5139d Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 4 Nov 2024 13:33:02 +0100 Subject: [PATCH 002/174] reduce: prefer use of `VIPS_FABS()` (#4243) To ensure we handle negative zero (-0.0) correctly. (cherry picked from commit 852fd7c69ef6903be838fb10937994388fd81263) --- libvips/resample/templates.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libvips/resample/templates.h b/libvips/resample/templates.h index 49a56b5ae5..e652149aa3 100644 --- a/libvips/resample/templates.h +++ b/libvips/resample/templates.h @@ -361,8 +361,7 @@ static double inline filter(double x); template <> double inline filter(double x) { - if (x < 0.0) - x = -x; + x = VIPS_FABS(x); if (x < 1.0) return 1.0 - x; From a26dce4a01472e77ccdb8c5cb316e1fc5303072e Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 5 Nov 2024 11:33:54 +0100 Subject: [PATCH 003/174] Revise ChangeLog note (#4246) --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 98aab5a735..4b99abe5f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,7 @@ 8.16.1 - support multipage JXL -- fix PFM byte order on little-endian machines [agoode] +- fix PFM byte order on big-endian machines [agoode] - morph: fix erode Highway path [kleisauke] - morph: fix C-paths with masks containing zero [kleisauke] From f6aa2bd0a497124666a98c754ccabe3f24ea6c58 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 12 Nov 2024 21:00:04 +0100 Subject: [PATCH 004/174] Fix `--vips-info` CLI flag with GLib >= 2.80 (#4251) Use `g_log_writer_default_set_debug_domains()` since resetting `G_MESSAGES_DEBUG` at runtime has no effect for GLib >= 2.80. Also, remove any checks for the old `G_MESSAGES_DEBUG` env variable and overwrite it directly instead. This means the `--vips-info` CLI flag and the `VIPS_INFO=1` env variable now take precedence over `G_MESSAGES_DEBUG`. See: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3710. --- ChangeLog | 1 + libvips/iofuncs/init.c | 24 +++++++++--------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b99abe5f0..97cf6f8fd5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ - fix PFM byte order on big-endian machines [agoode] - morph: fix erode Highway path [kleisauke] - morph: fix C-paths with masks containing zero [kleisauke] +- fix `--vips-info` CLI flag with GLib >= 2.80 [kleisauke] 10/10/24 8.16.0 diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 5df713b8c6..b6d0db3784 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -363,24 +363,18 @@ set_stacksize(guint64 size) #endif /*HAVE_PTHREAD_DEFAULT_NP*/ } +/** + * Equivalent to setting the `G_MESSAGES_DEBUG=VIPS` environment variable. + */ static void vips_verbose(void) { - const char *old; - - old = g_getenv("G_MESSAGES_DEBUG"); - - if (!old) - g_setenv("G_MESSAGES_DEBUG", G_LOG_DOMAIN, TRUE); - else if (!g_str_equal(old, "all") && - !g_strrstr(old, G_LOG_DOMAIN)) { - char *new; - - new = g_strconcat(old, " ", G_LOG_DOMAIN, NULL); - g_setenv("G_MESSAGES_DEBUG", new, TRUE); - - g_free(new); - } +#if GLIB_CHECK_VERSION(2, 80, 0) + const char *domains[] = { G_LOG_DOMAIN, NULL }; + g_log_writer_default_set_debug_domains(domains); +#else + g_setenv("G_MESSAGES_DEBUG", G_LOG_DOMAIN, TRUE); +#endif } static int From 4ece8726d204b4581cd5e896a7012ab005d9367b Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 17 Nov 2024 13:55:47 +0100 Subject: [PATCH 005/174] Make `subsample-mode=on` and `lossless=true` mutually exclusive (#4263) i.e. always disable chroma subsampling when saving lossless. Resolves: #4232. --- ChangeLog | 1 + libvips/foreign/heifsave.c | 6 ++---- libvips/foreign/jp2ksave.c | 9 ++++++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 97cf6f8fd5..b3b9b92255 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ - morph: fix erode Highway path [kleisauke] - morph: fix C-paths with masks containing zero [kleisauke] - fix `--vips-info` CLI flag with GLib >= 2.80 [kleisauke] +- make `subsample-mode=on` and `lossless=true` mutually exclusive [kleisauke] 10/10/24 8.16.0 diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index e1040650ac..cb1ca66bb4 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -526,11 +526,9 @@ vips_foreign_save_heif_build(VipsObject *object) !vips_object_argument_isset(object, "effort")) heif->effort = 9 - heif->speed; - /* Disable chroma subsampling by default when the "lossless" param - * is being used. + /* The "lossless" param implies no chroma subsampling. */ - if (vips_object_argument_isset(object, "lossless") && - !vips_object_argument_isset(object, "subsample_mode")) + if (heif->lossless) heif->subsample_mode = VIPS_FOREIGN_SUBSAMPLE_OFF; /* Default 12 bit save for 16-bit images. diff --git a/libvips/foreign/jp2ksave.c b/libvips/foreign/jp2ksave.c index e23fd14ff3..bbdc2025ae 100644 --- a/libvips/foreign/jp2ksave.c +++ b/libvips/foreign/jp2ksave.c @@ -819,11 +819,14 @@ vips_foreign_save_jp2k_build(VipsObject *object) return -1; } + /* The "lossless" param implies no chroma subsampling. + */ + if (jp2k->lossless) + jp2k->subsample_mode = VIPS_FOREIGN_SUBSAMPLE_OFF; + switch (jp2k->subsample_mode) { case VIPS_FOREIGN_SUBSAMPLE_AUTO: - jp2k->subsample = - !jp2k->lossless && - jp2k->Q < 90 && + jp2k->subsample = jp2k->Q < 90 && (save->ready->Type == VIPS_INTERPRETATION_sRGB || save->ready->Type == VIPS_INTERPRETATION_RGB16) && save->ready->Bands == 3; From c3abf9f4250138d6b4e2a4cef355d9fa239e327c Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 17 Nov 2024 18:08:14 +0100 Subject: [PATCH 006/174] Fix GIR error after #4251 (#4265) --- libvips/iofuncs/init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index b6d0db3784..75a81abfb2 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -363,8 +363,7 @@ set_stacksize(guint64 size) #endif /*HAVE_PTHREAD_DEFAULT_NP*/ } -/** - * Equivalent to setting the `G_MESSAGES_DEBUG=VIPS` environment variable. +/* Equivalent to setting the `G_MESSAGES_DEBUG=VIPS` environment variable. */ static void vips_verbose(void) From c1a42ac523ccf9362dd76028115bf9ba4532a0d8 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 17 Nov 2024 19:15:00 +0100 Subject: [PATCH 007/174] Avoid using `vips_object_argument_isset()` to check for flags (#4264) --- libvips/foreign/dzsave.c | 2 +- libvips/foreign/ppmsave.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index 922f10776a..19561cf306 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -1955,7 +1955,7 @@ vips_foreign_save_dz_build(VipsObject *object) * or the deprecated "no_strip" turns this off. */ if (!vips_object_argument_isset(object, "keep") && - !vips_object_argument_isset(object, "no_strip")) + !dz->no_strip) save->keep = VIPS_FOREIGN_KEEP_NONE; /* Google, zoomify and iiif default to zero overlap, ".jpg". diff --git a/libvips/foreign/ppmsave.c b/libvips/foreign/ppmsave.c index 3461a1bc45..57e6cc5631 100644 --- a/libvips/foreign/ppmsave.c +++ b/libvips/foreign/ppmsave.c @@ -324,7 +324,7 @@ vips_foreign_save_ppm_build(VipsObject *object) /* Handle the deprecated squash parameter. */ - if (vips_object_argument_isset(object, "squash")) + if (ppm->squash) ppm->bitdepth = 1; if (vips_check_uintorf("vips2ppm", image) || From a901cacfddb8f4edb70ace1a7d4b893d52caacc0 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 25 Nov 2024 12:50:27 +0100 Subject: [PATCH 008/174] Disable `unlimited` flag in fuzzing builds (#4266) The load-specific `unlimited` flag is known to be fuzzing-unfriendly. --- libvips/foreign/heifload.c | 2 ++ libvips/foreign/jpegload.c | 2 ++ libvips/foreign/pngload.c | 2 ++ libvips/foreign/spngload.c | 2 ++ libvips/foreign/svgload.c | 2 ++ test/test-suite/test_foreign.py | 3 --- 6 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libvips/foreign/heifload.c b/libvips/foreign/heifload.c index d50fa045da..3872811abf 100644 --- a/libvips/foreign/heifload.c +++ b/libvips/foreign/heifload.c @@ -1107,12 +1107,14 @@ vips_foreign_load_heif_class_init(VipsForeignLoadHeifClass *class) G_STRUCT_OFFSET(VipsForeignLoadHeif, autorotate), FALSE); +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION VIPS_ARG_BOOL(class, "unlimited", 22, _("Unlimited"), _("Remove all denial of service limits"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsForeignLoadHeif, unlimited), FALSE); +#endif } static gint64 diff --git a/libvips/foreign/jpegload.c b/libvips/foreign/jpegload.c index bb448a778f..f42dfdf33b 100644 --- a/libvips/foreign/jpegload.c +++ b/libvips/foreign/jpegload.c @@ -201,12 +201,14 @@ vips_foreign_load_jpeg_class_init(VipsForeignLoadJpegClass *class) G_STRUCT_OFFSET(VipsForeignLoadJpeg, autorotate), FALSE); +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION VIPS_ARG_BOOL(class, "unlimited", 22, _("Unlimited"), _("Remove all denial of service limits"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsForeignLoadJpeg, unlimited), FALSE); +#endif } static void diff --git a/libvips/foreign/pngload.c b/libvips/foreign/pngload.c index 1eb0b6c58e..1ecadb98cc 100644 --- a/libvips/foreign/pngload.c +++ b/libvips/foreign/pngload.c @@ -166,12 +166,14 @@ vips_foreign_load_png_class_init(VipsForeignLoadPngClass *class) load_class->header = vips_foreign_load_png_header; load_class->load = vips_foreign_load_png_load; +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION VIPS_ARG_BOOL(class, "unlimited", 23, _("Unlimited"), _("Remove all denial of service limits"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsForeignLoadPng, unlimited), FALSE); +#endif } static void diff --git a/libvips/foreign/spngload.c b/libvips/foreign/spngload.c index 9d3a48259f..e4b2d5015b 100644 --- a/libvips/foreign/spngload.c +++ b/libvips/foreign/spngload.c @@ -673,12 +673,14 @@ vips_foreign_load_png_class_init(VipsForeignLoadPngClass *class) load_class->header = vips_foreign_load_png_header; load_class->load = vips_foreign_load_png_load; +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION VIPS_ARG_BOOL(class, "unlimited", 23, _("Unlimited"), _("Remove all denial of service limits"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsForeignLoadPng, unlimited), FALSE); +#endif } static void diff --git a/libvips/foreign/svgload.c b/libvips/foreign/svgload.c index 040cce9ee4..76c21990ed 100644 --- a/libvips/foreign/svgload.c +++ b/libvips/foreign/svgload.c @@ -727,12 +727,14 @@ vips_foreign_load_svg_class_init(VipsForeignLoadSvgClass *class) G_STRUCT_OFFSET(VipsForeignLoadSvg, scale), 0.0, 100000.0, 1.0); +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION VIPS_ARG_BOOL(class, "unlimited", 23, _("Unlimited"), _("Allow SVG of any size"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsForeignLoadSvg, unlimited), FALSE); +#endif } static void diff --git a/test/test-suite/test_foreign.py b/test/test-suite/test_foreign.py index 57c8b79d1c..2dbd05f712 100644 --- a/test/test-suite/test_foreign.py +++ b/test/test-suite/test_foreign.py @@ -1426,9 +1426,6 @@ def heif_valid(im): im = pyvips.Image.heifload(AVIF_FILE_HUGE) assert im.avg() == 0.0 - im = pyvips.Image.heifload(AVIF_FILE_HUGE, unlimited=True) - assert im.avg() == 0.0 - @skip_if_no("heifsave") def test_avifsave(self): self.save_load_buffer("heifsave_buffer", "heifload_buffer", From e8564ae523ea801305227116c3eeb56093f8d39f Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Mon, 25 Nov 2024 11:58:21 +0000 Subject: [PATCH 009/174] CI: Homebrew has switched from pkg-config to pkgconf (#4285) --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 764008045b..0121c95a2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,8 +54,9 @@ jobs: if: runner.os == 'macOS' run: | pip3 install meson --break-system-packages + brew unlink pkg-config@0.29.2 brew install \ - ninja pkg-config \ + ninja pkgconf \ cfitsio cgif fftw fontconfig glib \ highway jpeg-xl libarchive libexif \ libheif libimagequant libmatio librsvg \ From 2d182fd16c8986bc99738a937b9fc87e91677c19 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Tue, 26 Nov 2024 09:43:27 +0000 Subject: [PATCH 010/174] heifsave: prevent use of AV1 intra block copy feature (#4284) Helps ensure encoding time is more predictable/consistent --- ChangeLog | 1 + libvips/foreign/heifsave.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index b3b9b92255..6ab3082fc2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ - morph: fix C-paths with masks containing zero [kleisauke] - fix `--vips-info` CLI flag with GLib >= 2.80 [kleisauke] - make `subsample-mode=on` and `lossless=true` mutually exclusive [kleisauke] +- heifsave: prevent use of AV1 intra block copy feature [lovell] 10/10/24 8.16.0 diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index cb1ca66bb4..6eab243806 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -657,6 +657,17 @@ vips_foreign_save_heif_build(VipsObject *object) return -1; } + /* Try to prevent the AVIF encoder from using intra block copy, + * helps ensure encoding time is more predictable. + */ + error = heif_encoder_set_parameter_boolean(heif->encoder, + "intra-block-copy", FALSE); + if (error.code && + error.subcode != heif_suberror_Unsupported_parameter) { + vips__heif_error(&error); + return -1; + } + /* TODO .. support extra per-encoder params with * heif_encoder_list_parameters(). */ From 030cbf938a577f60a10b5985bce76f3562aa7f6f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 26 Nov 2024 11:51:26 +0000 Subject: [PATCH 011/174] formatting --- libvips/foreign/tiff2vips.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index 3977031811..c9978576ea 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -680,11 +680,9 @@ rtiff_strip_read(Rtiff *rtiff, int strip, tdata_t buf) #endif /*DEBUG_VERBOSE*/ if (rtiff->header.read_scanlinewise) - length = TIFFReadScanline(rtiff->tiff, - buf, strip, (tsample_t) 0); + length = TIFFReadScanline(rtiff->tiff, buf, strip, (tsample_t) 0); else - length = TIFFReadEncodedStrip(rtiff->tiff, - strip, buf, (tsize_t) -1); + length = TIFFReadEncodedStrip(rtiff->tiff, strip, buf, (tsize_t) -1); if (length == -1) { vips_foreign_load_invalidate(rtiff->out); From c0c6546a6544b3cc6e4ec6a4a73db7e6c929a6c7 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 26 Nov 2024 12:56:49 +0000 Subject: [PATCH 012/174] fix dzsave associated images with openslide4 (#4286) openslide4 adds some new metadata items (eg. openslide.associated.label.width) which confuse the test for associated images. This PR adds another check to ensure only image-valued tags are written. Test with eg.: vips dzsave CMU-1.svs[attach-associated] x.szi unzip the SZI and verify that the associated images are correct: $ unzip -qq ../x.szi $ ls x/associated_images/ label.jpg macro.jpg thumbnail.jpg Thanks to @goran-hc See https://github.com/libvips/libvips/issues/4278 --- ChangeLog | 1 + libvips/foreign/dzsave.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6ab3082fc2..65724b098c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ - morph: fix C-paths with masks containing zero [kleisauke] - fix `--vips-info` CLI flag with GLib >= 2.80 [kleisauke] - make `subsample-mode=on` and `lossless=true` mutually exclusive [kleisauke] +- fix SZI write with openslide4 [goran-hc] - heifsave: prevent use of AV1 intra block copy feature [lovell] 10/10/24 8.16.0 diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index 19561cf306..223a3ee566 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -970,7 +970,8 @@ write_associated_images(VipsImage *image, { VipsForeignSaveDz *dz = (VipsForeignSaveDz *) a; - if (vips_isprefix("openslide.associated.", field)) { + if (vips_isprefix("openslide.associated.", field) && + vips_image_get_typeof(image, field) == VIPS_TYPE_IMAGE) { VipsImage *associated; const char *p; const char *q; From 0c7ba7ba03bca5dee197b7f1c8eb092c586170c9 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Wed, 27 Nov 2024 12:44:23 +0000 Subject: [PATCH 013/174] CI: macOS runners no longer include deprecated pkg-config (#4287) --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0121c95a2a..b7c155afee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,7 +54,6 @@ jobs: if: runner.os == 'macOS' run: | pip3 install meson --break-system-packages - brew unlink pkg-config@0.29.2 brew install \ ninja pkgconf \ cfitsio cgif fftw fontconfig glib \ From a379089f4798da362972e504b9e9c0d79856f3ed Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Wed, 27 Nov 2024 13:38:09 +0000 Subject: [PATCH 014/174] heifsave: rename intrabc parameter to match upstream (#4288) The previous name was not part of any published release --- libvips/foreign/heifsave.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index 6eab243806..a4806e58ea 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -661,7 +661,7 @@ vips_foreign_save_heif_build(VipsObject *object) * helps ensure encoding time is more predictable. */ error = heif_encoder_set_parameter_boolean(heif->encoder, - "intra-block-copy", FALSE); + "enable-intrabc", FALSE); if (error.code && error.subcode != heif_suberror_Unsupported_parameter) { vips__heif_error(&error); From 41e1db358643663b65716488f231bb4e1b675465 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 29 Nov 2024 08:51:42 +0000 Subject: [PATCH 015/174] add assemble-animated example --- examples/assemble-animated.c | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 examples/assemble-animated.c diff --git a/examples/assemble-animated.c b/examples/assemble-animated.c new file mode 100644 index 0000000000..91845c3775 --- /dev/null +++ b/examples/assemble-animated.c @@ -0,0 +1,51 @@ +/* compile with + * + * gcc -g -Wall assemble-animated.c `pkg-config vips --cflags --libs` + */ + +#include +#include + +int +main(int argc, char *argv[]) +{ + if (VIPS_INIT(argv[0])) + vips_error_exit(NULL); + if (argc < 3) + vips_error_exit("usage: %s outfile infile1 infile2 ...", argv[0]); + + /* Load a set of input files. + */ + g_autoptr(GPtrArray) frames = g_ptr_array_new_full(argc, g_object_unref); + for (int i = 2; i < argc; i++) { + VipsImage *frame; + if (!(frame = vips_image_new_from_file(argv[i], + "access", VIPS_ACCESS_SEQUENTIAL, + NULL))) + vips_error_exit(NULL); + + g_ptr_array_add(frames, frame); + } + + /* Combine to form a vertical strip. + */ + g_autoptr(VipsImage) strip; + if (vips_arrayjoin((VipsImage **) frames->pdata, &strip, frames->len, + "across", 1, + NULL)) + vips_error_exit(NULL); + + /* Set the animation metadata. Delay times are in milliseconds. + */ + VipsImage *frame0 = VIPS_IMAGE(frames->pdata[0]); + vips_image_set_int(strip, "page-height", frame0->Ysize); + vips_image_set_int(strip, "n-pages", frames->len); + vips_image_set_int(strip, "loop", 10); + int delays[] = { 100, 100, 100 }; + vips_image_set_array_int(strip, "delay", delays, VIPS_NUMBER(delays)); + + if (vips_image_write_to_file(strip, argv[1], NULL)) + vips_error_exit(NULL); + + return 0; +} From c9d16c873501ea78eb3353f5a5af7a4302b96eec Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 30 Nov 2024 16:38:54 +0100 Subject: [PATCH 016/174] threadpool: improve cooperative downsizing (#4293) Turn the exit flag back into a proper count. Fixes a regression introduced in commit 27229aa. --- ChangeLog | 1 + libvips/iofuncs/threadpool.c | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 65724b098c..c9e81033b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ - make `subsample-mode=on` and `lossless=true` mutually exclusive [kleisauke] - fix SZI write with openslide4 [goran-hc] - heifsave: prevent use of AV1 intra block copy feature [lovell] +- threadpool: improve cooperative downsizing [kleisauke] 10/10/24 8.16.0 diff --git a/libvips/iofuncs/threadpool.c b/libvips/iofuncs/threadpool.c index 4706545d92..5d6e7f007a 100644 --- a/libvips/iofuncs/threadpool.c +++ b/libvips/iofuncs/threadpool.c @@ -270,6 +270,11 @@ typedef struct _VipsThreadpool { */ int n_waiting; // (atomic) + /* Increment this and the next worker will decrement and exit if needed + * (used to downsize the threadpool). + */ + int exit; // (atomic) + /* Set this to abort evaluation early with an error. */ gboolean error; @@ -277,11 +282,6 @@ typedef struct _VipsThreadpool { /* Ask threads to exit, either set by allocate, or on free. */ gboolean stop; - - /* Set this and the next worker to see it will clear the flag and exit - * (used to downsize the threadpool). - */ - gboolean exit; // (atomic) } VipsThreadpool; static int @@ -325,7 +325,7 @@ vips_worker_work_unit(VipsWorker *worker) /* Has a thread been asked to exit? Volunteer if yes. */ - if (g_atomic_int_compare_and_exchange(&pool->exit, TRUE, FALSE)) { + if (g_atomic_int_add(&pool->exit, -1) > 0) { /* A thread had been asked to exit, and we've grabbed the * flag. */ @@ -333,6 +333,12 @@ vips_worker_work_unit(VipsWorker *worker) g_mutex_unlock(pool->allocate_lock); return; } + else { + /* No one had been asked to exit and we've mistakenly taken + * the exit count below zero. Put it back up again. + */ + g_atomic_int_inc(&pool->exit); + } if (vips_worker_allocate(worker)) { pool->error = TRUE; @@ -513,7 +519,7 @@ vips_threadpool_new(VipsImage *im) vips_semaphore_init(&pool->tick, 0, "tick"); pool->error = FALSE; pool->stop = FALSE; - pool->exit = FALSE; + pool->exit = 0; /* If this is a tiny image, we won't need all max_workers threads. * Guess how @@ -696,7 +702,7 @@ vips_threadpool_run(VipsImage *im, if (n_waiting > 3 && n_working > 1) { VIPS_DEBUG_MSG("shrinking thread pool\n"); - g_atomic_int_set(&pool->exit, TRUE); + g_atomic_int_inc(&pool->exit); n_working -= 1; } else if (n_waiting < 2 && From e931fbf863a401d09c4ebb2fe1df7445beb8383c Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 2 Dec 2024 17:41:54 +0000 Subject: [PATCH 017/174] try a chapter on multipage and animated images (#4292) * try a chapter on multipage and animated images since this seems to be asked about pretty frequently we'll need to generate an xml version too before merge * spelling, add note on `g_auto()` * Update doc/multipage-and-animated-images.md Co-authored-by: Kleis Auke Wolthuizen * Update doc/multipage-and-animated-images.md Co-authored-by: Kleis Auke Wolthuizen * Update doc/multipage-and-animated-images.md Co-authored-by: Kleis Auke Wolthuizen * Update doc/multipage-and-animated-images.md Co-authored-by: Kleis Auke Wolthuizen * note that libheif has multipage * Update doc/multipage-and-animated-images.md Co-authored-by: Kleis Auke Wolthuizen * Update doc/multipage-and-animated-images.md Co-authored-by: Kleis Auke Wolthuizen * Update doc/multipage-and-animated-images.md Co-authored-by: Kleis Auke Wolthuizen * index, add to build system, small text polish --------- Co-authored-by: Kleis Auke Wolthuizen --- doc/libvips-docs.xml | 1 + doc/meson.build | 2 + doc/multipage-and-animated-images.md | 211 ++++++++++++++++++++++++ doc/multipage-and-animated-images.xml | 221 ++++++++++++++++++++++++++ examples/assemble-animated.c | 7 +- 5 files changed, 440 insertions(+), 2 deletions(-) create mode 100644 doc/multipage-and-animated-images.md create mode 100644 doc/multipage-and-animated-images.xml diff --git a/doc/libvips-docs.xml b/doc/libvips-docs.xml index 0f31388a25..66160342e3 100644 --- a/doc/libvips-docs.xml +++ b/doc/libvips-docs.xml @@ -42,6 +42,7 @@ + diff --git a/doc/meson.build b/doc/meson.build index dc963813ad..b1177743f4 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -63,6 +63,7 @@ markdown_content_files = files( 'libvips-from-C++.md', 'Making-image-pyramids.md', 'Using-vipsthumbnail.md', + 'multipage-and-animated-images.md', ) pandoc = find_program('pandoc', required: false) @@ -103,6 +104,7 @@ else 'libvips-from-C++.xml', 'Making-image-pyramids.xml', 'Using-vipsthumbnail.xml', + 'multipage-and-animated-images.xml', ) endif diff --git a/doc/multipage-and-animated-images.md b/doc/multipage-and-animated-images.md new file mode 100644 index 0000000000..69a163c7af --- /dev/null +++ b/doc/multipage-and-animated-images.md @@ -0,0 +1,211 @@ + + Multipage and animated images + 3 + libvips + + + + Multipage and animated images + Processing multipage and animated images + + +libvips represents animated and multipage images as tall, thin strips of +frames, like a strip of movie film (or a roll of toilet paper). Special image +metadata items are used to hold the page height, the number of frames, and any +frame delay or loop settings. + +At least the JXL, GIF and WebP loaders and savers support animation, +and the TIFF, PDF, HEIC, AVIF and VIPS loaders and savers support multipage. + +# Reading multipage images + +For example, at the command-line, try: + +``` +$ vipsheader -a silver-gear-cogs-animation-5.gif[n=-1] +silver-gear-cogs-animation-5.gif: 281x2560 uchar, 4 bands, srgb, gifload +width: 281 +height: 2560 +bands: 4 +format: uchar +coding: none +interpretation: srgb +xoffset: 0 +yoffset: 0 +xres: 1 +yres: 1 +filename: silver-gear-cogs-animation-5.gif +vips-loader: gifload +page-height: 320 +n-pages: 8 +loop: 0 +delay: 100 100 100 100 100 100 100 100 +background: 0 0 0 +gif-palette: -12500671 -11447983 -723724 -3289651 -11974327 -11711155 -5395027 -13027015 -9276814 -9408400 -16777216 -14079703 -197380 -12237499 -5723992 -526345 -15592942 -12763843 -5921371 -13750738 -13553359 -10592674 -6908266 -7829368 -7960954 -8158333 -809254 +bits-per-sample: 7 +palette: 1 +``` + +Points to note: + +- By default, libvips will just read the first page from an animated or + multipage image. You pass `[n=-1]` to the loader to get all pages (or + frames) in the animation. You can pick out a single page or range of + pages with perhaps `[page=4]` and `[page=2,n=2]`. + +- `page-height` is the vertical size of each frame within the overall image + (2560 pixels high in this case). + +- `n-pages` is the number of pages (or frames) in this animation. Obviously + `n-pages * frame-height == height`, or in this case 320 * 8 == 2560. + +- `loop` is the number of times the animation should loop before stopping. + Zero means "never stop looping". + +- `delay` is an optional array with a time in milliseconds which each frame + should display for. + +You'll see a similar set of metadata for a multipage image, such as a PDF: + +``` +$ vipsheader -a nipguide.pdf[n=-1] +nipguide.pdf: 595x48836 uchar, 4 bands, srgb, pdfload +width: 595 +height: 48836 +bands: 4 +format: uchar +coding: none +interpretation: srgb +xoffset: 0 +yoffset: 0 +xres: 2.83465 +yres: 2.83465 +filename: nipguide.pdf +vips-loader: pdfload +page-height: 842 +pdf-n_pages: 58 +n-pages: 58 +pdf-creator: TeX +pdf-producer: pdfTeX-1.40.16 +``` + +Now there's no `loop` or `delay` since this is not animated, but `n-pages` and +`page-height` are set. In just the same way, you can load all pages, a single +page or a range of pages. + +This all assumes that every page (or frame) has the same dimensions. If +they don't (this can commonly happen with PDF and TIFF), you have to read +pages one by one. + +# Writing multipage images + +As long as these various pieces of metadata are set, you can write animated +and multipage images in the obvious way. For example: + +``` +$ vips copy nipguide.pdf[n=-1] x.gif +``` + +This will take the 58-page PDF and render a 58-frame animation. This only +works because this specific PDF has pages which are all the same size -- +PDFs with (for example) a mix of portrait and landscape pages can't be +handled like this. + +More usefully, you could convert a GIF to WebP with: + +``` +$ vips copy silver-gear-cogs-animation-5.gif[n=-1] silver.webp +``` + +To write an animated or multipage image programmatically, you need to +construct the tall, thin image and set the metadata. For example: + +``` +$ vips arrayjoin "k2.jpg k4a.png" x.tif[page-height=2048] --across=1 +``` + +Provided that the images are both 2048 pixels high, this will write a +two-page TIFF. + +In Python you could write something like: + +```python +#!/usr/bin/env python3 + +import sys +import pyvips + +# the input images -- assume these are all the same size +images = [pyvips.Image.new_from_file(filename, access="sequential") + for filename in sys.argv[2:]] + +# frame delays are in milliseconds +delay_array = [300] * len(images) + +animation = pyvips.Image.arrayjoin(images, across=1).copy() +animation.set_type(pyvips.GValue.gint_type, "loop", 10) +animation.set_type(pyvips.GValue.gint_type, "n-pages", len(images)) +animation.set_type(pyvips.GValue.gint_type, "page-height", images[0].height) +animation.set_type(pyvips.GValue.array_int_type, "delay", delay_array) +print(f"writing {sys.argv[1]} ...") +animation.write_to_file(sys.argv[1]) +``` + +It's a little more fiddly in C: + +```C +/* compile with + * + * gcc -g -Wall assemble-animated.c `pkg-config vips --cflags --libs` + */ + +#include +#include + +/* for libvips before 8.16, add this line: + * G_DEFINE_AUTOPTR_CLEANUP_FUNC(VipsImage, g_object_unref) + */ + +int +main(int argc, char *argv[]) +{ + if (VIPS_INIT(argv[0])) + vips_error_exit(NULL); + if (argc < 3) + vips_error_exit("usage: %s outfile infile1 infile2 ...", argv[0]); + + /* Load a set of input files. + */ + g_autoptr(GPtrArray) frames = g_ptr_array_new_full(argc, g_object_unref); + for (int i = 2; i < argc; i++) { + VipsImage *frame; + if (!(frame = vips_image_new_from_file(argv[i], + "access", VIPS_ACCESS_SEQUENTIAL, + NULL))) + vips_error_exit(NULL); + + g_ptr_array_add(frames, frame); + } + + /* Combine to form a vertical strip. + */ + g_autoptr(VipsImage) strip; + if (vips_arrayjoin((VipsImage **) frames->pdata, &strip, frames->len, + "across", 1, + NULL)) + vips_error_exit(NULL); + + /* Set the animation metadata. Delay times are in milliseconds. + */ + VipsImage *frame0 = VIPS_IMAGE(frames->pdata[0]); + vips_image_set_int(strip, "page-height", frame0->Ysize); + vips_image_set_int(strip, "loop", 10); + int delays[] = { 300, 300, 300 }; + vips_image_set_array_int(strip, "delay", delays, VIPS_NUMBER(delays)); + + if (vips_image_write_to_file(strip, argv[1], NULL)) + vips_error_exit(NULL); + + return 0; +} +``` diff --git a/doc/multipage-and-animated-images.xml b/doc/multipage-and-animated-images.xml new file mode 100644 index 0000000000..7d5edcc51e --- /dev/null +++ b/doc/multipage-and-animated-images.xml @@ -0,0 +1,221 @@ + + + + + + + Multipage and animated images 3 libvips + + + Multipage and animated images Processing multipage and animated images + + + libvips represents animated and multipage images as tall, thin strips of frames, like a strip of movie film (or a roll of toilet paper). Special image metadata items are used to hold the page height, the number of frames, and any frame delay or loop settings. + + + At least the JXL, GIF and WebP loaders and savers support animation, and the TIFF, PDF, HEIC, AVIF and VIPS loaders and savers support multipage. + + + Codestin Search App + + For example, at the command-line, try: + + +$ vipsheader -a silver-gear-cogs-animation-5.gif[n=-1] +silver-gear-cogs-animation-5.gif: 281x2560 uchar, 4 bands, srgb, gifload +width: 281 +height: 2560 +bands: 4 +format: uchar +coding: none +interpretation: srgb +xoffset: 0 +yoffset: 0 +xres: 1 +yres: 1 +filename: silver-gear-cogs-animation-5.gif +vips-loader: gifload +page-height: 320 +n-pages: 8 +loop: 0 +delay: 100 100 100 100 100 100 100 100 +background: 0 0 0 +gif-palette: -12500671 -11447983 -723724 -3289651 -11974327 -11711155 -5395027 -13027015 -9276814 -9408400 -16777216 -14079703 -197380 -12237499 -5723992 -526345 -15592942 -12763843 -5921371 -13750738 -13553359 -10592674 -6908266 -7829368 -7960954 -8158333 -809254 +bits-per-sample: 7 +palette: 1 + + + Points to note: + + + + + By default, libvips will just read the first page from an animated or multipage image. You pass [n=-1] to the loader to get all pages (or frames) in the animation. You can pick out a single page or range of pages with perhaps [page=4] and [page=2,n=2]. + + + + + page-height is the vertical size of each frame within the overall image (2560 pixels high in this case). + + + + + n-pages is the number of pages (or frames) in this animation. Obviously n-pages * frame-height == height, or in this case 320 * 8 == 2560. + + + + + loop is the number of times the animation should loop before stopping. Zero means never stop looping. + + + + + delay is an optional array with a time in milliseconds which each frame should display for. + + + + + You’ll see a similar set of metadata for a multipage image, such as a PDF: + + +$ vipsheader -a nipguide.pdf[n=-1] +nipguide.pdf: 595x48836 uchar, 4 bands, srgb, pdfload +width: 595 +height: 48836 +bands: 4 +format: uchar +coding: none +interpretation: srgb +xoffset: 0 +yoffset: 0 +xres: 2.83465 +yres: 2.83465 +filename: nipguide.pdf +vips-loader: pdfload +page-height: 842 +pdf-n_pages: 58 +n-pages: 58 +pdf-creator: TeX +pdf-producer: pdfTeX-1.40.16 + + + Now there’s no loop or delay since this is not animated, but n-pages and page-height are set. In just the same way, you can load all pages, a single page or a range of pages. + + + This all assumes that every page (or frame) has the same dimensions. If they don’t (this can commonly happen with PDF and TIFF), you have to read pages one by one. + + + + Codestin Search App + + As long as these various pieces of metadata are set, you can write animated and multipage images in the obvious way. For example: + + +$ vips copy nipguide.pdf[n=-1] x.gif + + + This will take the 58-page PDF and render a 58-frame animation. This only works because this specific PDF has pages which are all the same size – PDFs with (for example) a mix of portrait and landscape pages can’t be handled like this. + + + More usefully, you could convert a GIF to WebP with: + + +$ vips copy silver-gear-cogs-animation-5.gif[n=-1] silver.webp + + + To write an animated or multipage image programmatically, you need to construct the tall, thin image and set the metadata. For example: + + +$ vips arrayjoin "k2.jpg k4a.png" x.tif[page-height=2048] --across=1 + + + Provided that the images are both 2048 pixels high, this will write a two-page TIFF. + + + In Python you could write something like: + + +#!/usr/bin/env python3 + +import sys +import pyvips + +# the input images -- assume these are all the same size +images = [pyvips.Image.new_from_file(filename, access="sequential") + for filename in sys.argv[2:]] + +# frame delays are in milliseconds +delay_array = [300] * len(images) + +animation = pyvips.Image.arrayjoin(images, across=1).copy() +animation.set_type(pyvips.GValue.gint_type, "loop", 10) +animation.set_type(pyvips.GValue.gint_type, "n-pages", len(images)) +animation.set_type(pyvips.GValue.gint_type, "page-height", images[0].height) +animation.set_type(pyvips.GValue.array_int_type, "delay", delay_array) +print(f"writing {sys.argv[1]} ...") +animation.write_to_file(sys.argv[1]) + + + It’s a little more fiddly in C: + + +/* compile with + * + * gcc -g -Wall assemble-animated.c `pkg-config vips --cflags --libs` + */ + +#include <stdlib.h> +#include <vips/vips.h> + +/* for libvips before 8.16, add this line: + * G_DEFINE_AUTOPTR_CLEANUP_FUNC(VipsImage, g_object_unref) + */ + +int +main(int argc, char *argv[]) +{ + if (VIPS_INIT(argv[0])) + vips_error_exit(NULL); + if (argc < 3) + vips_error_exit("usage: %s outfile infile1 infile2 ...", argv[0]); + + /* Load a set of input files. + */ + g_autoptr(GPtrArray) frames = g_ptr_array_new_full(argc, g_object_unref); + for (int i = 2; i < argc; i++) { + VipsImage *frame; + if (!(frame = vips_image_new_from_file(argv[i], + "access", VIPS_ACCESS_SEQUENTIAL, + NULL))) + vips_error_exit(NULL); + + g_ptr_array_add(frames, frame); + } + + /* Combine to form a vertical strip. + */ + g_autoptr(VipsImage) strip; + if (vips_arrayjoin((VipsImage **) frames->pdata, &strip, frames->len, + "across", 1, + NULL)) + vips_error_exit(NULL); + + /* Set the animation metadata. Delay times are in milliseconds. + */ + VipsImage *frame0 = VIPS_IMAGE(frames->pdata[0]); + vips_image_set_int(strip, "page-height", frame0->Ysize); + vips_image_set_int(strip, "loop", 10); + int delays[] = { 300, 300, 300 }; + vips_image_set_array_int(strip, "delay", delays, VIPS_NUMBER(delays)); + + if (vips_image_write_to_file(strip, argv[1], NULL)) + vips_error_exit(NULL); + + return 0; +} + + + + + diff --git a/examples/assemble-animated.c b/examples/assemble-animated.c index 91845c3775..31ac691271 100644 --- a/examples/assemble-animated.c +++ b/examples/assemble-animated.c @@ -6,6 +6,10 @@ #include #include +/* for libvips before 8.16, add this line: + * G_DEFINE_AUTOPTR_CLEANUP_FUNC(VipsImage, g_object_unref) + */ + int main(int argc, char *argv[]) { @@ -39,9 +43,8 @@ main(int argc, char *argv[]) */ VipsImage *frame0 = VIPS_IMAGE(frames->pdata[0]); vips_image_set_int(strip, "page-height", frame0->Ysize); - vips_image_set_int(strip, "n-pages", frames->len); vips_image_set_int(strip, "loop", 10); - int delays[] = { 100, 100, 100 }; + int delays[] = { 300, 300, 300 }; vips_image_set_array_int(strip, "delay", delays, VIPS_NUMBER(delays)); if (vips_image_write_to_file(strip, argv[1], NULL)) From 77fdf1b0f84022463dbcf4c2fa3b9f8a5f802ab5 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 4 Dec 2024 14:16:03 +0100 Subject: [PATCH 018/174] shrink{h,v}: improve performance (#4269) * Revert "unroll shrinkh inner loop" This reverts commit 9b968491d366a68ea1008ed29a74f7293501e4c4. * shrinkh: initialize the sum with the addition Instead of adding to the sum during the clip, we could just initialize the sum with the addition. * shrinkv: optimize Remove the sum buffer, we can just use a local, about 7% faster. * Use `gint64` as accumulator type for the uint/int paths To align with `reduce{v,h}`. * shrink{h,v}: add fixed-point arithmetic path for uchar images About 9% faster. --- libvips/resample/shrinkh.c | 60 +++++---- libvips/resample/shrinkv.c | 248 ++++++++++++++----------------------- 2 files changed, 132 insertions(+), 176 deletions(-) diff --git a/libvips/resample/shrinkh.c b/libvips/resample/shrinkh.c index 4b2231ff42..574a44cf59 100644 --- a/libvips/resample/shrinkh.c +++ b/libvips/resample/shrinkh.c @@ -72,9 +72,24 @@ typedef VipsResampleClass VipsShrinkhClass; G_DEFINE_TYPE(VipsShrinkh, vips_shrinkh, VIPS_TYPE_RESAMPLE); -#define INNER(BANDS) \ - sum += p[x1]; \ - x1 += BANDS; +/* Fixed-point arithmetic path for uchar images. + */ +#define UCHAR_SHRINK(BANDS) \ + { \ + unsigned char *restrict p = (unsigned char *) in; \ + unsigned char *restrict q = (unsigned char *) out; \ +\ + for (x = 0; x < width; x++) { \ + for (b = 0; b < BANDS; b++) { \ + int sum = amend; \ + for (x1 = b; x1 < ne; x1 += BANDS) \ + sum += p[x1]; \ + q[b] = (sum * multiplier) >> 24; \ + } \ + p += ne; \ + q += BANDS; \ + } \ + } /* Integer shrink. */ @@ -85,13 +100,10 @@ G_DEFINE_TYPE(VipsShrinkh, vips_shrinkh, VIPS_TYPE_RESAMPLE); \ for (x = 0; x < width; x++) { \ for (b = 0; b < BANDS; b++) { \ - ACC_TYPE sum; \ -\ - sum = 0; \ - x1 = b; \ - VIPS_UNROLL(shrink->hshrink, INNER(BANDS)); \ - q[b] = (sum + shrink->hshrink / 2) / \ - shrink->hshrink; \ + ACC_TYPE sum = amend; \ + for (x1 = b; x1 < ne; x1 += BANDS) \ + sum += p[x1]; \ + q[b] = sum / shrink->hshrink; \ } \ p += ne; \ q += BANDS; \ @@ -107,11 +119,9 @@ G_DEFINE_TYPE(VipsShrinkh, vips_shrinkh, VIPS_TYPE_RESAMPLE); \ for (x = 0; x < width; x++) { \ for (b = 0; b < bands; b++) { \ - double sum; \ -\ - sum = 0.0; \ - x1 = b; \ - VIPS_UNROLL(shrink->hshrink, INNER(bands)); \ + double sum = 0.0; \ + for (x1 = b; x1 < ne; x1 += bands) \ + sum += p[x1]; \ q[b] = sum / shrink->hshrink; \ } \ p += ne; \ @@ -132,11 +142,15 @@ vips_shrinkh_gen2(VipsShrinkh *shrink, VipsRegion *out_region, VipsRegion *ir, VipsPel *out = VIPS_REGION_ADDR(out_region, left, top); VipsPel *in = VIPS_REGION_ADDR(ir, left * shrink->hshrink, top); + int amend = shrink->hshrink / 2; + int x; int x1, b; switch (resample->in->BandFmt) { - case VIPS_FORMAT_UCHAR: + case VIPS_FORMAT_UCHAR: { + unsigned int multiplier = (1LL << 32) / ((1 << 8) * shrink->hshrink); + /* Generate a special path for 1, 3 and 4 band uchar data. The * compiler will be able to vectorise these. * @@ -145,20 +159,20 @@ vips_shrinkh_gen2(VipsShrinkh *shrink, VipsRegion *out_region, VipsRegion *ir, */ switch (bands) { case 1: - ISHRINK(int, unsigned char, 1); + UCHAR_SHRINK(1); break; case 3: - ISHRINK(int, unsigned char, 3); + UCHAR_SHRINK(3); break; case 4: - ISHRINK(int, unsigned char, 4); + UCHAR_SHRINK(4); break; default: - ISHRINK(int, unsigned char, bands); + UCHAR_SHRINK(bands); break; } break; - + } case VIPS_FORMAT_CHAR: ISHRINK(int, char, bands); break; @@ -169,10 +183,10 @@ vips_shrinkh_gen2(VipsShrinkh *shrink, VipsRegion *out_region, VipsRegion *ir, ISHRINK(int, short, bands); break; case VIPS_FORMAT_UINT: - ISHRINK(double, unsigned int, bands); + ISHRINK(gint64, unsigned int, bands); break; case VIPS_FORMAT_INT: - ISHRINK(double, int, bands); + ISHRINK(gint64, int, bands); break; case VIPS_FORMAT_FLOAT: FSHRINK(float); diff --git a/libvips/resample/shrinkv.c b/libvips/resample/shrinkv.c index ad69a71273..3dcb8b07c3 100644 --- a/libvips/resample/shrinkv.c +++ b/libvips/resample/shrinkv.c @@ -90,7 +90,6 @@ #include #include -#include #include #include @@ -103,8 +102,7 @@ typedef struct _VipsShrinkv { VipsResample parent_instance; - int vshrink; /* Shrink factor */ - size_t sizeof_line_buffer; + int vshrink; /* Shrink factor */ gboolean ceil; /* Round operation */ } VipsShrinkv; @@ -113,175 +111,138 @@ typedef VipsResampleClass VipsShrinkvClass; G_DEFINE_TYPE(VipsShrinkv, vips_shrinkv, VIPS_TYPE_RESAMPLE); -/* Our per-sequence parameter struct. Somewhere to sum band elements. +/* Fixed-point arithmetic path for uchar images. */ -typedef struct { - VipsRegion *ir; - - VipsPel *sum; -} VipsShrinkvSequence; - -/* Free a sequence value. - */ -static int -vips_shrinkv_stop(void *vseq, void *a, void *b) -{ - VipsShrinkvSequence *seq = (VipsShrinkvSequence *) vseq; - - VIPS_FREEF(g_object_unref, seq->ir); - VIPS_FREE(seq->sum); - VIPS_FREE(seq); - - return 0; -} - -/* Make a sequence value. - */ -static void * -vips_shrinkv_start(VipsImage *out, void *a, void *b) -{ - VipsImage *in = (VipsImage *) a; - VipsShrinkv *shrink = (VipsShrinkv *) b; - VipsShrinkvSequence *seq; - - if (!(seq = VIPS_NEW(NULL, VipsShrinkvSequence))) - return NULL; - - seq->ir = vips_region_new(in); - - /* Big enough for the largest intermediate .. a whole scanline. - */ - seq->sum = VIPS_ARRAY(NULL, shrink->sizeof_line_buffer, VipsPel); - - return (void *) seq; -} - -#define ADD(ACC_TYPE, TYPE) \ +#define UCHAR_SHRINK(BANDS) \ { \ - ACC_TYPE *restrict sum = (ACC_TYPE *) seq->sum; \ - TYPE *restrict p = (TYPE *) in; \ + unsigned char *restrict p = (unsigned char *) in; \ + unsigned char *restrict q = (unsigned char *) out; \ \ - for (x = 0; x < sz; x++) \ - sum[x] += p[x]; \ - } - -/* Add a line of pixels to sum. - */ -static void -vips_shrinkv_add_line(VipsShrinkv *shrink, VipsShrinkvSequence *seq, - VipsRegion *ir, int left, int top, int width) -{ - VipsResample *resample = VIPS_RESAMPLE(shrink); - const int bands = resample->in->Bands * - (vips_band_format_iscomplex(resample->in->BandFmt) ? 2 : 1); - const int sz = bands * width; - - int x; - - VipsPel *in = VIPS_REGION_ADDR(ir, left, top); - switch (resample->in->BandFmt) { - case VIPS_FORMAT_UCHAR: - ADD(int, unsigned char); - break; - case VIPS_FORMAT_CHAR: - ADD(int, char); - break; - case VIPS_FORMAT_USHORT: - ADD(int, unsigned short); - break; - case VIPS_FORMAT_SHORT: - ADD(int, short); - break; - case VIPS_FORMAT_UINT: - ADD(double, unsigned int); - break; - case VIPS_FORMAT_INT: - ADD(double, int); - break; - case VIPS_FORMAT_FLOAT: - ADD(double, float); - break; - case VIPS_FORMAT_DOUBLE: - ADD(double, double); - break; - case VIPS_FORMAT_COMPLEX: - ADD(double, float); - break; - case VIPS_FORMAT_DPCOMPLEX: - ADD(double, double); - break; - - default: - g_assert_not_reached(); + for (x = 0; x < width; x++) { \ + for (b = 0; b < BANDS; b++) { \ + int sum = amend; \ + unsigned char *restrict ptr = p + b; \ + unsigned char *restrict end = ptr + (shrink->vshrink * sz); \ + for (; ptr < end; ptr += sz) \ + sum += *ptr; \ + q[b] = (sum * multiplier) >> 24; \ + } \ + p += BANDS; \ + q += BANDS; \ + } \ } -} -/* Integer average. +/* Integer shrink. */ -#define IAVG(ACC_TYPE, TYPE) \ +#define ISHRINK(ACC_TYPE, TYPE, BANDS) \ { \ - ACC_TYPE *restrict sum = (ACC_TYPE *) seq->sum; \ + TYPE *restrict p = (TYPE *) in; \ TYPE *restrict q = (TYPE *) out; \ \ - for (x = 0; x < sz; x++) \ - q[x] = (sum[x] + shrink->vshrink / 2) / shrink->vshrink; \ + for (x = 0; x < width; x++) { \ + for (b = 0; b < BANDS; b++) { \ + ACC_TYPE sum = amend; \ + TYPE *restrict ptr = p + b; \ + TYPE *restrict end = ptr + (shrink->vshrink * sz); \ + for (; ptr < end; ptr += sz) \ + sum += *ptr; \ + q[b] = sum / shrink->vshrink; \ + } \ + p += BANDS; \ + q += BANDS; \ + } \ } -/* Float average. +/* Float shrink. */ -#define FAVG(TYPE) \ +#define FSHRINK(TYPE) \ { \ - double *restrict sum = (double *) seq->sum; \ + TYPE *restrict p = (TYPE *) in; \ TYPE *restrict q = (TYPE *) out; \ \ - for (x = 0; x < sz; x++) \ - q[x] = sum[x] / shrink->vshrink; \ + for (x = 0; x < width; x++) { \ + for (b = 0; b < bands; b++) { \ + double sum = 0.0; \ + TYPE *restrict ptr = p + b; \ + TYPE *restrict end = ptr + (shrink->vshrink * sz); \ + for (; ptr < end; ptr += sz) \ + sum += *ptr; \ + q[b] = sum / shrink->vshrink; \ + } \ + p += bands; \ + q += bands; \ + } \ } -/* Average the line of sums to out. +/* Generate an area of @out_region. @ir is large enough. */ static void -vips_shrinkv_write_line(VipsShrinkv *shrink, VipsShrinkvSequence *seq, - VipsRegion *out_region, int left, int top, int width) +vips_shrinkv_gen2(VipsShrinkv *shrink, VipsRegion *out_region, VipsRegion *ir, + int left, int top, int width) { VipsResample *resample = VIPS_RESAMPLE(shrink); const int bands = resample->in->Bands * (vips_band_format_iscomplex(resample->in->BandFmt) ? 2 : 1); - const int sz = bands * width; + const int sz = width * bands; + VipsPel *out = VIPS_REGION_ADDR(out_region, left, top); + VipsPel *in = VIPS_REGION_ADDR(ir, left, top * shrink->vshrink); - int x; + int amend = shrink->vshrink / 2; + + int x, b; - VipsPel *out = VIPS_REGION_ADDR(out_region, left, top); switch (resample->in->BandFmt) { - case VIPS_FORMAT_UCHAR: - IAVG(int, unsigned char); + case VIPS_FORMAT_UCHAR: { + unsigned int multiplier = (1LL << 32) / ((1 << 8) * shrink->vshrink); + + /* Generate a special path for 1, 3 and 4 band uchar data. The + * compiler will be able to vectorise these. + * + * Vectorisation doesn't help much for 16, 32-bit or float + * data, don't bother with them. + */ + switch (bands) { + case 1: + UCHAR_SHRINK(1); + break; + case 3: + UCHAR_SHRINK(3); + break; + case 4: + UCHAR_SHRINK(4); + break; + default: + UCHAR_SHRINK(bands); + break; + } break; + } case VIPS_FORMAT_CHAR: - IAVG(int, char); + ISHRINK(int, char, bands); break; case VIPS_FORMAT_USHORT: - IAVG(int, unsigned short); + ISHRINK(int, unsigned short, bands); break; case VIPS_FORMAT_SHORT: - IAVG(int, short); + ISHRINK(int, short, bands); break; case VIPS_FORMAT_UINT: - IAVG(double, unsigned int); + ISHRINK(gint64, unsigned int, bands); break; case VIPS_FORMAT_INT: - IAVG(double, int); + ISHRINK(gint64, int, bands); break; case VIPS_FORMAT_FLOAT: - FAVG(float); + FSHRINK(float); break; case VIPS_FORMAT_DOUBLE: - FAVG(double); + FSHRINK(double); break; case VIPS_FORMAT_COMPLEX: - FAVG(float); + FSHRINK(float); break; case VIPS_FORMAT_DPCOMPLEX: - FAVG(double); + FSHRINK(double); break; default: @@ -291,11 +252,10 @@ vips_shrinkv_write_line(VipsShrinkv *shrink, VipsShrinkvSequence *seq, static int vips_shrinkv_gen(VipsRegion *out_region, - void *vseq, void *a, void *b, gboolean *stop) + void *seq, void *a, void *b, gboolean *stop) { - VipsShrinkvSequence *seq = (VipsShrinkvSequence *) vseq; VipsShrinkv *shrink = (VipsShrinkv *) b; - VipsRegion *ir = seq->ir; + VipsRegion *ir = (VipsRegion *) seq; VipsRect *r = &out_region->valid; /* How do we chunk up the output image? We don't want to prepare the @@ -309,7 +269,7 @@ vips_shrinkv_gen(VipsRegion *out_region, int input_target = VIPS_MAX(shrink->vshrink, r->height); int dy = input_target / shrink->vshrink; - int y, y1, y2; + int y, y1; #ifdef DEBUG printf("vips_shrinkv_gen: generating %d x %d at %d x %d\n", @@ -334,21 +294,9 @@ vips_shrinkv_gen(VipsRegion *out_region, VIPS_GATE_START("vips_shrinkv_gen: work"); - // each output line - for (y1 = 0; y1 < chunk_height; y1++) { - // top of this line in the input - int top = s.top + y1 * shrink->vshrink; - - memset(seq->sum, 0, shrink->sizeof_line_buffer); - - // each line in the corresponding area of input - for (y2 = 0; y2 < shrink->vshrink; y2++) - vips_shrinkv_add_line(shrink, seq, ir, - s.left, top + y2, s.width); - - vips_shrinkv_write_line(shrink, seq, out_region, + for (y1 = 0; y1 < chunk_height; y1++) + vips_shrinkv_gen2(shrink, out_region, ir, r->left, r->top + y + y1, r->width); - } VIPS_GATE_STOP("vips_shrinkv_gen: work"); } @@ -393,12 +341,6 @@ vips_shrinkv_build(VipsObject *object) return -1; in = t[1]; - /* We have to keep a line buffer as we sum columns. - */ - shrink->sizeof_line_buffer = - in->Xsize * in->Bands * - vips_format_sizeof(VIPS_FORMAT_DPCOMPLEX); - /* SMALLTILE or we'll need huge input areas for our output. In seq * mode, the linecache above will keep us sequential. */ @@ -430,7 +372,7 @@ vips_shrinkv_build(VipsObject *object) #endif /*DEBUG*/ if (vips_image_generate(t[2], - vips_shrinkv_start, vips_shrinkv_gen, vips_shrinkv_stop, + vips_start_one, vips_shrinkv_gen, vips_stop_one, in, shrink)) return -1; From 3ba36cedcbec93283c88d2458ef030dea6becd9a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 4 Dec 2024 14:44:08 +0000 Subject: [PATCH 019/174] fix alpha shift during colourspace conversion (#4302) * fix alpha shift during colourspace conversion The colour functions were not shifting alpha channels, just casting them, so operations which changed depth, like `icc_transform --depth 8` on a 16-bit image, could have an incorrectly scaled alpha. See https://github.com/libvips/libvips/issues/4301 Thanks frederikrosenberg * credit in changelog --- ChangeLog | 1 + libvips/colour/colour.c | 1 + 2 files changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index c9e81033b2..e13b37c190 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,7 @@ - fix SZI write with openslide4 [goran-hc] - heifsave: prevent use of AV1 intra block copy feature [lovell] - threadpool: improve cooperative downsizing [kleisauke] +- fix alpha shift during colourspace conversions [frederikrosenberg] 10/10/24 8.16.0 diff --git a/libvips/colour/colour.c b/libvips/colour/colour.c index c42dcba8ef..b9e0fa92c0 100644 --- a/libvips/colour/colour.c +++ b/libvips/colour/colour.c @@ -371,6 +371,7 @@ vips_colour_build(VipsObject *object) */ if (vips_cast(extra_bands[i], &t1, out->BandFmt, + "shift", TRUE, NULL)) { g_object_unref(out); return -1; From 83fed444230c23c6c91864fe72174d98c7af62a0 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 6 Dec 2024 13:25:28 +0000 Subject: [PATCH 020/174] add tomemory C++ example --- cplusplus/examples/tomemory.cpp | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 cplusplus/examples/tomemory.cpp diff --git a/cplusplus/examples/tomemory.cpp b/cplusplus/examples/tomemory.cpp new file mode 100644 index 0000000000..64b405c646 --- /dev/null +++ b/cplusplus/examples/tomemory.cpp @@ -0,0 +1,46 @@ +/* compile with: + * + * g++ -g -Wall tomemory.cpp `pkg-config vips-cpp --cflags --libs` + */ + +#include +#include + +int +main(int argc, char* argv[]) +{ + if (VIPS_INIT(argv[0])) + vips_error_exit(nullptr); + + for (int i = 0; i < 1000; i++) { + std::cout << "loop " << i << " ..." << std::endl; + + // create a uint8 RGBA VImage + // `black` makes a mono image, so you need to explicitly tag it as srgb + const int width = 50; + const int height = 50; + const int channels = 3; + vips::VImage image = + vips::VImage::black(width, height, vips::VImage::option() + ->set("bands", channels)) + .copy(vips::VImage::option() + ->set("interpretation", "srgb")) + .bandjoin(255); + + // C libvips API to print a vips subclass ... handy for debugging + std::cout << "built: "; + vips_object_print_summary(VIPS_OBJECT(image.get_image())); + + // render to an area of memory ... you can use `.data()`, but this is + // just as quick, and is threadsafe + size_t len; + void *data = image.write_to_memory(&len); + + std::cout << len << " bytes of data at address " << data << std::endl; + + // you own this pointer and must free it + g_free(data); + } + + return 0; +} From 9b5c7246b6136948c9b1ad9b77d26e53c68bf7ab Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 7 Dec 2024 11:37:43 +0000 Subject: [PATCH 021/174] improve line breaks --- libvips/foreign/tiff2vips.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index c9978576ea..ebfa9a1b03 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -1826,8 +1826,7 @@ rtiff_set_header(Rtiff *rtiff, VipsImage *out) vips_connection_filename(VIPS_CONNECTION(rtiff->source))); if (rtiff->n > 1) - vips_image_set_int(out, - VIPS_META_PAGE_HEIGHT, rtiff->header.height); + vips_image_set_int(out, VIPS_META_PAGE_HEIGHT, rtiff->header.height); if (rtiff->header.subifd_count > 0) vips_image_set_int(out, @@ -1843,24 +1842,18 @@ rtiff_set_header(Rtiff *rtiff, VipsImage *out) /* Read any ICC profile. */ - if (TIFFGetField(rtiff->tiff, - TIFFTAG_ICCPROFILE, &data_len, &data)) - vips_image_set_blob_copy(out, - VIPS_META_ICC_NAME, data, data_len); + if (TIFFGetField(rtiff->tiff, TIFFTAG_ICCPROFILE, &data_len, &data)) + vips_image_set_blob_copy(out, VIPS_META_ICC_NAME, data, data_len); /* Read any XMP metadata. */ - if (TIFFGetField(rtiff->tiff, - TIFFTAG_XMLPACKET, &data_len, &data)) - vips_image_set_blob_copy(out, - VIPS_META_XMP_NAME, data, data_len); + if (TIFFGetField(rtiff->tiff, TIFFTAG_XMLPACKET, &data_len, &data)) + vips_image_set_blob_copy(out, VIPS_META_XMP_NAME, data, data_len); /* Read any IPTC metadata. */ - if (TIFFGetField(rtiff->tiff, - TIFFTAG_RICHTIFFIPTC, &data_len, &data)) { - vips_image_set_blob_copy(out, - VIPS_META_IPTC_NAME, data, data_len); + if (TIFFGetField(rtiff->tiff, TIFFTAG_RICHTIFFIPTC, &data_len, &data)) { + vips_image_set_blob_copy(out, VIPS_META_IPTC_NAME, data, data_len); /* Older versions of libvips used this misspelt name :-( attach * under this name too for compatibility. @@ -1870,10 +1863,8 @@ rtiff_set_header(Rtiff *rtiff, VipsImage *out) /* Read any photoshop metadata. */ - if (TIFFGetField(rtiff->tiff, - TIFFTAG_PHOTOSHOP, &data_len, &data)) - vips_image_set_blob_copy(out, - VIPS_META_PHOTOSHOP_NAME, data, data_len); + if (TIFFGetField(rtiff->tiff, TIFFTAG_PHOTOSHOP, &data_len, &data)) + vips_image_set_blob_copy(out, VIPS_META_PHOTOSHOP_NAME, data, data_len); if (rtiff->header.image_description) vips_image_set_string(out, VIPS_META_IMAGEDESCRIPTION, @@ -1888,8 +1879,7 @@ rtiff_set_header(Rtiff *rtiff, VipsImage *out) /* Set the "orientation" tag. This is picked up later by autorot, if * requested. */ - vips_image_set_int(out, - VIPS_META_ORIENTATION, rtiff->header.orientation); + vips_image_set_int(out, VIPS_META_ORIENTATION, rtiff->header.orientation); /* Hint smalltile for tiled images, since we may be decompressing * outside the lock and THINSTRIP would prevent parallel tile decode. From 681a06340f22620559eb26b4037c9e9acc3e90b8 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Wed, 11 Dec 2024 12:42:08 +0000 Subject: [PATCH 022/174] tiff: add thread-safe warning/error handlers, requires libtiff 4.5.0+ (#4313) --- ChangeLog | 1 + libvips/foreign/tiff.c | 58 +++++++++++++++++++++++++++++++-- libvips/foreign/tiff.h | 11 +++++-- libvips/foreign/tiff2vips.c | 43 ++++++++++++++++++++++-- libvips/foreign/tiffload.c | 7 ++++ libvips/foreign/vips2tiff.c | 22 +++++++++++-- meson.build | 4 +++ test/test-suite/test_foreign.py | 9 +++++ 8 files changed, 147 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0683a199dd..39e612f392 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ - add `keep_duplicate_frames` option to GIF save [dloebl] - add Magic Kernel support [akimon658] +- tiff: add threadsafe warning/error handlers (requires libtiff 4.5.0+) [lovell] 8.16.1 diff --git a/libvips/foreign/tiff.c b/libvips/foreign/tiff.c index 2cf2761384..a6ad9c403a 100644 --- a/libvips/foreign/tiff.c +++ b/libvips/foreign/tiff.c @@ -59,6 +59,11 @@ #include "tiff.h" +#ifdef HAVE_TIFF_OPEN_OPTIONS +void +vips__tiff_init(void) {} +#else + /* Handle TIFF errors here. Shared with vips2tiff.c. These can be called from * more than one thread. */ @@ -89,6 +94,7 @@ vips__tiff_init(void) TIFFSetErrorHandler(vips__thandler_error); TIFFSetWarningHandler(vips__thandler_warning); } +#endif /*HAVE_TIFF_OPEN_OPTIONS*/ /* TIFF input from a vips source. */ @@ -157,7 +163,8 @@ openin_source_unmap(thandle_t st, tdata_t start, toff_t len) } TIFF * -vips__tiff_openin_source(VipsSource *source) +vips__tiff_openin_source(VipsSource *source, VipsTiffErrorHandler error_fn, + VipsTiffErrorHandler warning_fn, void *user_data) { TIFF *tiff; @@ -175,6 +182,28 @@ vips__tiff_openin_source(VipsSource *source) * chopped into c. 8kb chunks. This can reduce peak memory use for * this type of file. */ + +#ifdef HAVE_TIFF_OPEN_OPTIONS + TIFFOpenOptions *opts = TIFFOpenOptionsAlloc(); + TIFFOpenOptionsSetErrorHandlerExtR(opts, error_fn, user_data); + TIFFOpenOptionsSetWarningHandlerExtR(opts, warning_fn, user_data); + if (!(tiff = TIFFClientOpenExt("source input", "rmC", + (thandle_t) source, + openin_source_read, + openin_source_write, + openin_source_seek, + openin_source_close, + openin_source_length, + openin_source_map, + openin_source_unmap, + opts))) { + TIFFOpenOptionsFree(opts); + vips_error("vips__tiff_openin_source", "%s", + _("unable to open source for input")); + return NULL; + } + TIFFOpenOptionsFree(opts); +#else if (!(tiff = TIFFClientOpen("source input", "rmC", (thandle_t) source, openin_source_read, @@ -188,6 +217,7 @@ vips__tiff_openin_source(VipsSource *source) _("unable to open source for input")); return NULL; } +#endif /*HAVE_TIFF_OPEN_OPTIONS*/ /* Unreffed on close(), see above. */ @@ -264,7 +294,9 @@ openout_target_unmap(thandle_t st, tdata_t start, toff_t len) } TIFF * -vips__tiff_openout_target(VipsTarget *target, gboolean bigtiff) +vips__tiff_openout_target(VipsTarget *target, gboolean bigtiff, + VipsTiffErrorHandler error_fn, VipsTiffErrorHandler warning_fn, + void *user_data) { const char *mode = bigtiff ? "w8" : "w"; @@ -274,6 +306,27 @@ vips__tiff_openout_target(VipsTarget *target, gboolean bigtiff) printf("vips__tiff_openout_buffer:\n"); #endif /*DEBUG*/ +#ifdef HAVE_TIFF_OPEN_OPTIONS + TIFFOpenOptions *opts = TIFFOpenOptionsAlloc(); + TIFFOpenOptionsSetErrorHandlerExtR(opts, error_fn, user_data); + TIFFOpenOptionsSetWarningHandlerExtR(opts, warning_fn, user_data); + if (!(tiff = TIFFClientOpenExt("target output", mode, + (thandle_t) target, + openout_target_read, + openout_target_write, + openout_target_seek, + openout_target_close, + openout_target_length, + openout_target_map, + openout_target_unmap, + opts))) { + TIFFOpenOptionsFree(opts); + vips_error("vips__tiff_openout_target", "%s", + _("unable to open target for output")); + return NULL; + } + TIFFOpenOptionsFree(opts); +#else if (!(tiff = TIFFClientOpen("target output", mode, (thandle_t) target, openout_target_read, @@ -287,6 +340,7 @@ vips__tiff_openout_target(VipsTarget *target, gboolean bigtiff) _("unable to open target for output")); return NULL; } +#endif /*HAVE_TIFF_OPEN_OPTIONS*/ return tiff; } diff --git a/libvips/foreign/tiff.h b/libvips/foreign/tiff.h index f67167e4a0..e0619686e4 100644 --- a/libvips/foreign/tiff.h +++ b/libvips/foreign/tiff.h @@ -37,10 +37,17 @@ extern "C" { #endif /*__cplusplus*/ -TIFF *vips__tiff_openin_source(VipsSource *source); +typedef int (*VipsTiffErrorHandler)(TIFF *tiff, void* user_data, + const char *module, const char *fmt, va_list ap); + +TIFF *vips__tiff_openin_source(VipsSource *source, + VipsTiffErrorHandler error_fn, VipsTiffErrorHandler warning_fn, + void *user_data); TIFF *vips__tiff_openout(const char *path, gboolean bigtiff); -TIFF *vips__tiff_openout_target(VipsTarget *target, gboolean bigtiff); +TIFF *vips__tiff_openout_target(VipsTarget *target, gboolean bigtiff, + VipsTiffErrorHandler error_fn, VipsTiffErrorHandler warning_fn, + void *user_data); #ifdef __cplusplus } diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index ebfa9a1b03..96a3e88e8c 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -428,6 +428,10 @@ typedef struct _Rtiff { /* The Y we are reading at. Used to verify strip read is sequential. */ int y_pos; + + /* Stop processing due to an error or warning. + */ + gboolean failed; } Rtiff; /* Convert IEEE 754-2008 16-bit float to 32-bit float @@ -614,6 +618,28 @@ rtiff_minimise_cb(VipsImage *image, Rtiff *rtiff) vips_source_minimise(rtiff->source); } +static int +rtiff_handler_error(TIFF *tiff, void* user_data, + const char *module, const char *fmt, va_list ap) +{ + vips_verror("tiff2vips", fmt, ap); + return 1; +} + +static int +rtiff_handler_warning(TIFF *tiff, void* user_data, + const char *module, const char *fmt, va_list ap) +{ + if (user_data) { + Rtiff *rtiff = (Rtiff*) user_data; + if (rtiff->fail_on >= VIPS_FAIL_ON_WARNING) { + rtiff->failed = TRUE; + } + } + g_logv("tiff2vips", G_LOG_LEVEL_WARNING, fmt, ap); + return 1; +} + static Rtiff * rtiff_new(VipsSource *source, VipsImage *out, int page, int n, gboolean autorotate, int subifd, VipsFailOn fail_on) @@ -641,6 +667,7 @@ rtiff_new(VipsSource *source, VipsImage *out, rtiff->plane_buf = NULL; rtiff->contig_buf = NULL; rtiff->y_pos = 0; + rtiff->failed = FALSE; g_signal_connect(out, "close", G_CALLBACK(rtiff_close_cb), rtiff); @@ -664,7 +691,8 @@ rtiff_new(VipsSource *source, VipsImage *out, return NULL; } - if (!(rtiff->tiff = vips__tiff_openin_source(source))) + if (!(rtiff->tiff = vips__tiff_openin_source(source, + rtiff_handler_error, rtiff_handler_warning, rtiff))) return NULL; return rtiff; @@ -690,6 +718,11 @@ rtiff_strip_read(Rtiff *rtiff, int strip, tdata_t buf) return -1; } + if (rtiff->failed) { + vips_foreign_load_invalidate(rtiff->out); + return -1; + } + return 0; } @@ -729,6 +762,11 @@ rtiff_rgba_strip_read(Rtiff *rtiff, int strip, tdata_t buf) TIFFRGBAImageEnd(&img); + if (rtiff->failed) { + vips_foreign_load_invalidate(rtiff->out); + return -1; + } + return 0; } @@ -3396,7 +3434,8 @@ vips__testtiff_source(VipsSource *source, TiffPropertyFn fn) vips__tiff_init(); - if (!(tif = vips__tiff_openin_source(source))) { + if (!(tif = vips__tiff_openin_source(source, rtiff_handler_error, + rtiff_handler_warning, NULL))) { vips_error_clear(); return FALSE; } diff --git a/libvips/foreign/tiffload.c b/libvips/foreign/tiffload.c index 036ad8aa71..a192f98fdd 100644 --- a/libvips/foreign/tiffload.c +++ b/libvips/foreign/tiffload.c @@ -215,6 +215,7 @@ vips_foreign_load_tiff_class_init(VipsForeignLoadTiffClass *class) VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsForeignLoadTiff, subifd), -1, 100000, -1); + } static void @@ -470,6 +471,7 @@ vips_foreign_load_tiff_buffer_init(VipsForeignLoadTiffBuffer *buffer) * * @autorotate: %gboolean, use orientation tag to rotate the image * during load * * @subifd: %gint, select this subifd index + * * @fail_on: #VipsFailOn, types of read error to fail on * * Read a TIFF file into a VIPS image. It is a full baseline TIFF 6 reader, * with extensions for tiled images, multipage images, XYZ and LAB colour @@ -502,6 +504,9 @@ vips_foreign_load_tiff_buffer_init(VipsForeignLoadTiffBuffer *buffer) * selected. This can be used to read lower resolution layers from * bioformats-style image pyramids. * + * Use @fail_on to set the type of error that will cause load to fail. By + * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. + * * Any ICC profile is read and attached to the VIPS image as * #VIPS_META_ICC_NAME. Any XMP metadata is read and attached to the image * as #VIPS_META_XMP_NAME. Any IPTC is attached as #VIPS_META_IPTC_NAME. The @@ -540,6 +545,7 @@ vips_tiffload(const char *filename, VipsImage **out, ...) * * @autorotate: %gboolean, use orientation tag to rotate the image * during load * * @subifd: %gint, select this subifd index + * * @fail_on: #VipsFailOn, types of read error to fail on * * Read a TIFF-formatted memory block into a VIPS image. Exactly as * vips_tiffload(), but read from a memory source. @@ -584,6 +590,7 @@ vips_tiffload_buffer(void *buf, size_t len, VipsImage **out, ...) * * @autorotate: %gboolean, use orientation tag to rotate the image * during load * * @subifd: %gint, select this subifd index + * * @fail_on: #VipsFailOn, types of read error to fail on * * Exactly as vips_tiffload(), but read from a source. * diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 7a93d0f3d2..12f387dc55 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -441,6 +441,22 @@ embed_profile_meta(TIFF *tif, VipsImage *im) return 0; } +static int +wtiff_handler_error(TIFF *tiff, void* user_data, + const char *module, const char *fmt, va_list ap) +{ + vips_verror("vips2tiff", fmt, ap); + return 1; +} + +static int +wtiff_handler_warning(TIFF *tiff, void* user_data, + const char *module, const char *fmt, va_list ap) +{ + g_logv("vips2tiff", G_LOG_LEVEL_WARNING, fmt, ap); + return 1; +} + static void wtiff_layer_init(Wtiff *wtiff, Layer **layer, Layer *above, int width, int height) @@ -1146,7 +1162,8 @@ wtiff_allocate_layers(Wtiff *wtiff) vips__region_no_ownership(layer->copy); layer->tif = vips__tiff_openout_target(layer->target, - wtiff->bigtiff); + wtiff->bigtiff, wtiff_handler_error, + wtiff_handler_warning, wtiff); if (!layer->tif) return -1; } @@ -2401,7 +2418,8 @@ wtiff_gather(Wtiff *wtiff) if (!(source = vips_source_new_from_target(layer->target))) return -1; - if (!(in = vips__tiff_openin_source(source))) { + if (!(in = vips__tiff_openin_source(source, wtiff_handler_error, + wtiff_handler_warning, NULL))) { VIPS_UNREF(source); return -1; } diff --git a/meson.build b/meson.build index 5f56fb9b74..ccd3928b8b 100644 --- a/meson.build +++ b/meson.build @@ -414,6 +414,10 @@ if libtiff_dep.found() if cc.get_define('COMPRESSION_WEBP', prefix: '#include ', dependencies: libtiff_dep) != '' cfg_var.set('HAVE_TIFF_COMPRESSION_WEBP', '1') endif + # TIFFOpenOptions added in libtiff 4.5.0 + if cc.has_function('TIFFOpenOptionsAlloc', prefix: '#include ', dependencies: libtiff_dep) + cfg_var.set('HAVE_TIFF_OPEN_OPTIONS', '1') + endif endif # 2.40.3 so we get the UNLIMITED open flag diff --git a/test/test-suite/test_foreign.py b/test/test-suite/test_foreign.py index 2dbd05f712..8ddbd2cd90 100644 --- a/test/test-suite/test_foreign.py +++ b/test/test-suite/test_foreign.py @@ -662,6 +662,15 @@ def tiff_subsampled_valid(im): assert x1.xres == 100 assert x1.yres == 200 + if sys.platform == "darwin": + with open(TIF2_FILE, 'rb') as f: + buf = bytearray(f.read()) + buf = buf[:-4] + source = pyvips.Source.new_from_memory(buf) + im = pyvips.Image.tiffload_source(source, fail_on="warning") + with pytest.raises(Exception) as e_info: + im.avg() > 0 + # OME support in 8.5 x = pyvips.Image.new_from_file(OME_FILE) assert x.width == 439 From 33ab2ccfaa81e999bd7e2bf0375d461cef895279 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Mon, 16 Dec 2024 21:27:19 +0000 Subject: [PATCH 023/174] heifsave: set image orientation using irot and imir (#4314) --- ChangeLog | 1 + libvips/foreign/heifsave.c | 8 ++++++++ meson.build | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index e13b37c190..8ff41c5cc9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ - heifsave: prevent use of AV1 intra block copy feature [lovell] - threadpool: improve cooperative downsizing [kleisauke] - fix alpha shift during colourspace conversions [frederikrosenberg] +- heifsave: set image orientation using irot and imir transformations [lovell] 10/10/24 8.16.0 diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index a4806e58ea..ddb1a40c25 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -311,6 +311,14 @@ vips_foreign_save_heif_write_page(VipsForeignSaveHeif *heif, int page) } #endif /*HAVE_HEIF_ENCODING_OPTIONS_OUTPUT_NCLX_PROFILE*/ +#ifdef HAVE_HEIF_ENCODING_OPTIONS_IMAGE_ORIENTATION + /* EXIF orientation is informational in the HEIF specification. + * Orientation is defined using irot and imir transformations. + */ + options->image_orientation = vips_image_get_orientation(save->ready); + vips_autorot_remove_angle(save->ready); +#endif + #ifdef DEBUG { GTimer *timer = g_timer_new(); diff --git a/meson.build b/meson.build index 21797c1b6f..86ef36bb87 100644 --- a/meson.build +++ b/meson.build @@ -561,6 +561,10 @@ if libheif_dep.found() if libheif_dep.version().version_compare('>=1.13.0') cfg_var.set('HAVE_HEIF_INIT', '1') endif + # heif_encoding_options.image_orientation added in 1.14.0 + if cpp.has_member('struct heif_encoding_options', 'image_orientation', prefix: '#include ', dependencies: libheif_dep) + cfg_var.set('HAVE_HEIF_ENCODING_OPTIONS_IMAGE_ORIENTATION', '1') + endif # heif_error_success added in 1.17.0 if libheif_dep.version().version_compare('>=1.17.0') cfg_var.set('HAVE_HEIF_ERROR_SUCCESS', '1') From 1ad652636bf80190860afde5f4a0365f71dd0301 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 19 Dec 2024 17:57:24 +0100 Subject: [PATCH 024/174] shrinkv: fix region stride handling (#4320) Always use `VIPS_REGION_LSKIP()` to move down one line, as regions may have non-contiguous scanlines. --- libvips/resample/shrinkv.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libvips/resample/shrinkv.c b/libvips/resample/shrinkv.c index 3dcb8b07c3..a6691cd56d 100644 --- a/libvips/resample/shrinkv.c +++ b/libvips/resample/shrinkv.c @@ -122,8 +122,8 @@ G_DEFINE_TYPE(VipsShrinkv, vips_shrinkv, VIPS_TYPE_RESAMPLE); for (b = 0; b < BANDS; b++) { \ int sum = amend; \ unsigned char *restrict ptr = p + b; \ - unsigned char *restrict end = ptr + (shrink->vshrink * sz); \ - for (; ptr < end; ptr += sz) \ + unsigned char *restrict end = ptr + (shrink->vshrink * ls); \ + for (; ptr < end; ptr += ls) \ sum += *ptr; \ q[b] = (sum * multiplier) >> 24; \ } \ @@ -143,8 +143,8 @@ G_DEFINE_TYPE(VipsShrinkv, vips_shrinkv, VIPS_TYPE_RESAMPLE); for (b = 0; b < BANDS; b++) { \ ACC_TYPE sum = amend; \ TYPE *restrict ptr = p + b; \ - TYPE *restrict end = ptr + (shrink->vshrink * sz); \ - for (; ptr < end; ptr += sz) \ + TYPE *restrict end = ptr + (shrink->vshrink * ls); \ + for (; ptr < end; ptr += ls) \ sum += *ptr; \ q[b] = sum / shrink->vshrink; \ } \ @@ -164,8 +164,8 @@ G_DEFINE_TYPE(VipsShrinkv, vips_shrinkv, VIPS_TYPE_RESAMPLE); for (b = 0; b < bands; b++) { \ double sum = 0.0; \ TYPE *restrict ptr = p + b; \ - TYPE *restrict end = ptr + (shrink->vshrink * sz); \ - for (; ptr < end; ptr += sz) \ + TYPE *restrict end = ptr + (shrink->vshrink * ls); \ + for (; ptr < end; ptr += ls) \ sum += *ptr; \ q[b] = sum / shrink->vshrink; \ } \ @@ -183,7 +183,8 @@ vips_shrinkv_gen2(VipsShrinkv *shrink, VipsRegion *out_region, VipsRegion *ir, VipsResample *resample = VIPS_RESAMPLE(shrink); const int bands = resample->in->Bands * (vips_band_format_iscomplex(resample->in->BandFmt) ? 2 : 1); - const int sz = width * bands; + const int ls = VIPS_REGION_LSKIP(ir) / + VIPS_IMAGE_SIZEOF_ELEMENT(resample->in); VipsPel *out = VIPS_REGION_ADDR(out_region, left, top); VipsPel *in = VIPS_REGION_ADDR(ir, left, top * shrink->vshrink); From dee0d89ff385407b65f8526657a5cdb3b1e82bb9 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Thu, 19 Dec 2024 16:59:43 +0000 Subject: [PATCH 025/174] tiffload: add support for unlimited flag, requires libtiff 4.7.0+ (#4322) Default limit for cumulative allocation to 20MB, which is enough for hundreds of tags. Due to the way libtiff likes to re-allocate memory, an image with thousands of tags can quickly lead to fragmentation. --- ChangeLog | 1 + libvips/deprecated/im_tiff2vips.c | 4 ++-- libvips/foreign/pforeign.h | 6 ++++-- libvips/foreign/tiff.c | 7 ++++++- libvips/foreign/tiff.h | 2 +- libvips/foreign/tiff2vips.c | 17 ++++++++++------- libvips/foreign/tiffload.c | 26 +++++++++++++++++++++++--- libvips/foreign/vips2tiff.c | 2 +- meson.build | 4 ++++ 9 files changed, 52 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 39e612f392..99f7ffb76e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ - add `keep_duplicate_frames` option to GIF save [dloebl] - add Magic Kernel support [akimon658] - tiff: add threadsafe warning/error handlers (requires libtiff 4.5.0+) [lovell] +- tiffload: add support for unlimited flag (requires libtiff 4.7.0+) [lovell] 8.16.1 diff --git a/libvips/deprecated/im_tiff2vips.c b/libvips/deprecated/im_tiff2vips.c index e43b34646e..ff8977bb4e 100644 --- a/libvips/deprecated/im_tiff2vips.c +++ b/libvips/deprecated/im_tiff2vips.c @@ -75,7 +75,7 @@ im_tiff_read_header(const char *filename, VipsImage *out, if (!(source = vips_source_new_from_file(filename))) return -1; if (vips__tiff_read_header_source(source, out, - page, n, autorotate, -1, VIPS_FAIL_ON_ERROR)) { + page, n, autorotate, -1, VIPS_FAIL_ON_ERROR, TRUE)) { VIPS_UNREF(source); return -1; } @@ -93,7 +93,7 @@ im_tiff_read(const char *filename, VipsImage *out, if (!(source = vips_source_new_from_file(filename))) return -1; if (vips__tiff_read_source(source, out, - page, n, autorotate, -1, VIPS_FAIL_ON_ERROR)) { + page, n, autorotate, -1, VIPS_FAIL_ON_ERROR, TRUE)) { VIPS_UNREF(source); return -1; } diff --git a/libvips/foreign/pforeign.h b/libvips/foreign/pforeign.h index 603b8133b6..748328ae07 100644 --- a/libvips/foreign/pforeign.h +++ b/libvips/foreign/pforeign.h @@ -67,9 +67,11 @@ int vips__tiff_write_target(VipsImage *in, VipsTarget *target, gboolean vips__istiff_source(VipsSource *source); gboolean vips__istifftiled_source(VipsSource *source); int vips__tiff_read_header_source(VipsSource *source, VipsImage *out, - int page, int n, gboolean autorotate, int subifd, VipsFailOn fail_on); + int page, int n, gboolean autorotate, int subifd, VipsFailOn fail_on, + gboolean unlimited); int vips__tiff_read_source(VipsSource *source, VipsImage *out, - int page, int n, gboolean autorotate, int subifd, VipsFailOn fail_on); + int page, int n, gboolean autorotate, int subifd, VipsFailOn fail_on, + gboolean unlimited); extern const char *vips__foreign_tiff_suffs[]; diff --git a/libvips/foreign/tiff.c b/libvips/foreign/tiff.c index a6ad9c403a..241ebc402a 100644 --- a/libvips/foreign/tiff.c +++ b/libvips/foreign/tiff.c @@ -164,7 +164,7 @@ openin_source_unmap(thandle_t st, tdata_t start, toff_t len) TIFF * vips__tiff_openin_source(VipsSource *source, VipsTiffErrorHandler error_fn, - VipsTiffErrorHandler warning_fn, void *user_data) + VipsTiffErrorHandler warning_fn, void *user_data, gboolean unlimited) { TIFF *tiff; @@ -187,6 +187,11 @@ vips__tiff_openin_source(VipsSource *source, VipsTiffErrorHandler error_fn, TIFFOpenOptions *opts = TIFFOpenOptionsAlloc(); TIFFOpenOptionsSetErrorHandlerExtR(opts, error_fn, user_data); TIFFOpenOptionsSetWarningHandlerExtR(opts, warning_fn, user_data); +#ifdef HAVE_TIFF_OPEN_OPTIONS_SET_MAX_CUMULATED_MEM_ALLOC + if (!unlimited) { + TIFFOpenOptionsSetMaxCumulatedMemAlloc(opts, 20 * 1024 * 1024); + } +#endif /*HAVE_TIFF_OPEN_OPTIONS_SET_MAX_CUMULATED_MEM_ALLOC*/ if (!(tiff = TIFFClientOpenExt("source input", "rmC", (thandle_t) source, openin_source_read, diff --git a/libvips/foreign/tiff.h b/libvips/foreign/tiff.h index e0619686e4..67d21ad46c 100644 --- a/libvips/foreign/tiff.h +++ b/libvips/foreign/tiff.h @@ -42,7 +42,7 @@ typedef int (*VipsTiffErrorHandler)(TIFF *tiff, void* user_data, TIFF *vips__tiff_openin_source(VipsSource *source, VipsTiffErrorHandler error_fn, VipsTiffErrorHandler warning_fn, - void *user_data); + void *user_data, gboolean unlimited); TIFF *vips__tiff_openout(const char *path, gboolean bigtiff); TIFF *vips__tiff_openout_target(VipsTarget *target, gboolean bigtiff, diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index 96a3e88e8c..03a39e0c77 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -642,7 +642,8 @@ rtiff_handler_warning(TIFF *tiff, void* user_data, static Rtiff * rtiff_new(VipsSource *source, VipsImage *out, - int page, int n, gboolean autorotate, int subifd, VipsFailOn fail_on) + int page, int n, gboolean autorotate, int subifd, VipsFailOn fail_on, + gboolean unlimited) { Rtiff *rtiff; @@ -692,7 +693,7 @@ rtiff_new(VipsSource *source, VipsImage *out, } if (!(rtiff->tiff = vips__tiff_openin_source(source, - rtiff_handler_error, rtiff_handler_warning, rtiff))) + rtiff_handler_error, rtiff_handler_warning, rtiff, unlimited))) return NULL; return rtiff; @@ -3435,7 +3436,7 @@ vips__testtiff_source(VipsSource *source, TiffPropertyFn fn) vips__tiff_init(); if (!(tif = vips__tiff_openin_source(source, rtiff_handler_error, - rtiff_handler_warning, NULL))) { + rtiff_handler_warning, NULL, FALSE))) { vips_error_clear(); return FALSE; } @@ -3461,14 +3462,15 @@ vips__istifftiled_source(VipsSource *source) int vips__tiff_read_header_source(VipsSource *source, VipsImage *out, - int page, int n, gboolean autorotate, int subifd, VipsFailOn fail_on) + int page, int n, gboolean autorotate, int subifd, VipsFailOn fail_on, + gboolean unlimited) { Rtiff *rtiff; vips__tiff_init(); if (!(rtiff = rtiff_new(source, out, - page, n, autorotate, subifd, fail_on)) || + page, n, autorotate, subifd, fail_on, unlimited)) || rtiff_header_read_all(rtiff)) return -1; @@ -3491,7 +3493,8 @@ vips__tiff_read_header_source(VipsSource *source, VipsImage *out, int vips__tiff_read_source(VipsSource *source, VipsImage *out, - int page, int n, gboolean autorotate, int subifd, VipsFailOn fail_on) + int page, int n, gboolean autorotate, int subifd, VipsFailOn fail_on, + gboolean unlimited) { Rtiff *rtiff; @@ -3502,7 +3505,7 @@ vips__tiff_read_source(VipsSource *source, VipsImage *out, vips__tiff_init(); if (!(rtiff = rtiff_new(source, out, - page, n, autorotate, subifd, fail_on)) || + page, n, autorotate, subifd, fail_on, unlimited)) || rtiff_header_read_all(rtiff)) return -1; diff --git a/libvips/foreign/tiffload.c b/libvips/foreign/tiffload.c index a192f98fdd..5286eabf84 100644 --- a/libvips/foreign/tiffload.c +++ b/libvips/foreign/tiffload.c @@ -77,6 +77,10 @@ typedef struct _VipsForeignLoadTiff { */ gboolean autorotate; + /* Remove denial of service limits. + */ + gboolean unlimited; + } VipsForeignLoadTiff; typedef VipsForeignLoadClass VipsForeignLoadTiffClass; @@ -137,7 +141,7 @@ vips_foreign_load_tiff_header(VipsForeignLoad *load) if (vips__tiff_read_header_source(tiff->source, load->out, tiff->page, tiff->n, tiff->autorotate, tiff->subifd, - load->fail_on)) + load->fail_on, tiff->unlimited)) return -1; return 0; @@ -150,7 +154,7 @@ vips_foreign_load_tiff_load(VipsForeignLoad *load) if (vips__tiff_read_source(tiff->source, load->real, tiff->page, tiff->n, tiff->autorotate, tiff->subifd, - load->fail_on)) + load->fail_on, tiff->unlimited)) return -1; return 0; @@ -209,13 +213,21 @@ vips_foreign_load_tiff_class_init(VipsForeignLoadTiffClass *class) G_STRUCT_OFFSET(VipsForeignLoadTiff, autorotate), FALSE); - VIPS_ARG_INT(class, "subifd", 21, + VIPS_ARG_INT(class, "subifd", 23, _("subifd"), _("Subifd index"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsForeignLoadTiff, subifd), -1, 100000, -1); +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + VIPS_ARG_BOOL(class, "unlimited", 24, + _("Unlimited"), + _("Remove all denial of service limits"), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET(VipsForeignLoadTiff, unlimited), + FALSE); +#endif } static void @@ -224,6 +236,7 @@ vips_foreign_load_tiff_init(VipsForeignLoadTiff *tiff) tiff->page = 0; tiff->n = 1; tiff->subifd = -1; + tiff->unlimited = FALSE; } typedef struct _VipsForeignLoadTiffSource { @@ -472,6 +485,7 @@ vips_foreign_load_tiff_buffer_init(VipsForeignLoadTiffBuffer *buffer) * during load * * @subifd: %gint, select this subifd index * * @fail_on: #VipsFailOn, types of read error to fail on + * * @unlimited: %gboolean, remove all denial of service limits * * Read a TIFF file into a VIPS image. It is a full baseline TIFF 6 reader, * with extensions for tiled images, multipage images, XYZ and LAB colour @@ -507,6 +521,10 @@ vips_foreign_load_tiff_buffer_init(VipsForeignLoadTiffBuffer *buffer) * Use @fail_on to set the type of error that will cause load to fail. By * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. * + * When using libtiff 4.7.0+, the TIFF loader will limit memory allocation + * for tag processing to 20MB to prevent denial of service attacks. + * Set @unlimited to remove this limit. + * * Any ICC profile is read and attached to the VIPS image as * #VIPS_META_ICC_NAME. Any XMP metadata is read and attached to the image * as #VIPS_META_XMP_NAME. Any IPTC is attached as #VIPS_META_IPTC_NAME. The @@ -546,6 +564,7 @@ vips_tiffload(const char *filename, VipsImage **out, ...) * during load * * @subifd: %gint, select this subifd index * * @fail_on: #VipsFailOn, types of read error to fail on + * * @unlimited: %gboolean, remove all denial of service limits * * Read a TIFF-formatted memory block into a VIPS image. Exactly as * vips_tiffload(), but read from a memory source. @@ -591,6 +610,7 @@ vips_tiffload_buffer(void *buf, size_t len, VipsImage **out, ...) * during load * * @subifd: %gint, select this subifd index * * @fail_on: #VipsFailOn, types of read error to fail on + * * @unlimited: %gboolean, remove all denial of service limits * * Exactly as vips_tiffload(), but read from a source. * diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 12f387dc55..d90ff86726 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -2419,7 +2419,7 @@ wtiff_gather(Wtiff *wtiff) return -1; if (!(in = vips__tiff_openin_source(source, wtiff_handler_error, - wtiff_handler_warning, NULL))) { + wtiff_handler_warning, NULL, FALSE))) { VIPS_UNREF(source); return -1; } diff --git a/meson.build b/meson.build index ccd3928b8b..ba957ef08a 100644 --- a/meson.build +++ b/meson.build @@ -418,6 +418,10 @@ if libtiff_dep.found() if cc.has_function('TIFFOpenOptionsAlloc', prefix: '#include ', dependencies: libtiff_dep) cfg_var.set('HAVE_TIFF_OPEN_OPTIONS', '1') endif + # TIFFOpenOptionsSetMaxCumulatedMemAlloc added in libtiff 4.7.0 + if cc.has_function('TIFFOpenOptionsSetMaxCumulatedMemAlloc', prefix: '#include ', dependencies: libtiff_dep) + cfg_var.set('HAVE_TIFF_OPEN_OPTIONS_SET_MAX_CUMULATED_MEM_ALLOC', '1') + endif endif # 2.40.3 so we get the UNLIMITED open flag From c8eb7ccddf3d939455da24cf4c4b768b88235b89 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 23 Dec 2024 11:17:38 +0000 Subject: [PATCH 026/174] fix some line breaks --- libvips/foreign/heifsave.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index a4806e58ea..d48904fcd8 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -322,8 +322,7 @@ vips_foreign_save_heif_write_page(VipsForeignSaveHeif *heif, int page) heif->img, heif->encoder, options, &heif->handle); #ifdef DEBUG - printf("... libheif took %.2g seconds\n", - g_timer_elapsed(timer, NULL)); + printf("... libheif took %.2g seconds\n", g_timer_elapsed(timer, NULL)); g_timer_destroy(timer); } #endif /*DEBUG*/ @@ -397,9 +396,7 @@ vips_foreign_save_heif_pack(VipsForeignSaveHeif *heif, */ int vips_bitdepth = save->ready->Type == VIPS_INTERPRETATION_RGB16 || - save->ready->Type == VIPS_INTERPRETATION_GREY16 - ? 16 - : 8; + save->ready->Type == VIPS_INTERPRETATION_GREY16 ? 16 : 8; int shift = vips_bitdepth - heif->bitdepth; for (i = 0; i < ne; i++) { @@ -416,9 +413,7 @@ vips_foreign_save_heif_pack(VipsForeignSaveHeif *heif, */ int vips_bitdepth = save->ready->Type == VIPS_INTERPRETATION_RGB16 || - save->ready->Type == VIPS_INTERPRETATION_GREY16 - ? 16 - : 8; + save->ready->Type == VIPS_INTERPRETATION_GREY16 ? 16 : 8; int shift = vips_bitdepth - heif->bitdepth; for (i = 0; i < ne; i++) { @@ -515,8 +510,7 @@ vips_foreign_save_heif_build(VipsObject *object) const struct heif_encoder_descriptor *out_encoder; const struct heif_encoder_parameter *const *param; - if (VIPS_OBJECT_CLASS(vips_foreign_save_heif_parent_class)-> - build(object)) + if (VIPS_OBJECT_CLASS(vips_foreign_save_heif_parent_class)-> build(object)) return -1; /* If the old, deprecated "speed" param is being used and the new @@ -717,8 +711,7 @@ vips_foreign_save_heif_build(VipsObject *object) /* Write data. */ - if (vips_sink_disc(save->ready, - vips_foreign_save_heif_write_block, heif)) + if (vips_sink_disc(save->ready, vips_foreign_save_heif_write_block, heif)) return -1; /* This has to come right at the end :-( so there's no support for @@ -923,8 +916,7 @@ static int vips_foreign_save_heif_buffer_build(VipsObject *object) { VipsForeignSaveHeif *heif = (VipsForeignSaveHeif *) object; - VipsForeignSaveHeifBuffer *buffer = - (VipsForeignSaveHeifBuffer *) object; + VipsForeignSaveHeifBuffer *buffer = (VipsForeignSaveHeifBuffer *) object; VipsBlob *blob; @@ -986,8 +978,7 @@ static int vips_foreign_save_heif_target_build(VipsObject *object) { VipsForeignSaveHeif *heif = (VipsForeignSaveHeif *) object; - VipsForeignSaveHeifTarget *target = - (VipsForeignSaveHeifTarget *) object; + VipsForeignSaveHeifTarget *target = (VipsForeignSaveHeifTarget *) object; if (target->target) { heif->target = target->target; From 137de47014f27e1fbc8532601e034211c702c213 Mon Sep 17 00:00:00 2001 From: Masahiro Date: Thu, 26 Dec 2024 22:46:14 +0900 Subject: [PATCH 027/174] Replace carrierwave-vips with CarrierWave in README.md (#4329) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f95ac71af5..a8faca4015 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ libvips is used as an image processing engine by: | [bimg](https://github.com/h2non/bimg) | | [sharp for Go](https://github.com/DAddYE/vips) | | [Ruby on Rails](https://edgeguides.rubyonrails.org/active_storage_overview.html) | -| [carrierwave-vips](https://github.com/eltiare/carrierwave-vips) | +| [CarrierWave](https://github.com/carrierwaveuploader/carrierwave#using-vips) | | [mediawiki](https://www.mediawiki.org/wiki/Extension:VipsScaler) | | [PhotoFlow](https://github.com/aferrero2707/PhotoFlow) | | [JVips](https://github.com/criteo/JVips) | From 10d28ce95ea55a391be8eb8fa55806d24bc53238 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 26 Dec 2024 13:46:28 +0000 Subject: [PATCH 028/174] guard against /0 in XYZ2Yxy (#4323) Before this PR, converting to Yxy could leave -nan in pixels, eg.: $ vips colourspace k2.jpg x.v yxy $ vips avg x.v (vips:231364): GLib-GObject-CRITICAL **: 16:02:54.674: value "-nan" of type 'gdouble' is invalid or out of range for property 'out' of type 'gdouble' avg: parameter out not set This PR adds a check for 0 before divide. --- ChangeLog | 1 + libvips/colour/XYZ2Yxy.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8ff41c5cc9..e21ddb51cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ - threadpool: improve cooperative downsizing [kleisauke] - fix alpha shift during colourspace conversions [frederikrosenberg] - heifsave: set image orientation using irot and imir transformations [lovell] +- XYZ2Yxy: guard against divide by zero 10/10/24 8.16.0 diff --git a/libvips/colour/XYZ2Yxy.c b/libvips/colour/XYZ2Yxy.c index c46e4a74a9..ffc30c3b87 100644 --- a/libvips/colour/XYZ2Yxy.c +++ b/libvips/colour/XYZ2Yxy.c @@ -72,8 +72,14 @@ vips_XYZ2Yxy_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) p += 3; - x = X / total; - y = Y / total; + if (total == 0.0) { + x = 0; + y = 0; + } + else { + x = X / total; + y = Y / total; + } q[0] = Y; q[1] = x; From bd251d3cd6524506654cc67560c6db8e3275410d Mon Sep 17 00:00:00 2001 From: "k. Naka" <100704180+na-trium-144@users.noreply.github.com> Date: Thu, 2 Jan 2025 00:24:27 +0900 Subject: [PATCH 029/174] workaround C2124 error on MSVC (#4332) * Fix cross-phase operation for real numbers * workaround for MSVC C2142 error --- libvips/arithmetic/complex.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libvips/arithmetic/complex.c b/libvips/arithmetic/complex.c index 60010d994a..fe62ee04fb 100644 --- a/libvips/arithmetic/complex.c +++ b/libvips/arithmetic/complex.c @@ -449,12 +449,14 @@ G_DEFINE_TYPE(VipsComplex2, vips_complex2, VIPS_TYPE_BINARY); #define CROSS(Q, X1, Y1, X2, Y2) \ { \ if (((X1) == 0.0 && (Y1) == 0.0) || \ - ((X2) == 0.0 && (Y2) == 0.0)) { \ + ((X2) == 0.0 && (Y2) == 0.0) || \ + ((Y1) == 0.0 && (Y2) == 0.0)) { \ Q[0] = 0.0; \ Q[1] = 0.0; \ } \ else if (ABS(Y1) > ABS(Y2)) { \ - double a = Y2 / Y1; \ + double y1 = Y1; /* this suppress C2142 (division by zero) error on MSVC */ \ + double a = Y2 / y1; \ double b = Y1 + Y2 * a; \ double re = (X1 + X2 * a) / b; \ double im = (X2 - X1 * a) / b; \ @@ -464,7 +466,8 @@ G_DEFINE_TYPE(VipsComplex2, vips_complex2, VIPS_TYPE_BINARY); Q[1] = im / mod; \ } \ else { \ - double a = Y1 / Y2; \ + double y2 = Y2; \ + double a = Y1 / y2; \ double b = Y2 + Y1 * a; \ double re = (X1 * a + X2) / b; \ double im = (X2 * a - X1) / b; \ From 8e7bddeb693a2c68a8be430a4249aca82c733816 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 2 Jan 2025 00:52:31 +0000 Subject: [PATCH 030/174] fix a leak in fill_nearest the local image array was one too short --- libvips/morphology/nearest.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/libvips/morphology/nearest.c b/libvips/morphology/nearest.c index 7ba764a165..e213e1e66e 100644 --- a/libvips/morphology/nearest.c +++ b/libvips/morphology/nearest.c @@ -85,12 +85,6 @@ vips_fill_nearest_finalize(GObject *gobject) { VipsFillNearest *nearest = (VipsFillNearest *) gobject; -#ifdef DEBUG - printf("vips_fill_nearest_finalize: "); - vips_object_print_name(VIPS_OBJECT(gobject)); - printf("\n"); -#endif /*DEBUG*/ - VIPS_FREEF(g_array_unref, nearest->seeds); G_OBJECT_CLASS(vips_fill_nearest_parent_class)->finalize(gobject); @@ -244,8 +238,7 @@ vips_fill_nearest_build(VipsObject *object) if (i != ps) { Seed *seed; - g_array_set_size(nearest->seeds, - nearest->seeds->len + 1); + g_array_set_size(nearest->seeds, nearest->seeds->len + 1); seed = &g_array_index(nearest->seeds, Seed, nearest->seeds->len - 1); seed->x = x; @@ -261,9 +254,9 @@ vips_fill_nearest_build(VipsObject *object) /* Create the output and distance images in memory. */ g_object_set(object, "distance", vips_image_new_memory(), NULL); - if (vips_black(&t[1], nearest->width, nearest->height, NULL) || - vips_cast(t[1], &t[2], VIPS_FORMAT_FLOAT, NULL) || - vips_image_write(t[2], nearest->distance)) + if (vips_black(&t[0], nearest->width, nearest->height, NULL) || + vips_cast(t[0], &t[1], VIPS_FORMAT_FLOAT, NULL) || + vips_image_write(t[1], nearest->distance)) return -1; g_object_set(object, "out", vips_image_new_memory(), NULL); From 9db1f677c4d84adbc559f5eb518a6d358389d354 Mon Sep 17 00:00:00 2001 From: "k. Naka" <100704180+na-trium-144@users.noreply.github.com> Date: Thu, 2 Jan 2025 00:24:27 +0900 Subject: [PATCH 031/174] workaround C2124 error on MSVC (#4332) * Fix cross-phase operation for real numbers * workaround for MSVC C2142 error --- libvips/arithmetic/complex.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libvips/arithmetic/complex.c b/libvips/arithmetic/complex.c index 60010d994a..fe62ee04fb 100644 --- a/libvips/arithmetic/complex.c +++ b/libvips/arithmetic/complex.c @@ -449,12 +449,14 @@ G_DEFINE_TYPE(VipsComplex2, vips_complex2, VIPS_TYPE_BINARY); #define CROSS(Q, X1, Y1, X2, Y2) \ { \ if (((X1) == 0.0 && (Y1) == 0.0) || \ - ((X2) == 0.0 && (Y2) == 0.0)) { \ + ((X2) == 0.0 && (Y2) == 0.0) || \ + ((Y1) == 0.0 && (Y2) == 0.0)) { \ Q[0] = 0.0; \ Q[1] = 0.0; \ } \ else if (ABS(Y1) > ABS(Y2)) { \ - double a = Y2 / Y1; \ + double y1 = Y1; /* this suppress C2142 (division by zero) error on MSVC */ \ + double a = Y2 / y1; \ double b = Y1 + Y2 * a; \ double re = (X1 + X2 * a) / b; \ double im = (X2 - X1 * a) / b; \ @@ -464,7 +466,8 @@ G_DEFINE_TYPE(VipsComplex2, vips_complex2, VIPS_TYPE_BINARY); Q[1] = im / mod; \ } \ else { \ - double a = Y1 / Y2; \ + double y2 = Y2; \ + double a = Y1 / y2; \ double b = Y2 + Y1 * a; \ double re = (X1 * a + X2) / b; \ double im = (X2 * a - X1) / b; \ From 07df472140baa9eb8a5f4790cde2ce28135586ea Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 2 Jan 2025 01:07:52 +0000 Subject: [PATCH 032/174] note MSVC compile fix in changelog --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index e21ddb51cf..474bc61696 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,7 @@ - fix alpha shift during colourspace conversions [frederikrosenberg] - heifsave: set image orientation using irot and imir transformations [lovell] - XYZ2Yxy: guard against divide by zero +- fix MSVC compile error [na-trium-144] 10/10/24 8.16.0 From 7b47b07bcd0583c4f9d4afaac85d3abb5008edff Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Thu, 2 Jan 2025 11:10:47 +0000 Subject: [PATCH 033/174] tiffload: use fail_on to determine outcome of TIFFRead* failures (#4331) --- ChangeLog | 1 + libvips/foreign/tiff2vips.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b33f04ddf..e4a1d75ea1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ - add `keep_duplicate_frames` option to GIF save [dloebl] - add Magic Kernel support [akimon658] - tiff: add threadsafe warning/error handlers (requires libtiff 4.5.0+) [lovell] +- tiffload: add support for fail_on flag [lovell] - tiffload: add support for unlimited flag (requires libtiff 4.7.0+) [lovell] 8.16.1 diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index 03a39e0c77..450a2adf04 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -713,7 +713,7 @@ rtiff_strip_read(Rtiff *rtiff, int strip, tdata_t buf) else length = TIFFReadEncodedStrip(rtiff->tiff, strip, buf, (tsize_t) -1); - if (length == -1) { + if (length == -1 && rtiff->fail_on >= VIPS_FAIL_ON_WARNING) { vips_foreign_load_invalidate(rtiff->out); vips_error("tiff2vips", "%s", _("read error")); return -1; @@ -2316,7 +2316,7 @@ rtiff_read_tile(RtiffSeq *seq, tdata_t *buf, int page, int x, int y) size = TIFFReadRawTile(rtiff->tiff, tile_no, seq->compressed_buf, seq->compressed_buf_length); - if (size <= 0) { + if (size <= 0 && rtiff->fail_on >= VIPS_FAIL_ON_WARNING) { vips_foreign_load_invalidate(rtiff->out); g_rec_mutex_unlock(&rtiff->lock); return -1; @@ -2344,7 +2344,7 @@ rtiff_read_tile(RtiffSeq *seq, tdata_t *buf, int page, int x, int y) result = rtiff_read_rgba_tile(rtiff, x, y, buf); else result = TIFFReadTile(rtiff->tiff, buf, x, y, 0, 0) < 0; - if (result) { + if (result && rtiff->fail_on >= VIPS_FAIL_ON_WARNING) { vips_foreign_load_invalidate(rtiff->out); g_rec_mutex_unlock(&rtiff->lock); return -1; From 71602f24bf555c59f1fe3efcf99d69e1acc28698 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 11 Jan 2025 15:42:15 +0000 Subject: [PATCH 034/174] exif: ensure enum entries can be converted to string (#4339) Enumerated entries are often 1 byte in length but as a string are up to around 30 chars in length. Support this common case by reducing the multiplier and adding a constant when calculating the max length of the string. --- ChangeLog | 1 + libvips/foreign/exif.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 474bc61696..540c2fbcff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,7 @@ - heifsave: set image orientation using irot and imir transformations [lovell] - XYZ2Yxy: guard against divide by zero - fix MSVC compile error [na-trium-144] +- exif: ensure enumerated entries can to converted to string values [lovell] 10/10/24 8.16.0 diff --git a/libvips/foreign/exif.c b/libvips/foreign/exif.c index 3868583134..a73afbf85e 100644 --- a/libvips/foreign/exif.c +++ b/libvips/foreign/exif.c @@ -86,7 +86,7 @@ entry_to_s(ExifEntry *entry) * for formats like float. Ban crazy size values. */ int size = VIPS_MIN(entry->size, 10000); - int max_size = size * 5; + int max_size = size * 3 + 32; char *text = VIPS_MALLOC(NULL, max_size + 1); // this renders floats as eg. "12.2345", enums as "Inch", etc. From 5da29f4519084142233602972d8103c39178479f Mon Sep 17 00:00:00 2001 From: Peter Zmanovsky <48548636+peter15914@users.noreply.github.com> Date: Sat, 11 Jan 2025 20:42:52 +0500 Subject: [PATCH 035/174] fix null pointer dereference (#4337) class->suffs is dereferenced later in the function --- libvips/foreign/foreign.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 7e72610a1d..01de82b2ca 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1956,8 +1956,10 @@ vips_foreign_find_save_sub(VipsForeignSaveClass *save_class, /* All savers needs suffs defined since we use the suff to pick the * saver. */ - if (!class->suffs) + if (!class->suffs) { g_warning("no suffix defined for %s", object_class->nickname); + return NULL; + } /* Skip non-file savers. */ From b54cba45fad29398097857b5971eae349b93a19b Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 11 Jan 2025 15:43:16 +0000 Subject: [PATCH 036/174] tiffload: respect TIFFReadRawTile return code (#4340) Partially reverts commit 7b47b07 --- libvips/foreign/tiff2vips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index 450a2adf04..a3ecdcbb45 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -2316,7 +2316,7 @@ rtiff_read_tile(RtiffSeq *seq, tdata_t *buf, int page, int x, int y) size = TIFFReadRawTile(rtiff->tiff, tile_no, seq->compressed_buf, seq->compressed_buf_length); - if (size <= 0 && rtiff->fail_on >= VIPS_FAIL_ON_WARNING) { + if (size <= 0) { vips_foreign_load_invalidate(rtiff->out); g_rec_mutex_unlock(&rtiff->lock); return -1; From dbe46d13db44a0e2baa703cd560d3f5661ab5c01 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Mon, 13 Jan 2025 11:41:21 +0000 Subject: [PATCH 037/174] gifsave: ensure return code is propagated (#4344) - checks for error after final sink disc write - adds support for eval callbacks - adds GIF timeout test --- ChangeLog | 1 + libvips/foreign/cgifsave.c | 7 ++++++ libvips/iofuncs/sinkdisc.c | 4 +++ test/meson.build | 11 +++++++++ test/test_timeout_gifsave.c | 49 +++++++++++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 test/test_timeout_gifsave.c diff --git a/ChangeLog b/ChangeLog index 540c2fbcff..b788a87725 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,7 @@ - XYZ2Yxy: guard against divide by zero - fix MSVC compile error [na-trium-144] - exif: ensure enumerated entries can to converted to string values [lovell] +- gifsave: add support for eval callback, ensure correct return code [lovell] 10/10/24 8.16.0 diff --git a/libvips/foreign/cgifsave.c b/libvips/foreign/cgifsave.c index db7e70bffe..c28d5e5f9c 100644 --- a/libvips/foreign/cgifsave.c +++ b/libvips/foreign/cgifsave.c @@ -48,6 +48,7 @@ #include #include +#include #include "pforeign.h" #include "quantise.h" @@ -589,6 +590,12 @@ vips_foreign_save_cgif_write_frame(VipsForeignSaveCgif *cgif) VIPS_FREEF(vips__quantise_image_destroy, image); + /* Remapping is relatively slow, trigger eval callbacks. + */ + vips_image_eval(cgif->in, n_pels); + if (vips_image_iskilled(cgif->in)) + return -1; + /* Set up cgif on first use. */ if (!cgif->cgif_context) { diff --git a/libvips/iofuncs/sinkdisc.c b/libvips/iofuncs/sinkdisc.c index 236c271ac3..86a2549837 100644 --- a/libvips/iofuncs/sinkdisc.c +++ b/libvips/iofuncs/sinkdisc.c @@ -533,6 +533,10 @@ vips_sink_disc(VipsImage *im, VipsRegionWrite write_fn, void *a) vips_image_posteval(im); + /* The final write might have failed, pick up any error code. + */ + result |= write.buf->write_errno; + write_free(&write); vips_image_minimise_all(im); diff --git a/test/meson.build b/test/meson.build index 92b79d782e..90dc7e7779 100644 --- a/test/meson.build +++ b/test/meson.build @@ -89,3 +89,14 @@ test('webpsave_timeout', depends: test_timeout_webpsave, workdir: meson.current_build_dir(), ) + +test_timeout_gifsave = executable('test_timeout_gifsave', + 'test_timeout_gifsave.c', + dependencies: libvips_dep, +) + +test('gifsave_timeout', + test_timeout_gifsave, + depends: test_timeout_gifsave, + workdir: meson.current_build_dir(), +) diff --git a/test/test_timeout_gifsave.c b/test/test_timeout_gifsave.c new file mode 100644 index 0000000000..a47f0cd88e --- /dev/null +++ b/test/test_timeout_gifsave.c @@ -0,0 +1,49 @@ +#include + +#define TIMEOUT_SECONDS 2 + +static void +eval_callback(VipsImage *image, VipsProgress *progress, gboolean *is_killed) +{ + if (progress->run >= TIMEOUT_SECONDS) { + *is_killed = TRUE; + vips_image_set_kill(image, TRUE); + } +} + +int +main(int argc, char **argv) +{ + VipsImage *im; + void *buf; + size_t len; + gboolean is_killed = FALSE; + int ret; + + if (VIPS_INIT(argv[0])) + vips_error_exit(NULL); + + if (!vips_type_find("VipsOperation", "gifsave")) + /* gifsave not available, skip test with return code 77. + */ + return 77; + + if (vips_gaussnoise(&im, 8192, 8192, NULL)) + vips_error_exit(NULL); + + vips_image_set_progress(im, TRUE); + g_signal_connect(im, "eval", + G_CALLBACK(eval_callback), &is_killed); + + buf = NULL; + ret = vips_gifsave_buffer(im, &buf, &len, NULL); + if (!ret) + printf("expected error return from vips_gifsave_buffer()\n"); + + g_object_unref(im); + if (buf) + g_free(buf); + g_assert(is_killed); + + return !ret; +} From aa6db7679d04df777fe39e4823bbf6a432c1fcc3 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 13 Jan 2025 12:11:09 +0000 Subject: [PATCH 038/174] tiny sinkdisc cleanup Have a function to test errno and set a message on both buffers. --- libvips/iofuncs/sinkdisc.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/libvips/iofuncs/sinkdisc.c b/libvips/iofuncs/sinkdisc.c index 86a2549837..40d5a55d7f 100644 --- a/libvips/iofuncs/sinkdisc.c +++ b/libvips/iofuncs/sinkdisc.c @@ -98,6 +98,20 @@ typedef struct _Write { void *a; } Write; +static int +write_check_error(Write *write) +{ + if (write->buf->write_errno || + write->buf_back->write_errno) { + vips_error_system(write->buf->write_errno ? + write->buf->write_errno : write->buf_back->write_errno, + "wbuffer_write", "%s", _("write failed")); + return -1; + } + + return 0; +} + /* Our per-thread state ... we need to also track the buffer that pos is * supposed to write to. */ @@ -259,13 +273,8 @@ wbuffer_flush(Write *write) if (write->buf->area.top > 0) { vips_semaphore_down(&write->buf_back->done); - /* Previous write succeeded? - */ - if (write->buf_back->write_errno) { - vips_error_system(write->buf_back->write_errno, - "wbuffer_write", "%s", _("write failed")); + if (write_check_error(write)) return -1; - } } /* Set the background writer going for this buffer. @@ -535,7 +544,7 @@ vips_sink_disc(VipsImage *im, VipsRegionWrite write_fn, void *a) /* The final write might have failed, pick up any error code. */ - result |= write.buf->write_errno; + result |= write_check_error(&write); write_free(&write); From d7cc7b98fed1ded6222e617341a6c95417e2045d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 23 Jan 2025 13:51:43 +0000 Subject: [PATCH 039/174] fix a small leak in fill_nearest --- libvips/morphology/nearest.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/libvips/morphology/nearest.c b/libvips/morphology/nearest.c index 7ba764a165..e213e1e66e 100644 --- a/libvips/morphology/nearest.c +++ b/libvips/morphology/nearest.c @@ -85,12 +85,6 @@ vips_fill_nearest_finalize(GObject *gobject) { VipsFillNearest *nearest = (VipsFillNearest *) gobject; -#ifdef DEBUG - printf("vips_fill_nearest_finalize: "); - vips_object_print_name(VIPS_OBJECT(gobject)); - printf("\n"); -#endif /*DEBUG*/ - VIPS_FREEF(g_array_unref, nearest->seeds); G_OBJECT_CLASS(vips_fill_nearest_parent_class)->finalize(gobject); @@ -244,8 +238,7 @@ vips_fill_nearest_build(VipsObject *object) if (i != ps) { Seed *seed; - g_array_set_size(nearest->seeds, - nearest->seeds->len + 1); + g_array_set_size(nearest->seeds, nearest->seeds->len + 1); seed = &g_array_index(nearest->seeds, Seed, nearest->seeds->len - 1); seed->x = x; @@ -261,9 +254,9 @@ vips_fill_nearest_build(VipsObject *object) /* Create the output and distance images in memory. */ g_object_set(object, "distance", vips_image_new_memory(), NULL); - if (vips_black(&t[1], nearest->width, nearest->height, NULL) || - vips_cast(t[1], &t[2], VIPS_FORMAT_FLOAT, NULL) || - vips_image_write(t[2], nearest->distance)) + if (vips_black(&t[0], nearest->width, nearest->height, NULL) || + vips_cast(t[0], &t[1], VIPS_FORMAT_FLOAT, NULL) || + vips_image_write(t[1], nearest->distance)) return -1; g_object_set(object, "out", vips_image_new_memory(), NULL); From f24c62e66657dd28d979e0ed61070978655d8b1d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 23 Jan 2025 13:52:41 +0000 Subject: [PATCH 040/174] note leak fix in changelog --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index b788a87725..53f3711f22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ - fix MSVC compile error [na-trium-144] - exif: ensure enumerated entries can to converted to string values [lovell] - gifsave: add support for eval callback, ensure correct return code [lovell] +- fill_nearest: fix a leak 10/10/24 8.16.0 From 4811f1e4a8a3d89c91b34a90cc8bbb856534b51f Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 23 Jan 2025 15:01:33 +0100 Subject: [PATCH 041/174] tiffsave: honor disc threshold during pyramid save (#4349) See: https://github.com/kleisauke/net-vips/issues/245. Co-authored-by: John Cupitt --- ChangeLog | 1 + libvips/foreign/vips2tiff.c | 13 ++++++++++--- libvips/iofuncs/target.c | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53f3711f22..f6ec1fb46b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ - fix MSVC compile error [na-trium-144] - exif: ensure enumerated entries can to converted to string values [lovell] - gifsave: add support for eval callback, ensure correct return code [lovell] +- tiffsave: honor disc threshold during pyramid save [kleisauke] - fill_nearest: fix a leak 10/10/24 8.16.0 diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 7a93d0f3d2..9a85861409 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -475,9 +475,16 @@ wtiff_layer_init(Wtiff *wtiff, Layer **layer, Layer *above, (*layer)->target = wtiff->target; g_object_ref((*layer)->target); } - else - (*layer)->target = - vips_target_new_temp(wtiff->target); + else { + const guint64 disc_threshold = vips_get_disc_threshold(); + const guint64 layer_size = + VIPS_IMAGE_SIZEOF_PEL(wtiff->ready) * width * height; + + if (layer_size > disc_threshold) + (*layer)->target = vips_target_new_temp(wtiff->target); + else + (*layer)->target = vips_target_new_to_memory(); + } /* printf("wtiff_layer_init: sub = %d, width = %d, height = %d\n", diff --git a/libvips/iofuncs/target.c b/libvips/iofuncs/target.c index df5a409512..66145fbc4a 100644 --- a/libvips/iofuncs/target.c +++ b/libvips/iofuncs/target.c @@ -382,7 +382,7 @@ vips_target_new_to_file(const char *filename) * * See also: vips_target_new_to_file(). * - * Returns: a new #VipsConnection + * Returns: a new target. */ VipsTarget * vips_target_new_to_memory(void) From 22f68e86f5a4f902ecfa022dc6525e293e90dbbf Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 23 Jan 2025 15:27:33 +0000 Subject: [PATCH 042/174] fix operation cache (#4350) fix operation cache * improve diagnostics * fix dzsave "background" property * fix reduceh/v * fix tiffsave * fix draw_flood * fix affine * move the cache sanity check behind VIPS_LEAK * Add FIXMEs Co-authored-by: Kleis Auke Wolthuizen --- ChangeLog | 2 + libvips/arithmetic/measure.c | 4 +- libvips/colour/icc_transform.c | 2 +- libvips/conversion/arrayjoin.c | 6 +- libvips/conversion/bandfold.c | 3 +- libvips/conversion/bandrank.c | 2 +- libvips/conversion/bandunfold.c | 3 +- libvips/conversion/composite.cpp | 2 +- libvips/conversion/embed.c | 2 +- libvips/conversion/flatten.c | 2 +- libvips/conversion/premultiply.c | 2 +- libvips/conversion/smartcrop.c | 4 +- libvips/conversion/tilecache.c | 8 +-- libvips/conversion/transpose3d.c | 2 +- libvips/conversion/unpremultiply.c | 4 +- libvips/conversion/wrap.c | 4 +- libvips/convolution/conva.c | 2 +- libvips/convolution/sharpen.c | 2 +- libvips/create/gaussmat.c | 2 +- libvips/create/logmat.c | 2 +- libvips/create/text.c | 8 +-- libvips/draw/draw.c | 4 ++ libvips/foreign/dzsave.c | 21 ++---- libvips/foreign/fits.c | 2 +- libvips/foreign/heifload.c | 4 +- libvips/foreign/jxlload.c | 6 +- libvips/foreign/magick6load.c | 4 +- libvips/foreign/nsgifload.c | 20 ++++-- libvips/foreign/pdfiumload.c | 4 +- libvips/foreign/popplerload.c | 2 +- libvips/foreign/tiffsave.c | 82 +++++++++++----------- libvips/foreign/vips2magick.c | 3 +- libvips/include/vips/internal.h | 2 + libvips/iofuncs/cache.c | 105 +++++++++++++++++++++++++---- libvips/iofuncs/object.c | 19 ++---- libvips/mosaicing/match.c | 10 +-- libvips/mosaicing/mosaic1.c | 2 +- libvips/resample/affine.c | 47 ++++++++----- libvips/resample/quadratic.c | 2 +- libvips/resample/reduceh.cpp | 34 ++++++---- libvips/resample/reducev.cpp | 55 ++++++++------- test/test-suite/test_foreign.py | 4 +- 42 files changed, 305 insertions(+), 195 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53f3458ff8..0817682243 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ - tiff: add threadsafe warning/error handlers (requires libtiff 4.5.0+) [lovell] - tiffload: add support for fail_on flag [lovell] - tiffload: add support for unlimited flag (requires libtiff 4.7.0+) [lovell] +- much more reliable operation caching 8.16.1 @@ -23,6 +24,7 @@ - fix MSVC compile error [na-trium-144] - exif: ensure enumerated entries can to converted to string values [lovell] - gifsave: add support for eval callback, ensure correct return code [lovell] +- fill_nearest: fix a leak 10/10/24 8.16.0 diff --git a/libvips/arithmetic/measure.c b/libvips/arithmetic/measure.c index 1a8e779a16..a035b14b5f 100644 --- a/libvips/arithmetic/measure.c +++ b/libvips/arithmetic/measure.c @@ -117,9 +117,9 @@ vips_measure_build(VipsObject *object) /* left/top/width/height default to the size of the image. */ if (!vips_object_argument_isset(object, "width")) - measure->width = vips_image_get_width(ready); + measure->width = vips_image_get_width(ready); // FIXME: Invalidates operation cache if (!vips_object_argument_isset(object, "height")) - measure->height = vips_image_get_height(ready); + measure->height = vips_image_get_height(ready); // FIXME: Invalidates operation cache /* How large are the patches we are to measure? */ diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 28ef2eae8d..6be79ab516 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -1174,7 +1174,7 @@ vips_icc_transform_build(VipsObject *object) code->in && (code->in->Type == VIPS_INTERPRETATION_RGB16 || code->in->Type == VIPS_INTERPRETATION_GREY16)) - icc->depth = 16; + icc->depth = 16; // FIXME: Invalidates operation cache if (vips_icc_set_import(icc, transform->embedded, transform->input_profile_filename)) diff --git a/libvips/conversion/arrayjoin.c b/libvips/conversion/arrayjoin.c index 6136e7fff7..81c7cb0bab 100644 --- a/libvips/conversion/arrayjoin.c +++ b/libvips/conversion/arrayjoin.c @@ -240,15 +240,15 @@ vips_arrayjoin_build(VipsObject *object) } if (!vips_object_argument_isset(object, "hspacing")) - join->hspacing = hspacing; + join->hspacing = hspacing; // FIXME: Invalidates operation cache if (!vips_object_argument_isset(object, "vspacing")) - join->vspacing = vspacing; + join->vspacing = vspacing; // FIXME: Invalidates operation cache hspacing = join->hspacing; vspacing = join->vspacing; if (!vips_object_argument_isset(object, "across")) - join->across = n; + join->across = n; // FIXME: Invalidates operation cache /* How many images down the grid? */ diff --git a/libvips/conversion/bandfold.c b/libvips/conversion/bandfold.c index 707e6d3187..6762c0835c 100644 --- a/libvips/conversion/bandfold.c +++ b/libvips/conversion/bandfold.c @@ -116,7 +116,8 @@ vips_bandfold_build(VipsObject *object) return -1; if (bandfold->factor == 0) - bandfold->factor = bandfold->in->Xsize; + bandfold->factor = bandfold->in->Xsize; // FIXME: Invalidates operation cache + if (bandfold->in->Xsize % bandfold->factor != 0) { vips_error(class->nickname, "%s", _("@factor must be a factor of image width")); diff --git a/libvips/conversion/bandrank.c b/libvips/conversion/bandrank.c index ef26ba2019..4fa658a27c 100644 --- a/libvips/conversion/bandrank.c +++ b/libvips/conversion/bandrank.c @@ -223,7 +223,7 @@ vips_bandrank_build(VipsObject *object) bandary->out_bands = band[0]->Bands; if (bandrank->index == -1) - bandrank->index = bandary->n / 2; + bandrank->index = bandary->n / 2; // FIXME: Invalidates operation cache } if (VIPS_OBJECT_CLASS(vips_bandrank_parent_class)->build(object)) diff --git a/libvips/conversion/bandunfold.c b/libvips/conversion/bandunfold.c index 6bec18c835..4229186dd5 100644 --- a/libvips/conversion/bandunfold.c +++ b/libvips/conversion/bandunfold.c @@ -119,7 +119,8 @@ vips_bandunfold_build(VipsObject *object) return -1; if (bandunfold->factor == 0) - bandunfold->factor = bandunfold->in->Bands; + bandunfold->factor = bandunfold->in->Bands; // FIXME: Invalidates operation cache + if (bandunfold->in->Bands % bandunfold->factor != 0) { vips_error(class->nickname, "%s", _("@factor must be a factor of image bands")); diff --git a/libvips/conversion/composite.cpp b/libvips/conversion/composite.cpp index 2c5bafd66f..104cf56c69 100644 --- a/libvips/conversion/composite.cpp +++ b/libvips/conversion/composite.cpp @@ -1387,7 +1387,7 @@ vips_composite_base_build(VipsObject *object) break; } - composite->compositing_space = any_16 + composite->compositing_space = any_16 // FIXME: Invalidates operation cache ? (all_grey ? VIPS_INTERPRETATION_GREY16 : VIPS_INTERPRETATION_RGB16) diff --git a/libvips/conversion/embed.c b/libvips/conversion/embed.c index c1cbf181de..647a6af076 100644 --- a/libvips/conversion/embed.c +++ b/libvips/conversion/embed.c @@ -371,7 +371,7 @@ vips_embed_base_build(VipsObject *object) if (!vips_object_argument_isset(object, "extend") && vips_object_argument_isset(object, "background")) - base->extend = VIPS_EXTEND_BACKGROUND; + base->extend = VIPS_EXTEND_BACKGROUND; // FIXME: Invalidates operation cache if (base->extend == VIPS_EXTEND_BACKGROUND) if (!(base->ink = vips__vector_to_ink( diff --git a/libvips/conversion/flatten.c b/libvips/conversion/flatten.c index 92754d7cd4..88d7351e46 100644 --- a/libvips/conversion/flatten.c +++ b/libvips/conversion/flatten.c @@ -326,7 +326,7 @@ vips_flatten_build(VipsObject *object) * interpretation. */ if (!vips_object_argument_isset(object, "max_alpha")) - flatten->max_alpha = vips_interpretation_max_alpha(in->Type); + flatten->max_alpha = vips_interpretation_max_alpha(in->Type); // FIXME: Invalidates operation cache /* Is max_alpha less than the numeric range of this image? If it is, * we can get int overflow. diff --git a/libvips/conversion/premultiply.c b/libvips/conversion/premultiply.c index 335964013f..812043f749 100644 --- a/libvips/conversion/premultiply.c +++ b/libvips/conversion/premultiply.c @@ -224,7 +224,7 @@ vips_premultiply_build(VipsObject *object) * interpretation. */ if (!vips_object_argument_isset(object, "max_alpha")) - premultiply->max_alpha = vips_interpretation_max_alpha(in->Type); + premultiply->max_alpha = vips_interpretation_max_alpha(in->Type); // FIXME: Invalidates operation cache if (in->BandFmt == VIPS_FORMAT_DOUBLE) conversion->out->BandFmt = VIPS_FORMAT_DOUBLE; diff --git a/libvips/conversion/smartcrop.c b/libvips/conversion/smartcrop.c index d4b758878b..1874d1e070 100644 --- a/libvips/conversion/smartcrop.c +++ b/libvips/conversion/smartcrop.c @@ -386,8 +386,8 @@ vips_smartcrop_build(VipsObject *object) case VIPS_INTERESTING_ALL: left = 0; top = 0; - smartcrop->width = in->Xsize; - smartcrop->height = in->Ysize; + smartcrop->width = in->Xsize; // FIXME: Invalidates operation cache + smartcrop->height = in->Ysize; // FIXME: Invalidates operation cache break; default: diff --git a/libvips/conversion/tilecache.c b/libvips/conversion/tilecache.c index 0e4d2f302e..c601bc04f8 100644 --- a/libvips/conversion/tilecache.c +++ b/libvips/conversion/tilecache.c @@ -897,7 +897,7 @@ vips_line_cache_gen(VipsRegion *out_region, */ if (out_region->valid.height > block_cache->max_tiles * block_cache->tile_height) { - block_cache->max_tiles = + block_cache->max_tiles = // FIXME: Invalidates operation cache 1 + (out_region->valid.height / block_cache->tile_height); VIPS_DEBUG_MSG("vips_line_cache_gen: bumped max_tiles to %d\n", block_cache->max_tiles); @@ -922,7 +922,7 @@ vips_line_cache_build(VipsObject *object) VIPS_DEBUG_MSG("vips_line_cache_build\n"); if (!vips_object_argument_isset(object, "access")) - block_cache->access = VIPS_ACCESS_SEQUENTIAL; + block_cache->access = VIPS_ACCESS_SEQUENTIAL; // FIXME: Invalidates operation cache if (VIPS_OBJECT_CLASS(vips_line_cache_parent_class)->build(object)) return -1; @@ -931,7 +931,7 @@ vips_line_cache_build(VipsObject *object) */ vips_get_tile_size(block_cache->in, &tile_width, &tile_height, &n_lines); - block_cache->tile_width = block_cache->in->Xsize; + block_cache->tile_width = block_cache->in->Xsize; // FIXME: Invalidates operation cache /* Output has two buffers n_lines height, so 2 * n_lines is the maximum * non-locality from threading. Double again for conv, rounding, etc. @@ -941,7 +941,7 @@ vips_line_cache_build(VipsObject *object) * minimum of two strips, so we can handle requests that straddle a * tile boundary. */ - block_cache->max_tiles = VIPS_MAX(2, + block_cache->max_tiles = VIPS_MAX(2, // FIXME: Invalidates operation cache 4 * n_lines / block_cache->tile_height); VIPS_DEBUG_MSG("vips_line_cache_build: n_lines = %d\n", diff --git a/libvips/conversion/transpose3d.c b/libvips/conversion/transpose3d.c index 4151ed44bd..64c1da70b4 100644 --- a/libvips/conversion/transpose3d.c +++ b/libvips/conversion/transpose3d.c @@ -126,7 +126,7 @@ vips_transpose3d_build(VipsObject *object) if (!vips_object_argument_isset(object, "page_height")) { if (vips_image_get_int(in, - VIPS_META_PAGE_HEIGHT, &transpose3d->page_height)) + VIPS_META_PAGE_HEIGHT, &transpose3d->page_height)) // FIXME: Invalidates operation cache return -1; } diff --git a/libvips/conversion/unpremultiply.c b/libvips/conversion/unpremultiply.c index afec9ff575..db489cf1d3 100644 --- a/libvips/conversion/unpremultiply.c +++ b/libvips/conversion/unpremultiply.c @@ -281,12 +281,12 @@ vips_unpremultiply_build(VipsObject *object) * interpretation. */ if (!vips_object_argument_isset(object, "max_alpha")) - unpremultiply->max_alpha = vips_interpretation_max_alpha(in->Type); + unpremultiply->max_alpha = vips_interpretation_max_alpha(in->Type); // FIXME: Invalidates operation cache /* Is alpha-band unset? Default to the final band for this image. */ if (!vips_object_argument_isset(object, "alpha_band")) - unpremultiply->alpha_band = in->Bands - 1; + unpremultiply->alpha_band = in->Bands - 1; // FIXME: Invalidates operation cache if (in->BandFmt == VIPS_FORMAT_DOUBLE) conversion->out->BandFmt = VIPS_FORMAT_DOUBLE; diff --git a/libvips/conversion/wrap.c b/libvips/conversion/wrap.c index 29a43b9d6f..2a81a41d85 100644 --- a/libvips/conversion/wrap.c +++ b/libvips/conversion/wrap.c @@ -76,9 +76,9 @@ vips_wrap_build(VipsObject *object) return -1; if (!vips_object_argument_isset(object, "x")) - wrap->x = wrap->in->Xsize / 2; + wrap->x = wrap->in->Xsize / 2; // FIXME: Invalidates operation cache if (!vips_object_argument_isset(object, "y")) - wrap->y = wrap->in->Ysize / 2; + wrap->y = wrap->in->Ysize / 2; // FIXME: Invalidates operation cache /* Clock arithmetic: we want negative x/y to wrap around * nicely. diff --git a/libvips/convolution/conva.c b/libvips/convolution/conva.c index fcb6f81178..f76027a388 100644 --- a/libvips/convolution/conva.c +++ b/libvips/convolution/conva.c @@ -334,7 +334,7 @@ vips_conva_decompose_hlines(VipsConva *conva) layers_above = VIPS_CEIL(max / depth); depth = max / layers_above; layers_below = VIPS_FLOOR(min / depth); - conva->layers = layers_above - layers_below; + conva->layers = layers_above - layers_below; // FIXME: Invalidates operation cache VIPS_DEBUG_MSG("vips_conva_decompose_hlines: depth = %g, layers = %d\n", depth, conva->layers); diff --git a/libvips/convolution/sharpen.c b/libvips/convolution/sharpen.c index c5edfef92d..ea4f4e2893 100644 --- a/libvips/convolution/sharpen.c +++ b/libvips/convolution/sharpen.c @@ -189,7 +189,7 @@ vips_sharpen_build(VipsObject *object) */ if (!vips_object_argument_isset(object, "sigma") && vips_object_argument_isset(object, "radius")) - sharpen->sigma = 1 + sharpen->radius / 2; + sharpen->sigma = 1 + sharpen->radius / 2; // FIXME: Invalidates operation cache in = sharpen->in; diff --git a/libvips/create/gaussmat.c b/libvips/create/gaussmat.c index 5f3dbe4017..75ccfeed46 100644 --- a/libvips/create/gaussmat.c +++ b/libvips/create/gaussmat.c @@ -114,7 +114,7 @@ vips_gaussmat_build(VipsObject *object) if (vips_object_argument_isset(object, "integer") && !vips_object_argument_isset(object, "precision") && !gaussmat->integer) - gaussmat->precision = VIPS_PRECISION_FLOAT; + gaussmat->precision = VIPS_PRECISION_FLOAT; // FIXME: Invalidates operation cache /* Find the size of the mask. Limit the mask size to 10k x 10k for * sanity. We allow x == 0, meaning a 1x1 mask. diff --git a/libvips/create/logmat.c b/libvips/create/logmat.c index f84ac72ef2..251da27df6 100644 --- a/libvips/create/logmat.c +++ b/libvips/create/logmat.c @@ -106,7 +106,7 @@ vips_logmat_build(VipsObject *object) if (vips_object_argument_isset(object, "integer") && !vips_object_argument_isset(object, "precision") && !logmat->integer) - logmat->precision = VIPS_PRECISION_FLOAT; + logmat->precision = VIPS_PRECISION_FLOAT; // FIXME: Invalidates operation cache if (vips_check_precision_intfloat(class->nickname, logmat->precision)) diff --git a/libvips/create/text.c b/libvips/create/text.c index 43ff054f75..71b1325f6d 100644 --- a/libvips/create/text.c +++ b/libvips/create/text.c @@ -314,7 +314,7 @@ vips_text_autofit(VipsText *text) previous_difference = difference; previous_dpi = text->dpi; - text->dpi = difference < 0 ? text->dpi * 2 : text->dpi / 2; + text->dpi = difference < 0 ? text->dpi * 2 : text->dpi / 2; // FIXME: Invalidates operation cache /* This can happen with fixed-size fonts. */ @@ -343,7 +343,7 @@ vips_text_autofit(VipsText *text) */ while (upper_dpi - lower_dpi > 1 && difference != 0) { - text->dpi = (upper_dpi + lower_dpi) / 2; + text->dpi = (upper_dpi + lower_dpi) / 2; // FIXME: Invalidates operation cache if (vips_text_get_extents(text, &extents)) return -1; target.left = extents.left; @@ -361,9 +361,9 @@ vips_text_autofit(VipsText *text) * must take lower. */ if (difference == 0) - text->dpi = upper_dpi; + text->dpi = upper_dpi; // FIXME: Invalidates operation cache else - text->dpi = lower_dpi; + text->dpi = lower_dpi; // FIXME: Invalidates operation cache g_object_set(text, "autofit_dpi", text->dpi, NULL); #ifdef DEBUG diff --git a/libvips/draw/draw.c b/libvips/draw/draw.c index 88e4bb87b1..40f9c8ffc8 100644 --- a/libvips/draw/draw.c +++ b/libvips/draw/draw.c @@ -122,6 +122,7 @@ vips_draw_class_init(VipsDrawClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS(class); VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS(class); + VipsOperationClass *operation_class = VIPS_OPERATION_CLASS(class); gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; @@ -130,6 +131,9 @@ vips_draw_class_init(VipsDrawClass *class) vobject_class->description = _("draw operations"); vobject_class->build = vips_draw_build; + // no draw operation is cached + operation_class->flags |= VIPS_OPERATION_NOCACHE; + VIPS_ARG_IMAGE(class, "image", 1, _("Image"), _("Image to draw on"), diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index 223a3ee566..f5f825f18c 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -2009,21 +2009,6 @@ vips_foreign_save_dz_build(VipsObject *object) return -1; } - /* Default to white background. vips_foreign_save_init() defaults to - * black. - */ - if (!vips_object_argument_isset(object, "background")) { - VipsArrayDouble *background; - - /* Using g_object_set() to set an input param in build will - * change the hash and confuse caching, but we don't cache - * savers, so it's fine. - */ - background = vips_array_double_newv(1, 255.0); - g_object_set(object, "background", background, NULL); - vips_area_unref(VIPS_AREA(background)); - } - /* DeepZoom stops at 1x1 pixels, others when the image fits within a * tile. */ @@ -2499,6 +2484,12 @@ vips_foreign_save_dz_init(VipsForeignSaveDz *dz) dz->region_shrink = VIPS_REGION_SHRINK_MEAN; dz->skip_blanks = -1; dz->Q = 75; + + // we default background to 255 (not 0), see vips_foreign_save_init() + VipsForeignSave *save = (VipsForeignSave *) dz; + if (save->background) + vips_area_unref(VIPS_AREA(save->background)); + save->background = vips_array_double_newv(1, 255.0); } typedef struct _VipsForeignSaveDzTarget { diff --git a/libvips/foreign/fits.c b/libvips/foreign/fits.c index 03008c3c30..49f1ff958d 100644 --- a/libvips/foreign/fits.c +++ b/libvips/foreign/fits.c @@ -575,7 +575,7 @@ vips_fits_new_write(VipsImage *in, const char *filename) VIPS_IMAGE_SIZEOF_ELEMENT(in) * in->Xsize, VipsPel))) return NULL; - /* fits_create_file() will fail if there's a file of thet name, unless + /* fits_create_file() will fail if there's a file of that name, unless * we put a "!" in front of the filename. This breaks conventions with * the rest of vips, so just unlink explicitly. */ diff --git a/libvips/foreign/heifload.c b/libvips/foreign/heifload.c index 3872811abf..d683258461 100644 --- a/libvips/foreign/heifload.c +++ b/libvips/foreign/heifload.c @@ -810,10 +810,10 @@ vips_foreign_load_heif_header(VipsForeignLoad *load) */ if (!vips_object_argument_isset(VIPS_OBJECT(load), "page") && !vips_object_argument_isset(VIPS_OBJECT(load), "n")) - heif->page = heif->primary_page; + heif->page = heif->primary_page; // FIXME: Invalidates operation cache if (heif->n == -1) - heif->n = heif->n_top - heif->page; + heif->n = heif->n_top - heif->page; // FIXME: Invalidates operation cache if (heif->page < 0 || heif->n <= 0 || heif->page + heif->n > heif->n_top) { diff --git a/libvips/foreign/jxlload.c b/libvips/foreign/jxlload.c index c53e8f5ab2..446950d7af 100644 --- a/libvips/foreign/jxlload.c +++ b/libvips/foreign/jxlload.c @@ -745,7 +745,7 @@ vips_foreign_load_jxl_set_header(VipsForeignLoadJxl *jxl, VipsImage *out) if (jxl->frame_count > 1) { if (jxl->n == -1) - jxl->n = jxl->frame_count - jxl->page; + jxl->n = jxl->frame_count - jxl->page; // FIXME: Invalidates operation cache if (jxl->page < 0 || jxl->n <= 0 || @@ -772,8 +772,8 @@ vips_foreign_load_jxl_set_header(VipsForeignLoadJxl *jxl, VipsImage *out) } } else { - jxl->n = 1; - jxl->page = 0; + jxl->n = 1; // FIXME: Invalidates operation cache + jxl->page = 0; // FIXME: Invalidates operation cache } /* Init jxl->frame only when we need to decode multiple frames. diff --git a/libvips/foreign/magick6load.c b/libvips/foreign/magick6load.c index 98177d4eb5..31432087ef 100644 --- a/libvips/foreign/magick6load.c +++ b/libvips/foreign/magick6load.c @@ -204,7 +204,7 @@ vips_foreign_load_magick_file_header(VipsForeignLoad *load) (VipsForeignLoadMagickFile *) load; if (magick->all_frames) - magick->n = -1; + magick->n = -1; // FIXME: Invalidates operation cache if (vips__magick_read(magick_file->filename, load->out, magick->density, @@ -280,7 +280,7 @@ vips_foreign_load_magick_buffer_header(VipsForeignLoad *load) (VipsForeignLoadMagickBuffer *) load; if (magick->all_frames) - magick->n = -1; + magick->n = -1; // FIXME: Invalidates operation cache if (vips__magick_read_buffer( magick_buffer->buf->data, magick_buffer->buf->length, diff --git a/libvips/foreign/nsgifload.c b/libvips/foreign/nsgifload.c index ba24ff2b8c..eb45fb26e1 100644 --- a/libvips/foreign/nsgifload.c +++ b/libvips/foreign/nsgifload.c @@ -131,6 +131,10 @@ typedef struct _VipsForeignLoadNsgif { */ int gif_delay; + /* n, ready for libnsgif. + */ + int gif_n; + /* If the GIF contains any frames with transparent elements. */ gboolean has_transparency; @@ -263,7 +267,7 @@ vips_foreign_load_nsgif_set_header(VipsForeignLoadNsgif *gif, VIPS_DEBUG_MSG("vips_foreign_load_nsgif_set_header:\n"); vips_image_init_fields(image, - gif->info->width, gif->info->height * gif->n, + gif->info->width, gif->info->height * gif->gif_n, gif->has_transparency ? 4 : 3, VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, VIPS_INTERPRETATION_sRGB, 1.0, 1.0); @@ -272,9 +276,8 @@ vips_foreign_load_nsgif_set_header(VipsForeignLoadNsgif *gif, /* Only set page-height if we have more than one page, or this could * accidentally turn into an animated image later. */ - if (gif->n > 1) - vips_image_set_int(image, - VIPS_META_PAGE_HEIGHT, gif->info->height); + if (gif->gif_n > 1) + vips_image_set_int(image, VIPS_META_PAGE_HEIGHT, gif->info->height); vips_image_set_int(image, VIPS_META_N_PAGES, gif->info->frame_count); vips_image_set_int(image, "loop", gif->info->loop_max); @@ -435,11 +438,13 @@ vips_foreign_load_nsgif_header(VipsForeignLoad *load) } if (gif->n == -1) - gif->n = gif->info->frame_count - gif->page; + gif->gif_n = gif->info->frame_count - gif->page; + else + gif->gif_n = gif->n; if (gif->page < 0 || - gif->n <= 0 || - gif->page + gif->n > gif->info->frame_count) { + gif->gif_n <= 0 || + gif->page + gif->gif_n > gif->info->frame_count) { vips_error(class->nickname, "%s", _("bad page number")); return -1; } @@ -680,6 +685,7 @@ vips_foreign_load_nsgif_init(VipsForeignLoadNsgif *gif) } gif->n = 1; + gif->gif_n = 1; gif->frame_number = -1; gif->bitmap = NULL; } diff --git a/libvips/foreign/pdfiumload.c b/libvips/foreign/pdfiumload.c index 599f9cb30e..07d09b012c 100644 --- a/libvips/foreign/pdfiumload.c +++ b/libvips/foreign/pdfiumload.c @@ -277,7 +277,7 @@ vips_foreign_load_pdf_build(VipsObject *object) VIPS_ONCE(&once, vips_pdfium_init_cb, NULL); if (!vips_object_argument_isset(object, "scale")) - pdf->scale = pdf->dpi / 72.0; + pdf->scale = pdf->dpi / 72.0; // FIXME: Invalidates operation cache pdf->form_callbacks.version = 2; @@ -470,7 +470,7 @@ vips_foreign_load_pdf_header(VipsForeignLoad *load) /* @n == -1 means until the end of the doc. */ if (pdf->n == -1) - pdf->n = pdf->n_pages - pdf->page_no; + pdf->n = pdf->n_pages - pdf->page_no; // FIXME: Invalidates operation cache if (pdf->page_no + pdf->n > pdf->n_pages || pdf->page_no < 0 || diff --git a/libvips/foreign/popplerload.c b/libvips/foreign/popplerload.c index 59fcc6e3fd..79293f9a03 100644 --- a/libvips/foreign/popplerload.c +++ b/libvips/foreign/popplerload.c @@ -325,7 +325,7 @@ vips_foreign_load_pdf_header(VipsForeignLoad *load) /* @n == -1 means until the end of the doc. */ if (pdf->n == -1) - pdf->n = pdf->n_pages - pdf->page_no; + pdf->n = pdf->n_pages - pdf->page_no; // FIXME: Invalidates operation cache if (pdf->page_no + pdf->n > pdf->n_pages || pdf->page_no < 0 || diff --git a/libvips/foreign/tiffsave.c b/libvips/foreign/tiffsave.c index 75bf7c91d1..4075631861 100644 --- a/libvips/foreign/tiffsave.c +++ b/libvips/foreign/tiffsave.c @@ -147,73 +147,69 @@ vips_foreign_save_tiff_build(VipsObject *object) VipsForeignSave *save = (VipsForeignSave *) object; VipsForeignSaveTiff *tiff = (VipsForeignSaveTiff *) object; - const char *p; + if (VIPS_OBJECT_CLASS(vips_foreign_save_tiff_parent_class)->build(object)) + return -1; + + VipsImage *ready = save->ready; + g_object_ref(ready); /* If we are saving jpeg-in-tiff, we need a different convert_saveable * path. The regular tiff one will let through things like float and * 16-bit and alpha for example, which will make the jpeg saver choke. */ - if (save->in && - tiff->compression == VIPS_FOREIGN_TIFF_COMPRESSION_JPEG) { + if (tiff->compression == VIPS_FOREIGN_TIFF_COMPRESSION_JPEG) { VipsImage *x; /* See also vips_foreign_save_jpeg_class_init(). */ - if (vips__foreign_convert_saveable(save->in, &x, + if (vips__foreign_convert_saveable(ready, &x, VIPS_SAVEABLE_RGB_CMYK, bandfmt_jpeg, class->coding, - save->background)) + save->background)) { + VIPS_UNREF(ready); return -1; + } - g_object_set(object, "in", x, NULL); - g_object_unref(x); + VIPS_UNREF(ready); + ready = x; } - if (VIPS_OBJECT_CLASS(vips_foreign_save_tiff_parent_class)->build(object)) - return -1; - - /* Default xres/yres to the values from the image. This is always - * pixels/mm. - */ - if (!vips_object_argument_isset(object, "xres")) - tiff->xres = save->ready->Xres; - if (!vips_object_argument_isset(object, "yres")) - tiff->yres = save->ready->Yres; - - /* We default to pixels/cm. - */ - tiff->xres *= 10.0; - tiff->yres *= 10.0; - /* resunit param overrides resunit metadata. */ + VipsForeignTiffResunit resunit = tiff->resunit; + const char *p; if (!vips_object_argument_isset(object, "resunit") && - vips_image_get_typeof(save->ready, - VIPS_META_RESOLUTION_UNIT) && - !vips_image_get_string(save->ready, - VIPS_META_RESOLUTION_UNIT, &p) && + vips_image_get_typeof(ready, VIPS_META_RESOLUTION_UNIT) && + !vips_image_get_string(ready, VIPS_META_RESOLUTION_UNIT, &p) && vips_isprefix("in", p)) - tiff->resunit = VIPS_FOREIGN_TIFF_RESUNIT_INCH; + resunit = VIPS_FOREIGN_TIFF_RESUNIT_INCH; - if (tiff->resunit == VIPS_FOREIGN_TIFF_RESUNIT_INCH) { - tiff->xres *= 2.54; - tiff->yres *= 2.54; + double xres; + xres = ready->Xres; + if (vips_object_argument_isset(object, "xres")) { + if (resunit == VIPS_FOREIGN_TIFF_RESUNIT_INCH) + xres = tiff->xres * 25.4; + else + xres = tiff->xres * 10.0; } - /* Handle the deprecated squash parameter. - */ - if (tiff->squash) - /* We set that even in the case of LAB to LABQ. - */ - tiff->bitdepth = 1; + double yres; + yres = ready->Yres; + if (vips_object_argument_isset(object, "yres")) { + if (resunit == VIPS_FOREIGN_TIFF_RESUNIT_INCH) + yres = tiff->yres * 25.4; + else + yres = tiff->yres * 10.0; + } - if (vips__tiff_write_target(save->ready, tiff->target, + if (vips__tiff_write_target(ready, tiff->target, tiff->compression, tiff->Q, tiff->predictor, save->profile, tiff->tile, tiff->tile_width, tiff->tile_height, tiff->pyramid, - tiff->bitdepth, + // deprecated "squash" param + tiff->squash ? 1 : tiff->bitdepth, tiff->miniswhite, - tiff->resunit, tiff->xres, tiff->yres, + resunit, xres, yres, tiff->bigtiff, tiff->rgbjpeg, tiff->properties, @@ -223,8 +219,12 @@ vips_foreign_save_tiff_build(VipsObject *object) tiff->depth, tiff->subifd, tiff->premultiply, - save->page_height)) + save->page_height)) { + VIPS_UNREF(ready); return -1; + } + + VIPS_UNREF(ready); if (vips_target_end(tiff->target)) return -1; diff --git a/libvips/foreign/vips2magick.c b/libvips/foreign/vips2magick.c index 002f0b868d..ed5afbf006 100644 --- a/libvips/foreign/vips2magick.c +++ b/libvips/foreign/vips2magick.c @@ -503,8 +503,7 @@ vips_foreign_save_magick_class_init(VipsForeignSaveMagickClass *class) _("Optimize_gif_transparency"), _("Apply GIF transparency optimization"), VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET(VipsForeignSaveMagick, - optimize_gif_transparency), + G_STRUCT_OFFSET(VipsForeignSaveMagick, optimize_gif_transparency), FALSE); VIPS_ARG_INT(class, "bitdepth", 6, diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index edde31a272..2c4a3299f1 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -368,6 +368,8 @@ int vips__correl(VipsImage *ref, VipsImage *sec, int hwindowsize, int hsearchsize, double *correlation, int *x, int *y); +unsigned int vips_operation_hash(VipsOperation *operation); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index 7a187ec182..33df752c33 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -337,12 +337,14 @@ vips_object_hash_arg(VipsObject *object, /* Find a hash from the input arguments to a VipsOperstion. */ -static unsigned int +unsigned int vips_operation_hash(VipsOperation *operation) { - if (!operation->found_hash) { - guint hash; + guint hash; + if (operation->found_hash) + hash = operation->hash; + else { /* Include the operation type in the hash. */ hash = (guint) G_OBJECT_TYPE(operation); @@ -353,11 +355,16 @@ vips_operation_hash(VipsOperation *operation) */ hash |= 1; - operation->hash = hash; - operation->found_hash = TRUE; + /* The hash can change up to the moment of construction. After that, + * it should be fixed. + */ + if (VIPS_OBJECT(operation)->constructed) { + operation->hash = hash; + operation->found_hash = TRUE; + } } - return operation->hash; + return hash; } static void * @@ -393,7 +400,7 @@ vips_object_equal_arg(VipsObject *object, /* Optional and was not set on other ... we've found a * difference! */ - return object; + return (void *) name; g_value_init(&v1, type); g_value_init(&v2, type); @@ -405,7 +412,7 @@ vips_object_equal_arg(VipsObject *object, /* Stop (return non-NULL) if we've found a difference. */ - return !equal ? object : NULL; + return !equal ? (void *) name : NULL; } /* Are two objects equal, ie. have the same inputs. @@ -418,13 +425,49 @@ vips_operation_equal(VipsOperation *a, VipsOperation *b) if (G_OBJECT_TYPE(a) == G_OBJECT_TYPE(b) && vips_operation_hash(a) == vips_operation_hash(b) && - !vips_argument_map(VIPS_OBJECT(a), - vips_object_equal_arg, b, NULL)) + !vips_argument_map(VIPS_OBJECT(a), vips_object_equal_arg, b, NULL)) return TRUE; return FALSE; } +static void * +vips_operation_copy_argument(VipsObject *object, + GParamSpec *pspec, + VipsArgumentClass *argument_class, + VipsArgumentInstance *argument_instance, + void *a, void *b) +{ + VipsOperation *new = VIPS_OPERATION(a); + + if ((argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && + (argument_class->flags & VIPS_ARGUMENT_INPUT) && + argument_instance->assigned) { + const char *name = g_param_spec_get_name(pspec); + GType type = G_PARAM_SPEC_VALUE_TYPE(pspec); + GValue value = G_VALUE_INIT; + + g_value_init(&value, type); + g_object_get_property(G_OBJECT(object), name, &value); + g_object_set_property(G_OBJECT(new), name, &value); + g_value_unset(&value); + } + + return NULL; +} + +static VipsOperation * +vips_operation_copy(VipsOperation *operation) +{ + VipsObject *object = VIPS_OBJECT(operation); + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); + + VipsOperation *new = vips_operation_new(class->nickname); + (void) vips_argument_map(object, vips_operation_copy_argument, new, NULL); + + return new; +} + void * vips__cache_once_init(void *data) { @@ -828,12 +871,49 @@ vips_cache_operation_buildp(VipsOperation **operation) g_mutex_unlock(vips_cache_lock); /* If there was a miss, we need to build this operation and add - * it to the cache if appropriate. + * it to the cache, if appropriate. */ if (!hit) { + unsigned int hash_before = 0; + VipsOperation *operation_before = NULL; + + /* The _build method must not change the object hash. If it does, the + * finished operation won't detect hits with next identical call. + */ + if (vips__leak) { + hash_before = vips_operation_hash(*operation); + operation_before = vips_operation_copy(*operation); + } + if (vips_object_build(VIPS_OBJECT(*operation))) return -1; + if (vips__leak && + !(flags & VIPS_OPERATION_NOCACHE) && + hash_before != vips_operation_hash(*operation)) { + const char *name = (const char *) + vips_argument_map(VIPS_OBJECT(*operation), + vips_object_equal_arg, operation_before, NULL); + VipsObject *object = VIPS_OBJECT(*operation); + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); + + char txt[256]; + VipsBuf buf = VIPS_BUF_STATIC(txt); + + VIPS_UNREF(operation_before); + + vips_object_summary_class(class, &buf); + vips_buf_appends(&buf, ", "); + vips_object_summary(object, &buf); + vips_buf_appends(&buf, ", "); + vips_error(class->nickname, "arg \"%s\" changed during build, %s", + name, vips_buf_all(&buf)); + + return -1; + } + + VIPS_UNREF(operation_before); + /* Retrieve the flags again, as vips_foreign_load_build() may * set load->nocache. */ @@ -853,8 +933,7 @@ vips_cache_operation_buildp(VipsOperation **operation) printf("vips cache : "); else printf("vips cache+: "); - vips_object_print_summary( - VIPS_OBJECT(*operation)); + vips_object_print_summary(VIPS_OBJECT(*operation)); } if (!(flags & VIPS_OPERATION_NOCACHE)) diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index e0c017d673..489a2573b8 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -354,12 +354,11 @@ vips_object_check_required(VipsObject *object, GParamSpec *pspec, int vips_object_build(VipsObject *object) { - VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS(object); + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); /* Input and output args must both be set. */ - VipsArgumentFlags iomask = - VIPS_ARGUMENT_INPUT | VIPS_ARGUMENT_OUTPUT; + VipsArgumentFlags iomask = VIPS_ARGUMENT_INPUT | VIPS_ARGUMENT_OUTPUT; int result; @@ -369,7 +368,7 @@ vips_object_build(VipsObject *object) printf("\n"); #endif /*DEBUG*/ - if (object_class->build(object)) + if (class->build(object)) return -1; /* Check all required arguments have been supplied, don't stop on 1st @@ -2940,8 +2939,7 @@ vips_class_build_hash_cb(void *dummy) { GType base; - vips__object_nickname_table = - g_hash_table_new(g_str_hash, g_str_equal); + vips__object_nickname_table = g_hash_table_new(g_str_hash, g_str_equal); base = g_type_from_name("VipsObject"); g_assert(base); @@ -2982,8 +2980,7 @@ vips_type_find(const char *basename, const char *nickname) VIPS_ONCE(&once, vips_class_build_hash_cb, NULL); hit = (NicknameGType *) - g_hash_table_lookup(vips__object_nickname_table, - (void *) nickname); + g_hash_table_lookup(vips__object_nickname_table, (void *) nickname); /* We must only search below basename ... check that the cache hit is * in the right part of the tree. @@ -3163,14 +3160,12 @@ vips__object_leak(void) /* Don't count static objects. */ if (vips__object_all && - g_hash_table_size(vips__object_all) > - vips_object_n_static()) { + g_hash_table_size(vips__object_all) > vips_object_n_static()) { fprintf(stderr, "%d objects alive:\n", g_hash_table_size(vips__object_all)); vips_object_map( - (VipsSListMap2Fn) vips_object_print_all_cb, - &n_leaks, NULL); + (VipsSListMap2Fn) vips_object_print_all_cb, &n_leaks, NULL); } return n_leaks; diff --git a/libvips/mosaicing/match.c b/libvips/mosaicing/match.c index e8e2c94daf..662046992e 100644 --- a/libvips/mosaicing/match.c +++ b/libvips/mosaicing/match.c @@ -122,7 +122,7 @@ vips_match_build(VipsObject *object) return -1; if (!match->interpolate) - match->interpolate = vips_interpolate_new("bilinear"); + match->interpolate = vips_interpolate_new("bilinear"); // FIXME: Invalidates operation cache if (match->search) { int xs, ys; @@ -133,8 +133,8 @@ vips_match_build(VipsObject *object) match->hwindow, match->harea, &cor, &xs, &ys)) return -1; - match->xs1 = xs; - match->ys1 = ys; + match->xs1 = xs; // FIXME: Invalidates operation cache + match->ys1 = ys; // FIXME: Invalidates operation cache if (vips__correl(match->ref, match->sec, match->xr2, match->yr2, match->xs2, match->ys2, @@ -142,8 +142,8 @@ vips_match_build(VipsObject *object) &cor, &xs, &ys)) return -1; - match->xs2 = xs; - match->ys2 = ys; + match->xs2 = xs; // FIXME: Invalidates operation cache + match->ys2 = ys; // FIXME: Invalidates operation cache } /* Solve to get scale + rot + disp to obtain match. diff --git a/libvips/mosaicing/mosaic1.c b/libvips/mosaicing/mosaic1.c index efe6fb8b7c..dcfc28adeb 100644 --- a/libvips/mosaicing/mosaic1.c +++ b/libvips/mosaicing/mosaic1.c @@ -454,7 +454,7 @@ vips_mosaic1_build(VipsObject *object) return -1; if (!mosaic1->interpolate) - mosaic1->interpolate = vips_interpolate_new("bilinear"); + mosaic1->interpolate = vips_interpolate_new("bilinear"); // FIXME: Invalidates operation cache jfn = mosaic1->direction == VIPS_DIRECTION_HORIZONTAL ? vips__lrmerge1 diff --git a/libvips/resample/affine.c b/libvips/resample/affine.c index 74881ddabe..c950db41b3 100644 --- a/libvips/resample/affine.c +++ b/libvips/resample/affine.c @@ -156,6 +156,10 @@ typedef struct _VipsAffine { VipsTransformation trn; + /* Interpolate parameter, prepared and ready for use. + */ + VipsInterpolate *affine_interpolate; + /* How to generate extra edge pixels. */ VipsExtend extend; @@ -178,6 +182,16 @@ typedef VipsResampleClass VipsAffineClass; G_DEFINE_TYPE(VipsAffine, vips_affine, VIPS_TYPE_RESAMPLE); +static void +vips_affine_dispose(GObject *gobject) +{ + VipsAffine *affine = (VipsAffine *) gobject; + + VIPS_UNREF(affine->affine_interpolate); + + G_OBJECT_CLASS(vips_affine_parent_class)->dispose(gobject); +} + /* We have five (!!) coordinate systems. Working forward through them, these * are: * @@ -216,12 +230,11 @@ vips_affine_gen(VipsRegion *out_region, VipsRegion *ir = (VipsRegion *) seq; const VipsAffine *affine = (VipsAffine *) b; const VipsImage *in = (VipsImage *) a; - const int window_size = - vips_interpolate_get_window_size(affine->interpolate); - const int window_offset = - vips_interpolate_get_window_offset(affine->interpolate); - const VipsInterpolateMethod interpolate = - vips_interpolate_get_method(affine->interpolate); + VipsInterpolate *interpolate = affine->affine_interpolate; + const int window_size = vips_interpolate_get_window_size(interpolate); + const int window_offset = vips_interpolate_get_window_offset(interpolate); + const VipsInterpolateMethod interpolate_method = + vips_interpolate_get_method(interpolate); /* Area we generate in the output image. */ @@ -374,7 +387,7 @@ vips_affine_gen(VipsRegion *out_region, (int) iy - window_offset + window_size - 1)); - interpolate(affine->interpolate, q, ir, ix, iy); + interpolate_method(interpolate, q, ir, ix, iy); } else { /* Out of range: paint the background. @@ -420,27 +433,28 @@ vips_affine_build(VipsObject *object) if (vips_check_coding_known(class->nickname, resample->in)) return -1; - if (vips_check_vector_length(class->nickname, - affine->matrix->n, 4)) + if (vips_check_vector_length(class->nickname, affine->matrix->n, 4)) return -1; if (vips_object_argument_isset(object, "oarea") && - vips_check_vector_length(class->nickname, - affine->oarea->n, 4)) + vips_check_vector_length(class->nickname, affine->oarea->n, 4)) return -1; - /* Can be set explicitly to NULL to mean default setting. + /* "interpolate" be set explicitly to NULL to mean default setting. */ - if (!affine->interpolate) - affine->interpolate = vips_interpolate_new("bilinear"); + affine->affine_interpolate = affine->interpolate; + if (affine->affine_interpolate) + g_object_ref(affine->affine_interpolate); + else + affine->affine_interpolate = vips_interpolate_new("bilinear"); in = resample->in; /* Set up transform. */ - window_size = vips_interpolate_get_window_size(affine->interpolate); + window_size = vips_interpolate_get_window_size(affine->affine_interpolate); window_offset = - vips_interpolate_get_window_offset(affine->interpolate); + vips_interpolate_get_window_offset(affine->affine_interpolate); affine->trn.iarea.left = 0; affine->trn.iarea.top = 0; @@ -618,6 +632,7 @@ vips_affine_class_init(VipsAffineClass *class) VIPS_DEBUG_MSG("vips_affine_class_init\n"); + gobject_class->dispose = vips_affine_dispose; gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; diff --git a/libvips/resample/quadratic.c b/libvips/resample/quadratic.c index e24b37e46a..faf6472792 100644 --- a/libvips/resample/quadratic.c +++ b/libvips/resample/quadratic.c @@ -293,7 +293,7 @@ vips_quadratic_build(VipsObject *object) } if (!quadratic->interpolate) - quadratic->interpolate = vips_interpolate_new("bilinear"); + quadratic->interpolate = vips_interpolate_new("bilinear"); // FIXME: Invalidates operation cache window_size = vips_interpolate_get_window_size(quadratic->interpolate); window_offset = vips_interpolate_get_window_offset(quadratic->interpolate); diff --git a/libvips/resample/reduceh.cpp b/libvips/resample/reduceh.cpp index 4e369c92e9..f1f3787b00 100644 --- a/libvips/resample/reduceh.cpp +++ b/libvips/resample/reduceh.cpp @@ -82,6 +82,10 @@ typedef struct _VipsReduceh { */ double hoffset; + /* The hshrink we do after integer reduction. + */ + double residual_hshrink; + /* Precalculated interpolation matrices. short (used for pel * sizes up to int), and double (for all others). We go to * scale + 1 so we can round-to-nearest safely. @@ -202,7 +206,7 @@ static void inline reduceh_notab(VipsReduceh *reduceh, typename LongT::type cx[MAX_POINT]; vips_reduce_make_mask(cx, reduceh->kernel, reduceh->n_point, - reduceh->hshrink, x); + reduceh->residual_hshrink, x); for (int z = 0; z < bands; z++) out[z] = reduce_sum(in + z, bands, cx, n); @@ -230,9 +234,9 @@ vips_reduceh_gen(VipsRegion *out_region, void *seq, r->width, r->height, r->left, r->top); #endif /*DEBUG*/ - s.left = r->left * reduceh->hshrink - reduceh->hoffset; + s.left = r->left * reduceh->residual_hshrink - reduceh->hoffset; s.top = r->top; - s.width = r->width * reduceh->hshrink + reduceh->n_point; + s.width = r->width * reduceh->residual_hshrink + reduceh->n_point; s.height = r->height; if (vips_region_prepare(ir, &s)) return -1; @@ -247,7 +251,7 @@ vips_reduceh_gen(VipsRegion *out_region, void *seq, q = VIPS_REGION_ADDR(out_region, r->left, r->top + y); - X = (r->left + 0.5) * reduceh->hshrink - 0.5 - + X = (r->left + 0.5) * reduceh->residual_hshrink - 0.5 - reduceh->hoffset; /* We want p0 to be the start (ie. x == 0) of the input @@ -319,7 +323,7 @@ vips_reduceh_gen(VipsRegion *out_region, void *seq, break; } - X += reduceh->hshrink; + X += reduceh->residual_hshrink; q += ps; } } @@ -350,9 +354,9 @@ vips_reduceh_uchar_vector_gen(VipsRegion *out_region, void *seq, r->width, r->height, r->left, r->top); #endif /*DEBUG*/ - s.left = r->left * reduceh->hshrink - reduceh->hoffset; + s.left = r->left * reduceh->residual_hshrink - reduceh->hoffset; s.top = r->top; - s.width = r->width * reduceh->hshrink + reduceh->n_point; + s.width = r->width * reduceh->residual_hshrink + reduceh->n_point; s.height = r->height; if (vips_region_prepare(ir, &s)) return -1; @@ -367,14 +371,14 @@ vips_reduceh_uchar_vector_gen(VipsRegion *out_region, void *seq, q = VIPS_REGION_ADDR(out_region, r->left, r->top + y); - X = (r->left + 0.5) * reduceh->hshrink - 0.5 - + X = (r->left + 0.5) * reduceh->residual_hshrink - 0.5 - reduceh->hoffset; p0 = VIPS_REGION_ADDR(ir, ir->valid.left, r->top + y) - ir->valid.left * ps; vips_reduceh_uchar_hwy(q, p0, reduceh->n_point, r->width, - bands, reduceh->matrixs, X, reduceh->hshrink); + bands, reduceh->matrixs, X, reduceh->residual_hshrink); } VIPS_GATE_STOP("vips_reduceh_uchar_vector_gen: work"); @@ -422,6 +426,10 @@ vips_reduceh_build(VipsObject *object) */ extra_pixels = width * reduceh->hshrink - in->Xsize; + /* The hshrink we do after integer reduction. + */ + reduceh->residual_hshrink = reduceh->hshrink; + if (reduceh->gap > 0.0 && reduceh->kernel != VIPS_KERNEL_NEAREST) { if (reduceh->gap < 1.0) { @@ -443,16 +451,16 @@ vips_reduceh_build(VipsObject *object) return -1; in = t[0]; - reduceh->hshrink /= int_hshrink; + reduceh->residual_hshrink /= int_hshrink; extra_pixels /= int_hshrink; } } - if (reduceh->hshrink == 1.0) + if (reduceh->residual_hshrink == 1.0) return vips_image_write(in, resample->out); reduceh->n_point = - vips_reduce_get_points(reduceh->kernel, reduceh->hshrink); + vips_reduce_get_points(reduceh->kernel, reduceh->residual_hshrink); g_info("reduceh: %d point mask", reduceh->n_point); if (reduceh->n_point > MAX_POINT) { vips_error(object_class->nickname, @@ -479,7 +487,7 @@ vips_reduceh_build(VipsObject *object) return -1; vips_reduce_make_mask(reduceh->matrixf[x], reduceh->kernel, - reduceh->n_point, reduceh->hshrink, + reduceh->n_point, reduceh->residual_hshrink, (float) x / VIPS_TRANSFORM_SCALE); for (int i = 0; i < reduceh->n_point; i++) diff --git a/libvips/resample/reducev.cpp b/libvips/resample/reducev.cpp index 3cc3f6fbbe..3d19cb856e 100644 --- a/libvips/resample/reducev.cpp +++ b/libvips/resample/reducev.cpp @@ -125,6 +125,10 @@ typedef struct _VipsReducev { */ double voffset; + /* The vshrink we do after integer reduction. + */ + double residual_vshrink; + /* Precalculated interpolation matrices. short (used for pel * sizes up to int), and double (for all others). We go to * scale + 1 so we can round-to-nearest safely. @@ -471,7 +475,7 @@ static void inline reducev_notab(VipsReducev *reducev, typename LongT::type cy[MAX_POINT]; vips_reduce_make_mask(cy, reducev->kernel, reducev->n_point, - reducev->vshrink, y); + reducev->residual_vshrink, y); for (int z = 0; z < ne; z++) out[z] = reduce_sum(in + z, l1, cy, n); @@ -501,15 +505,15 @@ vips_reducev_gen(VipsRegion *out_region, void *vseq, #endif /*DEBUG*/ s.left = r->left; - s.top = r->top * reducev->vshrink - reducev->voffset; + s.top = r->top * reducev->residual_vshrink - reducev->voffset; s.width = r->width; - s.height = r->height * reducev->vshrink + reducev->n_point; + s.height = r->height * reducev->residual_vshrink + reducev->n_point; if (vips_region_prepare(ir, &s)) return -1; VIPS_GATE_START("vips_reducev_gen: work"); - double Y = (r->top + 0.5) * reducev->vshrink - 0.5 - + double Y = (r->top + 0.5) * reducev->residual_vshrink - 0.5 - reducev->voffset; for (int y = 0; y < r->height; y++) { @@ -572,7 +576,7 @@ vips_reducev_gen(VipsRegion *out_region, void *vseq, break; } - Y += reducev->vshrink; + Y += reducev->residual_vshrink; } VIPS_GATE_STOP("vips_reducev_gen: work"); @@ -603,15 +607,15 @@ vips_reducev_uchar_vector_gen(VipsRegion *out_region, void *vseq, #endif /*DEBUG*/ s.left = r->left; - s.top = r->top * reducev->vshrink - reducev->voffset; + s.top = r->top * reducev->residual_vshrink - reducev->voffset; s.width = r->width; - s.height = r->height * reducev->vshrink + reducev->n_point; + s.height = r->height * reducev->residual_vshrink + reducev->n_point; if (vips_region_prepare(ir, &s)) return -1; VIPS_GATE_START("vips_reducev_uchar_vector_gen: work"); - double Y = (r->top + 0.5) * reducev->vshrink - 0.5 - + double Y = (r->top + 0.5) * reducev->residual_vshrink - 0.5 - reducev->voffset; for (int y = 0; y < r->height; y++) { @@ -629,7 +633,7 @@ vips_reducev_uchar_vector_gen(VipsRegion *out_region, void *vseq, q, p, reducev->n_point, ne, lskip, cys); - Y += reducev->vshrink; + Y += reducev->residual_vshrink; } VIPS_GATE_STOP("vips_reducev_uchar_vector_gen: work"); @@ -662,9 +666,9 @@ vips_reducev_vector_gen(VipsRegion *out_region, void *vseq, #endif /*DEBUG_PIXELS*/ s.left = r->left; - s.top = r->top * reducev->vshrink - reducev->voffset; + s.top = r->top * reducev->residual_vshrink - reducev->voffset; s.width = r->width; - s.height = r->height * reducev->vshrink + reducev->n_point; + s.height = r->height * reducev->residual_vshrink + reducev->n_point; if (vips_region_prepare(ir, &s)) return -1; @@ -680,7 +684,7 @@ vips_reducev_vector_gen(VipsRegion *out_region, void *vseq, VIPS_GATE_START("vips_reducev_vector_gen: work"); - double Y = (r->top + 0.5) * reducev->vshrink - 0.5 - + double Y = (r->top + 0.5) * reducev->residual_vshrink - 0.5 - reducev->voffset; for (int y = 0; y < r->height; y++) { @@ -727,7 +731,7 @@ vips_reducev_vector_gen(VipsRegion *out_region, void *vseq, printf("\t%d\n", *q); #endif /*DEBUG_PIXELS*/ - Y += reducev->vshrink; + Y += reducev->residual_vshrink; } VIPS_GATE_STOP("vips_reducev_vector_gen: work"); @@ -848,14 +852,17 @@ vips_reducev_build(VipsObject *object) /* Output size. We need to always round to nearest, so round(), not * rint(). */ - height = VIPS_ROUND_UINT( - (double) in->Ysize / reducev->vshrink); + height = VIPS_ROUND_UINT((double) in->Ysize / reducev->vshrink); /* How many pixels we are inventing in the input, -ve for * discarding. */ extra_pixels = height * reducev->vshrink - in->Ysize; + /* The vshrink we do after integer reduction. + */ + reducev->residual_vshrink = reducev->vshrink; + if (reducev->gap > 0.0 && reducev->kernel != VIPS_KERNEL_NEAREST) { if (reducev->gap < 1.0) { @@ -877,16 +884,16 @@ vips_reducev_build(VipsObject *object) return -1; in = t[0]; - reducev->vshrink /= int_vshrink; extra_pixels /= int_vshrink; + reducev->residual_vshrink /= int_vshrink; } } - if (reducev->vshrink == 1.0) + if (reducev->residual_vshrink == 1.0) return vips_image_write(in, resample->out); reducev->n_point = - vips_reduce_get_points(reducev->kernel, reducev->vshrink); + vips_reduce_get_points(reducev->kernel, reducev->residual_vshrink); g_info("reducev: %d point mask", reducev->n_point); if (reducev->n_point > MAX_POINT) { vips_error(object_class->nickname, @@ -904,21 +911,19 @@ vips_reducev_build(VipsObject *object) /* Build the tables of pre-computed coefficients. */ for (int y = 0; y < VIPS_TRANSFORM_SCALE + 1; y++) { - reducev->matrixf[y] = - VIPS_ARRAY(object, reducev->n_point, double); - reducev->matrixs[y] = - VIPS_ARRAY(object, reducev->n_point, short); + reducev->matrixf[y] = VIPS_ARRAY(object, reducev->n_point, double); + reducev->matrixs[y] = VIPS_ARRAY(object, reducev->n_point, short); if (!reducev->matrixf[y] || !reducev->matrixs[y]) return -1; vips_reduce_make_mask(reducev->matrixf[y], reducev->kernel, - reducev->n_point, reducev->vshrink, + reducev->n_point, reducev->residual_vshrink, (float) y / VIPS_TRANSFORM_SCALE); for (int i = 0; i < reducev->n_point; i++) - reducev->matrixs[y][i] = (short) (reducev->matrixf[y][i] * - VIPS_INTERPOLATE_SCALE); + reducev->matrixs[y][i] = + (short) (reducev->matrixf[y][i] * VIPS_INTERPOLATE_SCALE); #ifdef DEBUG printf("vips_reducev_build: mask %d\n ", y); for (int i = 0; i < reducev->n_point; i++) diff --git a/test/test-suite/test_foreign.py b/test/test-suite/test_foreign.py index 8ddbd2cd90..87dc50cebd 100644 --- a/test/test-suite/test_foreign.py +++ b/test/test-suite/test_foreign.py @@ -1067,7 +1067,9 @@ def gif_valid(im): assert x2.get("bits-per-sample") == 4 assert x2.get("palette") == 1 - x2 = pyvips.Image.new_from_file(GIF_ANIM_FILE, n=-1) + x2 = pyvips.Image.new_from_file(GIF_ANIM_FILE, + n=-1, + access="sequential") # our test gif has delay 0 for the first frame set in error assert x2.get("delay") == [0, 50, 50, 50, 50] assert x2.get("loop") == 32761 From 35cc76e9eb364725827499ba79171f27f9c9e61a Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 23 Jan 2025 16:28:52 +0100 Subject: [PATCH 043/174] Fix typo (#4357) --- libvips/foreign/fits.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvips/foreign/fits.c b/libvips/foreign/fits.c index 03008c3c30..49f1ff958d 100644 --- a/libvips/foreign/fits.c +++ b/libvips/foreign/fits.c @@ -575,7 +575,7 @@ vips_fits_new_write(VipsImage *in, const char *filename) VIPS_IMAGE_SIZEOF_ELEMENT(in) * in->Xsize, VipsPel))) return NULL; - /* fits_create_file() will fail if there's a file of thet name, unless + /* fits_create_file() will fail if there's a file of that name, unless * we put a "!" in front of the filename. This breaks conventions with * the rest of vips, so just unlink explicitly. */ From 27b2f393e8cc0dcee17557fcfa7bc536398cc68b Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 23 Jan 2025 16:30:11 +0100 Subject: [PATCH 044/174] Simplify `@background` initialization (#4356) --- libvips/conversion/arrayjoin.c | 8 +++----- libvips/conversion/join.c | 6 ++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/libvips/conversion/arrayjoin.c b/libvips/conversion/arrayjoin.c index 81c7cb0bab..8c086d1c23 100644 --- a/libvips/conversion/arrayjoin.c +++ b/libvips/conversion/arrayjoin.c @@ -64,7 +64,7 @@ typedef struct _VipsArrayjoin { VipsArrayImage *in; int across; int shim; - VipsArea *background; + VipsArrayDouble *background; VipsAlign halign; VipsAlign valign; int hspacing; @@ -224,7 +224,7 @@ vips_arrayjoin_build(VipsObject *object) */ band = (VipsImage **) vips_object_local_array(object, n); if (vips__bandalike_vec(class->nickname, - in, band, n, join->background->n)) + in, band, n, VIPS_AREA(join->background)->n)) return -1; in = band; @@ -452,9 +452,7 @@ vips_arrayjoin_init(VipsArrayjoin *join) { /* Init our instance fields. */ - join->background = - vips_area_new_array(G_TYPE_DOUBLE, sizeof(double), 1); - ((double *) (join->background->data))[0] = 0.0; + join->background = vips_array_double_newv(1, 0.0); } static int diff --git a/libvips/conversion/join.c b/libvips/conversion/join.c index ef7896d5d3..5d6dd7c767 100644 --- a/libvips/conversion/join.c +++ b/libvips/conversion/join.c @@ -81,7 +81,7 @@ typedef struct _VipsJoin { VipsDirection direction; gboolean expand; int shim; - VipsArea *background; + VipsArrayDouble *background; VipsAlign align; } VipsJoin; @@ -286,9 +286,7 @@ vips_join_init(VipsJoin *join) { /* Init our instance fields. */ - join->background = - vips_area_new_array(G_TYPE_DOUBLE, sizeof(double), 1); - ((double *) (join->background->data))[0] = 0.0; + join->background = vips_array_double_newv(1, 0.0); } /** From 7949f5bad56055e7d3f476bc1906a742944d9283 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 24 Jan 2025 12:32:17 +0100 Subject: [PATCH 045/174] Test: regenerate XYB JPEG fixture (#4358) After commit https://github.com/libjxl/libjxl/commit/e9e60cc2937898d7db855267006c2ee6462cd3d3, libjxl/jpegli generates an XYB profile with a no-op B2A0 tag, improving compatibility with more applications. --- test/test-suite/images/sample-xyb.jpg | Bin 60121 -> 27474 bytes test/test-suite/test_resample.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test-suite/images/sample-xyb.jpg b/test/test-suite/images/sample-xyb.jpg index 6e802dc85b696602d1e55b9bddbeaa013f056d56..376d92557b8da286aafd6d365e9eafee72ff4717 100644 GIT binary patch literal 27474 zcma%ibyOYAv*5+u-JReL!69&QcXtc!4#C|M+}*jjUEJN>9RdWmAPLL&`_8_%f4n`r zb*8GiqFtg0j_BQF7ffB*m>XKlRf$e~3609P{y7gZ@S za%~-5a<~HkGT_7d515#_I(<=Amj74!pXlTAzrG91|BR&(zm<%}0S%im9F5n6BI5f$ z_4q$@u;v!7W*_q82QryCxww7s-ycZr>E`s&h9LfEW1D?7G5=_@{p0h6L+pb?=zk!! z7{`~7He}$3UfJHx{hx9Efqx=Lws6o;`{1Y_NDR;h=m5k3MgV1i1;7OW_`mqV{>N7w zAP)E#^`AU^$RF_E^K-T2N z)7YK&`+EY?*N{b#@r@;}?jJN~bB zh~S0y_uZv`?brnXh)})vzlR_Gn3^AV{K!>O;748*-~VR!0U$`!0f5@rkMJTtF!Td6 z?8Uy2|I_#X$k9LIf5Csn^N;5LBS-HWfFS@92?;qFIVlMVDFrDxDFr1NF)4J8@L z2j!xtrlFyx=VGOyp{1c=Wo72)XJ%yE;v|NSU9*3 z3I_-O!9OSh{6_;G9^r$30K&h3h=hQIh=hoU^dE`{34@A?iH?bbj*f$eOMr_PHmx7)uRAuu4JDA+N-P;x+HiD3XBA)p|kp;3)i=BxIDn1q=NT#05X*7 z#~eP^f(YO)tKI7aj5^4d6uBFED^ zK^Eu>0Zb7KO7!x0c;xBAuuMm|)Z{vj#YnOjoyIc+v1WgdI5Bmm(moT@3aw}<5DwK` zz5_~z3g7ZQakne6Rgabyet{H!hH#lfO%x^O|1^+WV+}KbS)>u4d|Z$MZCY_oAjCo= zJ*e1lK|8eZV2$=!w8ap134OyK2t-4&&$dY72ttx_$75?ApQh$XQX!}m>Mw96Hm>4` zp4~xnf?ZUCoWWH){0!2;v)}-@m=c(C&10Mp7uZ7NnxInM&)ZSK{_uWfmRB3*Yzw&| z@(IqURK7uSHjWAjJY!JI%-90vg^BtOkk-D9Q(|WgMY5rdMIuLj#j@tv{!5{Gy^c{yev(UkAm%uGanNckIlE^uzB)oum z5T`7uLQs_Ntr@tN;I#NN9ET%6*E}Hn`yBAn9Qd4w+3BKvpuit)fMS#^W6pSptNf>o5m+=C3sp^v4gsmHk!bHh(bPH8Gm{L> zN5o^AB#KljbwrPDoHWT3enj96S@Bt530Nm*VXYsqb9r-lG`9+8SVz}#jF*IG4_#$Q zKwyL)nZdM@xcKD@gfn6X_hoLbas162n7p}MUtUi)Xats&00H&IQv?xZgOYu>f7LhC z=kv0he=VHpS|wd}i^&yqjg#oMbtetzDllf9A)l%q$u#~FFNF+ z!9$EgyBHs=Nl;QgW_dKIjFw75x8g}^XcGS7#}!;ggSEIE76=Z7!IsP3i1o5q1ha>v zeW9*$8i6ruiu66JEG9K#hwpurvQ~!d>zkTn&toM$Yd|+2BnC3Z22=*FTo{Z`?o*OS zU>rylC{T^LqDoEtIm@i)A;?xDxVLn*HM#S41QKb8i9~#H|2d&b7YzXUU&7$;9&v5y#5xC8AvskYf%cj%^+M_9`=o+plAMk64rI64c$9Yv;D z@RxjBP)r4(g!c9(r1QCxKvaYU%hW04%485QNrB_3wK5?bFG*pWEcK)Hb=CE{3h`Vy zubgPA!LTLRx98$MyS%+FG3h{&J33QQd*ek;2Ov$9#UyIa6@m;GiewY2&a~S#|K` zsnbBLIB{kBO_@<+D)6;p!h=S_%T8$#^Eoky@A$LBHW--u16HlfpqXNdMITQ2DTP)I z+vmy>H^wCDt^cA@9aGYJ$`xH6#8-$Qf@PMOUKIEVlz5wfxbT%AOf;=b%e^+wK zcX&TxHnqE^I%3NX3M=P<3sxSio>U_9OmJ7{-f#y!be?1;P+25rP|2|;K3+kmK_ zCDb(mtZ`ZsU?F**h`$45Xc&eaP+1Ho?=C4z-oQzjI#9+URDx-C~k9%iG&E|&U5 zT?YkhYpn7yoL+rJBNL(=2CcJ;Te5cBeyH&R@nqCSh5BO{GgNn&AeAxfNAOH;f8rqw zYQF<8lxy!RN5@@7_((JL4;BguO{&@8C&I;-^bOm`Ev`GU^<^zOeZwPAQCLhm2cm8% z2cyG_X^Ajk>zL9~v?X818tr6@>sSg|qKmk1xTyxk^YbHEGTQ){Aw6vteS^j#OkLaz z7~=%QcFWIDxrGd{rLVp+tw1O=PK+&eBr6Cf$!(arTqh-oMJCyUd< zlCm8Pr;39}d<+Ld)q9X}2JiqbPk2-TMtKD* zyJmLxB0zhK*V``1KK7DidX=vS^l#c}Sb+*3O{NW9mNokgtS#x{O16mIN5*&o=fc3& zQTM98_V;hm#+uf&r)Wxai?^pnr69~v6CPW+6k1~;gL@oXo|YHe-$NDXqp3i{ z%({B7;+*l-`s00~Xe578orR0p*JYC4)^I+igpPNBw#whA3WZksHuGuC{xig7w)xRh}yBQ!5F6z!>tM8oBwmOhI$_2+RZFLWVB*#lP0qW?oYEN(+Rh8QF)tkB5AoYBY}H za|GynBa>1s?S?WJbp|zsJI+j$@f2sp3!ETGlW;7|I;sgW1B(h^fldO>NScZUJ>##M z%R)^TU{{8PR^>Nr%sSn*E`VT8S3swQVG(YkC+;P8wdm4mF1Q56Mf1R777rE>PN|_T zI1$A}YZi(-Ux8JucMe?RdWIV|3gHLaT$@emh0k#2{Jt2@kAYVs>&o_+)2%Pe2oCd8 z`r}4F7ti!}wB*8o{tWv3m;L@m@WNA1)MP2e%Ra8hd}CzPYjfmD3J)<(<1w^%*>{+Q zR^$o;E&_8X-oDFNPt|>->}}5eDP^12nbK-{8&m{SOqG71_Zr&K0tH=>vcUkQB;E+t zP@V)2dZ8mTjGb@=Nsk1KVhHUsl-(d`*()Pg9=s4{8^&3~k)<0KJ!q`v*Ndga#yQ;>ecuCJ^ovs0(ewrVM2M18D1CL9}~p%kni z1zUG!6L~oO3=BE=TRF2{5ftVCuMI_^_B3eV9?k-HYDi+{$uUh%>41}@p>2ZH#qN?G znUoe3WiI@)2Q>nv=t_<9C~GPHmo;yVK^_`HRyyz2d=ID=qr_I(%yGA14r5-fQYG|z z(`J)sS-f_VhH~8zQwn{qh>V1Es?S4>WSxohaR1hdJpB0I-CEOmXd0_|4R!@mYDiPw z;koMd=+F|!13u%v*Ks-vVV!qCDd)3w2Vu?zt3hk}$mi3N0~)uX`F%obTxnw+f3gS# zA+(MjXKxxTxQzYApXh(wVZ&OUf65Hl7bg%$pq{1I`=aWjMF$<;jchY@Si94t!9|)I zz#)WUT;vA7fmu{ZoHM=UW&P)(VxXnUGNcM*=l4&Pcu6FeY1a>20ipRgr3tWRUVmL@M9m!4mZ^qjMJS~v~g?3CxNPgBaz@Fl1Icd(dHDHdIz@UaX znQpr}Bd|dT=P7W|4j1LyAc1{FO~tVJ94ADDcG>mPAvJG`TA$e=d)a4eH& zTjd(S=_$#*=tqf9YVQDGI^^>Dn#UaJwa>T8sqR=iD!!?(I;ka{_80eOaHBZRK1a%! z1Ic2Cf5e0pbJ-vcBRg?e{j$10BbB}<>0xW^XlcoKivEi@G~yl2S!>WC#vDVT zdcBI#T$~n;zjt;k7r$;D7>*2qwFIRhGJL)ye=*z}u`$GzRa8QjYp4z`@buW7c8(Ee zYJJ!P0+xMJ2Gm`6%RTNNHO?wBe}eM!aogAioK?RoC~rx(EJY8qqZ%y%tztGtTO`sM zM0e3r#ZL=+;VQf4msqqiA8`#cGnHUVJAe}?$e)S$_{`Rx+_kYU9E!c;-A0wT2BpF9 z4A$u+0eE2utw0WTc4xr-(k`>E4dhU*Vr%Sr;l_i?o;Yy3hBa)bD9|biJ^V&wPK?gl z=Fx9O_;xK;H0X8}D(cP`e`ccen>#;Cm*(_|{0$V}rq#st>Qz;Jr)4h1Bcv;05QoW8 z>NUBAx*?YRh7+@}IEw04vG`95`;;&{9R$4t_I_yRtu2kOuCJEls~Fdq{5IGW^}|pJ zITByc~eHl%mu#3at5WpH<~HYjS@o;o4U(V`<#z zdJW>Ev7)a7xk4<@mb9QHH?Vvn6H+Igh7;~iC6RKG*%FD(TfH^C?|;Va;MZvrh&DxR z-H;^X`og?wdXYyM)WL-EM!(Yi(u@S1vF%*BQl0L^p``2Dwsh4SVme7e(hAl+{IxLR zCWJ+^`pmb_7q6YdkX!8QjDIxP1piHYfubhmPf;S0aUz>X0>qkxW_kg?e?<>|I>-Hk z^02wx%=OCKl2=PeA5Zo~Io-ZH5a{;%Xw#q%$OLEedRIn6o4e2z;yy^c4`9T&SJoif zR05XckQ(%>7x$XcN;hc#lt;f{0)K79i-xiF7?YScAa)vzsH=QHWKyO;K0za%V3J$W zXcBSQ4{EVgcCmyR7y3OnE_c=5=A6@6qv9a(1Bs9y`l{AWLKqc?i380u&~7@Pb;E{r zVR;#+2@2?GDwJ#t`rbu!v;$K|&pJ>AN;PxrN^e&Y`ev?|sZLkOpNmLtI*$?)%TA`i zp-NXYq66$Y)2?a1#F!xzvd6x3IKI_pBXT~wUt;Jg3rr^%eeJEm$b1-@ly9K*0%(|4 zVfgQ2DdG(lE$OL1uH@>xR0R5M9btE%6MR-JB}@GxPAMU}xvh_QsL+x2pfXy%X2&vR zOrN3M=gt&S`D0c+xt+W}M!xIHv9NKy+|yu#D5vt*NdzO4ypOkA^%5@jlvG;38k7Uf z?Fgt0$Ptkl?=6?18o^=`e|xM74v#-qIe`m<`I4*Sa83wQ4nAAINV4?_Ar7%N%l!ll zKF$z^-3^3^5S(--+0)SFUh1pMVt|Kr$H0?dMVIes>&}Y#rn*;36@^C}obk-f*d_T( z#yWY1*qKSnf>ew|DWr+F&1(WV^Jiki#ssN`w2eILCT_j!=$rq)|G+&o_w5s8k*0 z^j?~^P}DW)kxaclQcUN-qrB5|IZWBfRe!xuNwEI!_30-1&!V4WTi^qK7>ZGC>DZ0P z!pf#jA514z@SADdtFmR=WRU~()9`r za`#Tm$c#tEG6st>GsTuRv*6hJ6_&lKU7gj)&@)B?B5+G>0wuR+%e$cbp1-ZGbvSozM=;L5O<5FQ zbkkPAcqt^X914Zl2m-WgKPr=QUafsrJ5Fg$dkQFOeFvN%a$s=%a8ycX188I3kQNml zzfcA0P-Pu3Z(tJm4k<~xwVx&VjPKcj+ju15bqH@LdJ$`MZSCjhFd%pbsE0GMqN94}5ItM8#s_skuD=snKWFBJP@J}Qpg{b;G%hR)zpJ37t zsl)@b%E0p|o9*njPEVEw?|?|K3zJHBM_Yso@sE9~G&X_YXd2sO{@`AS#vpebPFrRj zhdj&VYF;Zo^FBgHj-|hSwURqy*;ecWsnmLKY0vH*d00aES9WZ>4Qp|3?KilPl4Vww zUd`!d9ggmtx4Nq-ZZTO-J~3u+6ypVV4>P&sW$Os(=EjVJ&ei_Tr>8~{PY!b8i`+B0 zRSXl=Cs8w1go}~SPLml4t6ipLe~Sa9Lv`A9{M|nq3f7?ot812evBj;D-(bf~Sk$B`xfz%a z6jJZEqjIEVCpA>TSo)LP%(0P5yTI52ya8-{>0Vp5H$7M+aUQZ7ql6swfcbj0w>N(; zcBE!vOiY@8%t`qUV0U9$S{VP9gXCJs0`QTm<<~8`%tFO|2S}@2Yg)`u46s%}6UttqC{E$*v{ztKbSm3M&Y z%3AP>z@YehHi#q>R3_F!u;BHG#2dBsasjy$#XL|#PXt3AOYJdtec6I%4iA;IaKd;+ zEuNx%{Xl)uAzmSleQTbk&Q@yoL7L@iA6{aT3EaS7`AOZG^119ULkAMkV-83!CrPJV zDK|7%I2dunBtQouqhi2`R_7>9!}`q5M`T1C=2kz@lPq1JYVu*Gq1ZVi_&dQFQ$v;f zw^sQi9AT_S+{wg!K_JHn1!1W>U-$M#B=)d>kA~88d-hFvmcs2mvc!-z{~@8vF_RD$5ldoFVs!xMnuN_lb-0fcYxeuQ93E^B{|{zNV*WdR`#uzqX^;n z#-~JPZTaiAQ%cBHjp1fc6JJXNJg}({=t7C8+56B=H<3a^LGHh#TW$D3tb==jEXFiIDUsu5_@_~nx{yQDTi;#LPw2u&`u-za_fnm_R zoTuA}UbCGR7S)hlQofl37T0~KuQ5w%5pgYT zJ5z_Y1ad<2m-9o1z8q`TMM{mCyWtI`Xc!KHNjthBOSw^>gzNJxe$u5;6DKHSsAE>< zuAbC!@Nh)S&sk`FtH8%2iJ2EOTi#Dtqp{uG>nC{=TznA-So-)cvY_jAK)sjJtO1w) z?W8UT&Vil@eC0=FOTbgrN3%&mK+U~_S|ME7u<|Zf3ESP}!k6gLa080jY+KY_EAu>7 zb!fQ50hbhIxgHNOJKa?H9{dh?cuOHimZ`|(nudRV>t>QIF+7N)@0PedfD;HNbqYvb?@ktXjLhTGf#QjI1Q z*&`b||H}4qcI3A3mlJp`!}3OB+Bw>MjnCb|aNiDE%9aJi8uGU~NXM;-+(cU4?UI;E(lm zY0QE0awM|6bwZJo0Orp`)?Jvv$9&&h^khppis3?z568#N(&u3k4;m5M8tqmaM)_jx zh>(gCT1q6L^w#D05`K(+-q&%6XtBu z7|%tVtapGC5sBJCw}U3L*by6mxI6#yZTzNT-)h;PUzz5t9bs4XOY4FbqxJ$Wrj(#{ zfJ6e1*>@+CLy3hrc^Z@C4Sl9#RPV|`mrB*A2!nO=N&c2gLR>FNgObIljUcfbDhjJg z&>ul@yHee3`sMZ}xf2g`wVL~agw=h$_5d>BcR)*8lgh&e?JA0s4i|8(r74#DbbsKu zfxIt&Ywd+zvk2(0;OVEi>o8=wwNsehZ0l!#0m6h!q?^H{oKBI^U0*(o$o9l^(gXT) zX~V(jOTl7K3-M{3GpKv@`{j3b@o5>248W3rcD&@o1JjQ`e_bg)Hmyo&Rr=FhbU*qP zD&j9gfbe1mx)e195b9fH=<7%vLiK^Nu$i*(^8$KZcN^w|rtm5EAEUnb+<4J&Z&;c{ zOQR_1eOMZ2;@+~vUEt8Y4R4yuZN+qmNYj{&DpgRvn14aK-!brsQDTU zvJAv8%5|aNT4HWtEP|##GObO$)HtDb5GIz?UNWm)BU4q5?w6H5_u*m@V z*qyr8lOi)<_);ng%O|*&VdNAir&jQ`wAt=VhC{{_9;OR^Ez;9YBw$q(YT~UU>N_fN zux9&YDTb{-10?r^+k5^&>~czaTQLL9VZ8&r0~$m!GgH0r^ev5?nW&hH_hyjk&*tje z+ZIyT&^-~oGR$exRX;WmxA&Kp(`YxBdx=AR&t^61csQ0tqoH#DUN#`o#`Vd-^wLq? zC#=Yn7ytRPXFF_lj9`|qqQ`rp-B^{C3vh7j?Y(3z?P3+&*SD=On){PaT$*;nioD?*KH3sT!k|wNqOe9SIRmascG|2e@t3!O{tV%@n)#JTG4v zceb;ksn%dU{qTLO-1!Us^6&1=MR`sWt=*8$M~PAHDqP`Ja;aMxC6)2o_L%3-?jAVE zi}Rk+Sr!c%K@j$T+`6oie*ejG{5_e!WOiu4n#DsNWD3uI9Qli?#-o_!RIWu@7mzL| zM{oF^R%T9fbuhsEH(J(--y4O%G2bX=0TzooF7X~OWF?)DmSfn%6M zH1UMiwg`3__{^&{+0V;sSoNzf2QQwp0gs7s8kUMn5|5P4wO>&Q&>t4ai&B}~mx{rk zw$YEGP_YA6xUEq6A~{9ke0s>r(}>TssLxB4h+FMzTJTka%^ON@lU#2z7?u!#hn1%k zA6sNPV74_fktH2Ad<^A}1vazm#F#gbN!Jh*=3SvHjVDMM#;Lkyd z>jTQSv27Q{cMthLrO3iOYy03X-eMRIy+w{kS>t7>-nYcW7rR1G;kSez&A!A&d#>J$w76WI>2r&HDSaYjmW@V!v1m`EVEAQeH4D^c5zukm@zmpzqW+5-vf?l0QgVNBmS=r-CrdVY$aRhJrF6b(h4M?(n#C>2hAs)+ z?yTWclplIexCTwDHC)<4PhUfP3eB3rf6T$Nt9`=vZ9g(goNwoC{aRK3g*i-6>Pkrc zWl4lSFG^%e&b$}Ydr^Csx{#8(PkLKpR4emU^Ksg5(1g5NiM5=O>BZz}98&eWi)z8e zh}Z4UB%`$U;3ammZ1jCf@y5d1`%DO?W5@InhWlLnp{Z|+tucKn>)m`CnwMFrCNS$F4G{R0#&8Q4kuoJh3(^q`L!K3B{)tG8deB z%W#6`aLyXzGRf^4N%5=8BUXDFV!owiuA1TMoIaa@}WSAuw{W(8+tQSE_H6Wa8PD z9ZXNuyhH79O+~ge$L=9SX9y^e12p&;t8Rm91Pg9ma%tqMpxZnc_cqm=8A0T@!iB|& znX2*`7-z*nM@8^?Pn9(EBY)2}MhV-m=f2jrTHg`et*pHRYTw*k2t1mln;LJ*;3^Xz zSbxa|jo=d=252S<a#1rpGpv-i$>pgFx^x?BT;| zv08*P7Q#((LPVGBlMwk>)gXkUfsA-#YXM6mFtk6`u!r3w;e;r3m?czLjE8 zuM5a}1F?OvNKm6Q)?l?}4!(7Jf{qD&=~ADRyI<3hW>2E|)cTu_-AQ$e)4?7a7(L1_ z*YvY)T>teQ&|9v_rM_8t8a^#ZXv9&K`=fShB%%e%3)%U#Kj^GlOfo8XY9O1IH^&YdfPX+u>k*F^NbQGD#0SZh~@MWQSh{4_2&zDuw0+w~| z7j^10D2wAroo~1IaV+F3jzj?(cHzvAYRu?7&flvy8%yPg8(5V}>%FPUB5Ync>e?4J z>>iGrKRcz_dk0Wv$`=o$$78XxpPxl-KnIvdoWU&>dXhym}uJ3d)nUG`g}e^qU2go5%C5&P`v0_yKiZnn!YG8`tu zFE2A%lnVhqUDpC5pJxD+YJ|>{e%V|~H{RQrZbW7VnP)DMvJjK<(wie;T1uCSpb84C++dE)i z%LQWGm6NjVwu(PD^UTSy2Q|~Xs0=2v?m-n}HUKk_+KK{Xb-!%AcNZi@P_AK^w$&ea zc`IlOWp$D&zlsi&korosD>|U!j$o#A^l3;cS#1wNX@F2kL;3RoP2A^DHA>zfSRr+x z;Wq)+)fHgM`a}X2a*u}B4%6cf(W9T&q=ai-bnA-8iQ{8Uu*t@f;z>?am}aJK%xURms;`!38i5_SPnnU{bi`J#toiPq1n`z zhb&?#O@+IncT?^E@j2E4q|5}lX(Yi!0izJMjGUcHlg5!3OMj(o-tIS>7>0g9c>fL8 zLE*7;T6ReMcGR}@fa55qjbRg{#|wYIoEt*jM%m^DmXDWP(m5fg2$xfdoQxOOGHD?* znH^iwJQ`j?1xjq_JF*(}yRkN<)mzydA{pz8ne(RYs|xxBsObaS_9A1oEa&iwc`xxR z7}=e81JU=??keS8Ou?NlbF68Ii==-vOh`nZ)|3;IuY(yT)?hzPHdJ@^ z!GD~u9uykD02vuB8}Us>Rvy|@m2`#AFZlXBitHAf3-~^#jNU$6Xf5PEyn44hMn7<} z3*3(SRu%1c;1_8PFq~Tz8VDA05DrW|mQX)`Y;RNZwBu(-Cv7hAH?E!s9_h=o;zjOD z+-t?$DLJJ76#uU3iWd2x3At1fmvi)eZvoK9Vw|udA4P5W)wQp*MLI;vDZyUgiwVzp zqp9l;1m%OY%3xOA1<-Oa+iC?BIV`KAhPq;Mr|~-{Vl`^HkvxNo-Y z{rVdhysnPbLC%64gHj-HHa=?;%cA;9yT-cz;ddIrrQBxbuzy>{`~+vY%ibWya3I_>}(goHBR4qiD+T7R=cA zvWn{~n>He#o)tb%5lMIolRo&;&9%vUx?{Q%vtuWYmD$^>74{BT5CW3`|03##j%0YO z5VA8Vlw&+kMw+#fE>vlcv#_M_;yxreI}{qi*Ap*~jmAR@e9P3Y94czD7;4yULymY& z=6E%WUSslW$YW)Vc+`xojF+YN--VgTp@64)q87lDGZ1xot%zWBO4Hn~q;8smzfiH6 zvjQ07?y;PizXRmU>kW{euhTNBGonz9A`Byj{>pcrW0+y!2gy!Qu-w!v7fj}^Zrwc? zHz5QYH1x_n%(=KH_hL`k&d2n|n+1szVAyZy2-uyz18i7MQrs~cm^}QqT>RAT zhudixD?}z3%vv?a`1Zg}F3z_3rA^;kE@^anAnp#-Zs(YuHK!H0lu~R8n3lp!tH>KU zq6TeA3cQdakK|8^OUq<1!~Gst7{?}yE1i$D+iM_&*Zm)t1FPkKyz2(;b-d7ZB9^GIcFwk-ugA?YtZRTced%kvOyk-_1pA4g4^LRE-q z^ZzyrA(U1fvZ0y+>ub4BP8Q03Urdx03^N)V51>;w$#xdMO!t^CMg=QcMZsynF63)P zgQMWqlcmv|QaH1;P?qhpIvhS>!V1Wy+yM2q?0u|=1TsX5BS3kdPE&C>z|5O#cXwxh z*R6i75>cM5qps^+YU?$e7eu>1H5TTODUJ@|(K&XGi?bNL%4!HgE5xT&oiTy+LoM2k zVIr-b-PQt_etlzMf*nf?%H@!lq^uP`=qaY8Wkz4g+X~mH%bUg%{y50uaO`s2HsNl6 zgj5yRC}qhN;g6=||8V3or{Jr+9w*?Yq9icLlLbpSppcAZpA%Q$JC21xo#e% zvo|muJTAL%qEpKgDgo19c@qQwTY-h!U8ydOm^I6ha~W3dkNd!#ORKCc*xSJRNrqL} z$C;!(+zzB9T*dI$NSMWLn`Z?n(bRtfShYNCW$PQSE*)D(5z>~dP2$e0n)jG&zojdt zd`B@}Byc}tzR>EGu9SYi!a5}+P&T5zwbP}kiA?kSxnyA7eZQx=c2;g9s}%7SjRb^Q zxw_~))vlPCO4ONY#3Wmlshn##Yoy1ZGL0VFam1XQ8e7`d9u&H)x z@f|Q9pD!%i_=q#^0M?(a&*-BplT2w?W=yRn zK3!x{y6s6ZDzllMxT*_nSs^2BjqIQu!GTY{#se+$rPwZI(E7pDUFJ_90jg_skWTm~ z2*@^6BNa4vcG>#_pLARG>zFt(AXnXkvd^b5R!IHd3(j<2H<{WB{aNMe=GSq}5#W6O z{vH2ZH`@_yqYZ;kZWTGgl@o_23xzXEXBf?&3#Iqiyh5P;HI5uBhez(7HoDk)YurUC zzoL3vja+t}bi4z;b#$|AzKr3`l9hIGJr-vcS5 zrncPiO0#aIcsZQ3l+?)f?U@hi4gO$Sp3Wm<^f_0DGjHP+Tut7@ z_QR>$ffgr-jaBZSUdfT&tDzjr z>%7yxkIVP%I?l)Jr=SG-s_BWAA4m2?WsQ^VS-$UpK<3nuG-E&T?lbSaYxIlUQi?kz z*7Yu*RYw`&S0DJcH_Phz0krt5Fy63z$tI%30fooq!0+Wrs=@q0S{eP$B|mjb&y2dc zu+xHQhu8-Qn6+Jz7GxH~iQUaUN(tM%f3m8OtRG(Flkr~~O5Ly0+yi9op|9*}r1#Z) z9pVjd*+%+Z`JK_xQY6L-J#_Tr?ca_D|%IW@A za2KCDt7PD+h)mBsdGJ>u`B4%eKc9pksEuis;?@1PiGLNWKi1MVxgLZJjPd$=S--l@ zL87>Z+F@(&6_nOt`Eh(f=4|!>6cwvuSG@QaT#n<$HeU$oO4pYq|#)> zeGX?%6OU9S?6$+k653hB**P2&o)49k{}hD()>9g9Wb2a78i9GqaP@0Y#CTdybj);) zw1DMo>hO2l&t>F*+y3cIZ@9q;rVhrL8~=iFsY3|^8$3}+4Pit79tC|dLv`TMa111i zzVpGrcvkpLDhW617s|Df-`1UvwgH5Tq|s4+2kO#)#|>yub>t5XxZ@>|VH|R!FqCzb zvZc+7V)qTiwdrIrhUwhDU=|WLJeYmSoJTz!=h-ZV6nqYnyEONZ{hO;$bZL*xC#p{; zo;r7lHcindzxw?1DaRNHf@CrDNf|f@1r)jizBW5Hh;S8$bT=4tRc%fs4q{ zDvs7kKXH}mk=mAC7S=UvyD?1}Ub^+pZpdZFtvqZcShjLJ`6QaUbT$p=SB z7O~llR&jS?xJc(|oGU6%?*gc;tyGv|Of(GXzC8prfEzxqH$u_)_Dz^*j42No1De`U zP4yxVsU^C>1YvPlUs?sQ3>N#gpy0lyzA1ui_AqfhQCac3OzXAAPVeEPDqO6%pouG8{^j zID;}Y6+2_EsB=7(u+%xW{6#o1syS;NEXA$tLz|wz)7Fm}sVw)i9!*Kt3)!R@) z6&R(tEq=A3*hD>ESAMmPd!ks(CIm@vOAm8qlFE1^o`5kisCDeCb7eQu?mgvN>aK0)^U%d?*Ch<4Ks|3@ zR_z%nB~wkMuvb499juD~Oyq~1UZd$@ha<;C=`+e-a@NCa1jXjE;LyGD^=a(vC@OY32DcsSq zc-&|GhXmMEdvnMH0&CJ8nWb}5ORg!lE9OgY0Deu?Q<#2tRq32wXh|v>5)df7_+)DE zihx8L0RC5h7>UmGJP3n0aUpNjoRC5T2~gpc($g*pD!Svn!sb z;|tz!kj#Du{HW;|y)2oZX!}6niuKn~7&E_Dh_eLC&S!i6P`V2zRHS5&`*)K_N-!so4+3KuMrEqz5AL3NGGTld)HL>?zFlm zdA;zD%ao(8Nw#;<9bCS3<98GODh$Hp3?MO^%fyo6QHJvB@ikXQiMHScKRc; z-bml7tVM`U-oYrP90tOMnQ$?Uj_=-cho5AAEfwVIl{094_wGaaoLLsf`4x_CLd+_aSGkx#2oVY z5T9*zIIB{mY-GCU!kTPsVxJ;!*AkBY9Es%JYd2I;wkF!>@aiY9+d)j{&B!J9F&ww7 zsR=x1h1X_P!Y}>Oadeu{2_g3iVyZ7ZY2p5!o968BWh{H9m9QJsWG6hML{W7^gw`bQ zqjY_qx1l}P%zFAZFbwJAOg2&NtP#`L&#am{7@OplW^W(Kz_O*e!k+!$7w)4NN6WXs z8tw9TN8}ygM(?TebJ{^^L79bhb7uwkO1aw$TW{l-h_$R$5xk*bm39F8&Oq-nJcNQC6bD+y{q zrqcV(v_x%bASwX;4&aDZ#n;Soha3^@a~w%qdmTqiB9R@7t9J>fhB#-xdsvYg0tN^# z(0o0>j60vS?dS)_9X|6U!XN6@*9Z=1?VSuaf7MRlH&S8X>=7)(B>k0OE zpU!i3F8W#T6&$ZSZ)f@!d}rX=yzsvQKPkZ0uf>liR?^Q>SYdW1;vw|{{pDusoTFB4 zNuJQzGTA&qVqCj{FY?({*Qf#YtvoafOCC{T#7k3FzKG!~D zi|>tJE}w7VM2$aFZ|y~ZB!<}}<*{Zv1V1i|_|2z#LYr0@r}u2B!i{z} z_S&LYi-iY>5HS{dsIc7I&SkaaiG+gzp6pM%mqn^;SCgmew!x^RWi3GmJ099aBP=2o zF&8t2OUPO3tmjEjF*&(W4 zD9v|DXD|aCvFfa%8|`%qOY}C?v4P{bOll#^H+p^6gL&f+T+}h1?w+XVD<>lI*E5)I zeM8g{F8LjWv=S)dJmb_58X{tp5OEs}79ho0p0%$Fz18Bd$$fR=b^H z%&}ApfuGcvU8nOZx##kdleK+P&9P_Tp)6MB4n0Bml-oZ?i1j^gI|Jf`neWKXQ%S&SfOoV=rx$r zl9Wi^s7#5FJwf<%KcvP_%DGMBm7Bl>fUzOND$9CSHjCY9?6W{V10Zm6@gB+yD2rIT zUFs2YYbsNOepr9ZrgILm1-VgeEx1Ilaq`)XGLUwBeEEgvO~@;`?yYaw*>^g5iVzlJ zS%q@W7Lk9#;sWJiJF(^gQ{qnd+EZ_#YzORK;SnkoK-&vTtvJjaeAq6Xw5qDQS{PhR z+(DQgSqO<#pXnMjHn$R)13dB^a*B3f{E=^_{?J0ppCYCf)?>VByyhx$X0zArtl}+Q z!QY5Q(9hmdXMWMuelPT!8-iYfYws8<_3g)A^O7^4dn6dd0EnmiDMb z2y#Q6l~?3|P`+d?2jr1$EP76lqZ}i>(yoE+RvUSVEOu5#ab@1o&a*xdmMa%GXtIMB zr0qa1ZMY`oG6Gvfsj-|Wq33LuL!hz|$VVQkBca;1uH8rzZlz%g+*tQhWJz8xrXz-b z3NOVs^rKTNg^?1{@ zT{l$yoV%OD=R#HmZbRE#ds0->tuHkpgmXDLiHPOURZXbS} zvbpz0obhL>hKoTjbi0)cpQkmBvr{&Z_MKj`!<73@H@aHvZc_(xJ4#E|s>R>Mmxwp?yK^a zF6(yNC>#;e%vq0ZKbwZ9HokudqW!ghLM~tX9@YVl=N>-oXVz86VvsCswYzn_2MB&Z zL?N=RXDh81?TZPwyD@kVQ5RJRbH=5iYEQaa#S2J??zj=^I@``3s@tzpv3_^$leZDX zNO$EyVYdA@RkXN|4%fj+bdgpnT4QacwkB#QnDoI>)N4BM*OF7k!OJb9$F8K6Kf{FD zEuk5h8vuK&S1c#i7wuF`X@nd+g@Myvhs90F-)GZakR+Jts}Iz9QG}doB@ss$r1cG) zj108DRbs*$?4=SeK4c~FsF8%_5yOpCP>^};D%S#8j9`n0O$xvV&T^|%X;zlWxUsqy zJCMbXF(sE#{vB|9-s<(auUgdgT?DN;Sol!^=69Daxc$ZAg}K}&*4F8}?zLSu?%T&JG@+cfU_0>qN@fmf=d{v=S*hs^ zq2-eQ0AJ=+t0i*V z6EcE4oFqMzI9kdtlCZtGZMPo?#+fCby`wD+UV97ws#ih zD^0-RiDkb!sn7yem8s~G62OOne6kI|R6nJpO|h{?!(4LM&v>$=T0;I0P5NkBxBX>y zw-$iwkjU}Le!S}}Cq8GXTU>)Ixsf6{Z5r7FtS4R*x3pTu3gYBwLQ&QN)o>b+#}h0^ z9_kO%JQ3vC>o#nK4+WOqo|C4@8%o3OJ)RYef(m(|yJ+mC^~!D1b-3!b&VXE)$o7$J zDp$5R+LO!F6AcIjy@Wz5I+Fr@%sJgdoUZ_3h1hO*28uNZ@?Aj)kU~Xom&e#lREh0Sx z70s(q))flVts+`7k^R@PQ`I#caI$;E;I!^FGC@al(Aq39R3 z)~6QCi5EX{5qBM4;$=1Jx-u`D7d*~Ui1w8?SF9VsT$RMwM9JALfWly}Wnbxus`6|! ztAJ`4WpXOTgd4!A619z3J)UL#zwH8NC|Iy&T?Qda=&2gU-DQtAw=`UNP5I6 z+^P(+(Kd%{W}a-IPouB*m3<0I_K7SzWnUmYy%N9lLR<_$fohuJ|!S}`4gDbVeCpDv|8t!paC-JU=pK1q+p&>6iO;H~1I6iUi z-B{`d!^{e^g_V4$tz7#j*bWm+<^eUwp6Wh=NBpy;VwY?!)o};SZz%bBBW`@t{5rwk zSl1m4F{!HJ#aBr+Eej571hzar?!4D`YVolzSVe@(4`T86Ybr-dK3RK9qiTzUu%H-w zc_uyd9~Q~4^cx!n+!>H7FL*wRR0#YPpi1jlwnfB6>;j;Jchq%y)CW`1(S2$AUr+Oa>LA(uhlFQ%Z@w=xRni6Xp6R7+RCws0t|5~ z6fqxWY=XxA{?UPq7Gyj}Wk{L?n?7EzeydhN!xxgozU=6ZHS{-@mD-zdZaZmqlo`Bf z!XyrO$cI;|or+hrytlYO1n?GPjx=+Yb^P4+#mbFM;7k^o4kM4&B>LRPEg&VIjkJDJG2`9{I=fZqnl$JH0pQbStx{#1a@TA0Q zKmdvJ45O%qrl@Yt7N$WqCjl(68o}G5JDwW7M#j$HnGG@!UR~l9=In|DjS3epPN6X5 znR}K;Se*t&buF*6Ru-=Fm^{QWBK5AKq+d10s*8(aM+RH3mMlHsK|_Yib!`zA)@bmt zl#jb`mvseEZ$Q*fNV~_EAcvPN!d<_aONqwOeWQk{C&FW%CCo{BsK#Jzh10?db|nF*;~})SR=G`uYYe@z7wSmi7OKEsyM1h9Tz{^<+fcY0%VCf*U%www{v~%jQ3YE` zD2z(FAEcV6bimQ*MKD}T9+9R5k(UaZb>Uw!WJX|1>Y}F#S0F&xf{oRRh2+P(%C%2~ z`NM%^HJhKNzY*n?YUnQfCoUNJX)v%z2&R|Up^k*nG-!D&uQ-CsaQ#*1yq-ryj-arz zRguU5W(wRsy5rqEHzw&9i)6%MJ-mCXH?qbrdv+xC*xHs%X_)2d{7UI^sCLueZ)k~2 zT)8sZTf69bS$|gcYIPA^-L2WLm%9)xg;}ZuM@!SLl?h-6Hy?N<*PRqN0|9Ykb8l=A zZos|SM_(qDVvRbp^yS(^FLB4~_0Xlsw>l&Bi@Mw3`zNPsZneLXwIm4IJKHKa*wo&C9Y1vj2S>8>~r z=;IQ8nJT>Y&qBHPzkwgmLezjZscLPR2a$l|mRstE9{Ja7RNJ=Tjb(;IJ=7YYzGzLr zBsdTN<&|kBhEo$f^)6PE97MYa=`@%ws{52*uIV3jw7#lb4R=qq8Wh=!$M<5xt_*8G8=5=U@<9cWfiBmkeB`c)@-7 zf!c+KEnt#Z4#MUA<$69Rq+*rTyJPx5Dn$dgm?N_~&0@@&PMrNkhO{p;5zDHsd4DLO zHxO3mHtku11hFiuZ$0V7D%FIJW6qSK&DLil1wB19j*6`-ry3z1n5l*&9-4Pu5Rv1+ zN2+Tm5=42&>ZD(dC3cpFe3o)7t`uP+u;sW%W)RP3} zg~h$Kvcaap$cLk4HyH%VH2HV!n=ybjW==%+RQ*7LUz-9e|hQ|`zGj2_Ucy(s7H8lu%p*0k%MWS-V9FZgv@%n#ZB0BHvEQeTW-GSKBL zhqUVI+DEjSRh{83ZaDE0$Z;wYH0d^I3j#z=UAcOKt|u1QleJt=TJp#A)0$z(L^*I@ zVNy~+b+bH6STm9frG4W=`AH>Pt`DE?@#)H)%A-hMFqO<%<&RL&REKc9E!l^kpI7$K zpEZJLcP|n!F+2sPJjzc|rEPai<)q9fw<<(sq|G~);APyCIAUT$TPsGHZ07hysg9XQ zW=RiCWT;^}uR3)g+)Y`ISdVQJNa`z7hT5$7aM{yPDe!|CgZNV=KpnlLBG~0qfdLx^ zovg8nK=_-leZ+aKJ-E~7MTlAK;o{nD-ZU~)~>&nTMq{1%V6W*T@MNwCAJ1pp4jfL z<>)@PFe&rtENYZiXH_Gjd<>#?)x(1r*0}@ZdCuBjT$1c#l-6H_H*Y*7NWK|XKD|on z=a*O7>ehD9Amq&ZuoRc1E6H`&wc}p3_K!-G!sUh2(nCmz0Mzu9YAGx9u)*qC@<=OG zKu(sMp|Q2KAzNXjeC)fZ?kV-UHKMfuLSw_v%vpL)u5}isUdP=r*B7^UYlbwkVD=R% z)v=q6J^9U_H2FNuqCKZe{U;tunWx<3t_Er?!}Zja8hSl@RMd!v!{aC)m+IzG;ARnUu#F5b35zHE<1NC;$QH@Rv1ZE@3G012ONl3egwALBMJy{JpM6D|INIpv< zco3dN*++2&CtV@8mf)TcKv@wD5}Md8a*#e9C6!Wa^u+zIRNh&x+y*!k10wX(x%$tL zzhi9T+#KFHZsm{Cb-S*ST*2*rp6eU=Z01XA42ZiccaN{xGRsAU&B!Vsmj$=iU4QvC zd+}|($*A~@kE)9ItA%i!_|?kCML<09@}l8dv{lfzeI;RB1h-c=uc7EDnrBndowUVs z?@+!OWWegKXMghP=DS-^_Iz$(j1CDgSPFd=R-lVo7Ih4Foqgr`#Y%}>l>Auc99U~YNu%! zEwybgRpu=r0e2#6%N#1|$+|wXs#&#`1cqF~n0o|w(nF-zsD`Ovq@2Je49Gx-10Cl~ zQ#5v;V;AR`f#O}m{?e0#$uFJZ?hQ7to@YOnoQvG&_;mSMk67Hf%sJMTxL=VHhhYBh zs-C(7_JyQ*bAp5NxKPrskl^H;z`Qz_PNqM2Nl@l-5CmI@yK6HHB(mLUo@7iKoASy% zbaiQTwwT8TM2wDNSy02(i-+YflL0)BX-zk%&|GfN(3woM$!3}cW+N1rrG6^*fp;FO-t>LoQLVAFX6m$Sw{MvF26O4 zjr3g^g?QwV$Qp+%hqk*Nd4EY{+R|=Sbk2JXt{$Qx>Z|e9ojr}Swz|A*UMx&`Ic}ow zyiOKo(3z`TS|Bk3aq{vW%GcuW{GJc$mWs0rRRqCH2*{aE@pru;7MZ8b>xu`6k8udq z`8xIrWU^Jsr25uIG}+d}jfY3JHQZX=!~qE&A|ze)gURuuv#sx3t7fr_lN_t>iU!saoSqw$!XmC^%|MaPFk(F%M|$ z%S=F8*fhkOIOIFgwY(BNn(V+TO-OODj#^VHHY;ccVNfWKF zOVtYbhZff@;6E=h!lo-*t;Mw7SjD}^13W`@C@~~^Cn&o+k$+cDWiZa#KA(4_>JGaX z$(#1Dy)>F^_WM*FKI!W%rbKx92s5duUhx*~;>ESMGmkA}J*Lli%5mv3-$?FguPVlH;ndLfEZk!P&XV2*NJ;K5GTkVSGv`0{&1luM?K@FL*$73j1IKSL zYb}7`dT%(DNO4{}N|_=-0?O{n-q0@>3+A-gC6-_zM}8d~)OhmZLu~qnv+|Z{Z>t^C zJUbvJ0QqH1zgHW@qLeUr3`7^xMc2b*7uI8_-g01eD1eETBQg7lwOzd0uYoW}5)m4! zNGX{Og|{wwQVr^+Z>6Vov8RRLTp7VM8IP*7PQ994MQ3qqIK)i#RVp-#ZW4ugW3V>* zYLQT0q#Tw5J{b2?x7!-Sw9gEZe6B*}i!IC!-^;Dpv4fqTaIJ6J1@kTWF%9LgePLTT z=kV4|bhekGS=u7uz@YQr48lcVBtuQ)RS#?I3@z=Oh)nv_9$~jC?V#G;wn<;9P(`~LN!^b%eQv`ol z6$McO_gB?sGPPXpXGxDpP=MR-Xmx8yvT9Y6Tv(9dmla96%BD0GcLhD znOStOe@DHvEB7eSureICbQj&#q%T%-v@4V4?PJ8rd46Dgy3x;GkMu|oe5~2!cDzB1 zV13^*tDZ?ikeTzy{Odl|M$M+EBIS=tp=%=P?-QnVMLGV^MBR8+Z85;IE{bP03YXXC zd=Y185=S2GjUC}kZ&F@~jh6x9Z2|49Kh{iI#R5v3wT$P@_sjItD&wkb{#bcV1U=MU zD4VIWblGLvm7d>tG!-PfWx1TownT7l;Tou%KMj~YVIE-_Wla7m0csaWuvFWWd1JTf zto+Yr6>oA9rSL8}R)dWa-e(irJ21;_1x0+jn02!PH*LhKXSP+#R!AKxZlB9BhByl% z?h5N~rdX$CqOi3WYP=>EMdB^T)D=H}r&lhaL&5fD)rUy?;poPJ&wj93{*`eNY?z5w zc##)=bm&*(_o!Lj-z9-{zyVu@KCj+Y^L?k5N9uKLB~zSLUQTQ^#|Ek+M9R^jX_Sz*fcS5`WD9utJ9 z%$fBCP0&n#v^RP~WFMW!i~w@@k4RMffp6N{ez3J$p!sISxO26z(`MT2 zOnK7-iDW(Np}j(+tuZ!MwikEYu2h!MFRqrTXV76+%xaMCYT7);CA%>?O*+N(y%$jn zgGIR*S}@G962Juh@}#K8L0MUay@jekz1ZQ-c6ps@HRfINZ(9M4&A-b|+&{dm^{BcT zYVD0)5I}6ihp~T$RT;!L*P2-A>*ZeCF^|oBp)KP0o6A6+&n(aGZz8OKo7Q>@F{MO-u$2rO|RCVq-uqyp1X zm+`gb#9%#CI?<|I%*vv8aFM6ajB5bbopd)0A!=ne`1XNS1t2H%vL6Uc#%?W0mzCQ^r06fr=TJ^8UZXt(>XXHgN-{T1Gy6 zpz5WVJl-PEc)l^+kLsptp9=Bs+M_}^1Ir@BYV@#gP+$s~#3YQCdt$Fs&n{o~WSkn6 z#j}$jXVw1FpVv)r@$Ht5Q)sJ%MsS?@iOQ!vDDUiYJRXX%Wcify2P)6q(pycbeX$K0^Kl70@_}Xtsk*jPKoT=>>Pe3VA#S8 zewvrHNa$sat%F*rjy&Ia=StK$A)1s8)!bVyPfq5aJWI6m`HQAS!jNAoNq!bum-7$a z0c;?m{D)m#BcJT!#_r>icIf7bG`F$emrFiaAF$DOa`U<;6i2*Ru(lD^T6MYGsSnhy z4SDbo#DvFYf0sid7lQLhw|eIP04@O2TNNF__lu$o4_eZ6@VlFvRIqIbxzMpH1;G1l zaV}X}-l|95VlFK6!|v%;E;T!=g*A&rHBB&3ZUWDk6r;4N7nXL$#JB(rfMlHd2nYK?G#;XOhFQ!>X4lVtads+j8ysK3QVo^wDS^a0GES4jt8c8BUXX zWvJ>mXKFF-3zkgvQz;v@A_nr(YL@{XC5-^Uy)4|H6KQaQ<;y>!v+%;Im4b}7xKpC; z#h|w1$}ESmlp1)@Ef)Sr01O%TV^Y8(WtvYo!bGtlq*StX&o@+#9SR)3j*s%VW7igO zYEMjL&{^aBlxW8tSn0=di-tou;5iVFt)GcZr%ak&oqG&0O}b1EX=U5_l%LvNFRof0 z-idORjA!Ao{yZpkT)9(6)-LT8XQZnFb40|FV}Ypu027%`#n)Tu*}BBuO2vRa^BS!~ z5ceEPyzek0KhH z=dgrUsa~t%XUNPk5}H0fwrS#AR};s7O)syhsux*`S1~iRw{RNKJ`^gd(A6gQlr@G} zuj!=p&~SKhnV8>7jMky1vE#$b8reQH2^@u7UojFzmP1)5($$M5%gW&Vq!e3A)D-$y zZqy%TeQOG~Ll(jxcxF@*rZJs2MNWxw_FK&Od(Fl4oi_BXX(mflgk#2fsX$KD*7D4R zuC2kVn8oS$y4{u8BpaDJ*mius z{q$#9j*EM!Jmp|h?-jduNPZ<8sCLsP6{iB=rer`0vMI{8wkWyOe0;7!%e&>5?rGAl z$5>gX9}tC<@XH_7ONnQ?wXLFGY{nA#rd+k~EDzn&TTYmpZZB+Zn5&`pf*?Z7dV}uk z2VYB~rSG&i(%_Ce2X-ahPtQ!6UV*8*Rcn!Tz{p1>jy*JglWXf@9mYaKF)T~<(EL^> zOd}p%6MC1fV7C~T=&qOXW7@RyZ6(7pGOfe5hlHuw=zN#!qYwuw{u`e}3)-8D~Ri;N34 zkEW}yt2pX6a5{Oidiq3ux@YjAe$j_{qyzp@@uYOn(lC6eJ~2CKaSAV$qR8D1h9$DKavN|633bJQ#7>Sr`*lWr@r$t9;zhB z%eABs*^;hYUL0^I52z}G5>A%=M)*%oY%0poL1IhU&7;PSmGQRrvB_gYn9<~j<=^;|J;OIv5X{I|_7Bf{!qqNN8(Q=*);fOmN71sAC#i)NLpB zdqsU>8E&nl&osg@(qVoClZMfUJ527i* z!;9X}HszXVh2IG26JN%s;n&BTGu1m`K?y_<6}?T4KO8=u@<- zrNmBTv)w^he_8LdfLdOOHy1I&OLj$0{x@RQqPA*YJ=Ze=*O?N_v?)|OSvK~pM92(C zKXza9DHRCx+i*?f+JSkra`P^l(6F6S*e-boF`OabR4e{2xgcCTqiEtZpX;7|b3e3} zDC92ZEKMvi5*pq7Ur*1nmf+jNeDUP~WJDvgu7+~X8-1n#PzB24DGzr_>yvThye4?_ z56|hV#5=y{`rSROXu5a@B(}#__C+bA_+?L3XN;%TZK!`=U1^IdYJW0+O)3ccqV$L8 zqN}ZuUlmfX(k^>N{Y*byH?M$t$NH-O07z2!_>hZ;{+J)8ihV>Psv<5fI7D^SpA<&a z{%b!?3=NM#i16k5LWZ?CU3}4@jH~l^(9hf*ZYDvdf7N07&X&3GqMz%RAHi4AM?t^( zgFi)2<16$qVmt!;qo6B0pi0}~6u=qKXQ)~~`q)2pT4Kgo@=AuU_z+(aq|dH-^@ICM5&JpbQS(B#e;Rb5 i?2(*ly0k$|Y*)g5x_oC0I`{Pn{yJAg)Kb3X%XA7ytm) z-PYTl0$v0Fa5HmsRh1T_(ALqVK-vYM0p6tlz{JeWSyV+u;lJGfM(>yYt2@v9&(;Ox*XIw#WbNivLd=g1Lp8*&E;Yh9AwGUESZxUvEg`VU5xduuJVs}u=n_P?LYYEEt-X+hT2<+{)Qv~ZGa9y3}6IM0ayTB0f7ID zF5-W5#R1}gH>>|*f8*ca|BcDbl7sy}O)zL8006?q>+1~=06Ap|*yic$R2g@gM?0Tgd|`-b2*eDfDT;cVh+@>c#A-aP*Q<6&W8|3~{j<$pP} z@P7u6MzjE9H08FUf>&spj0D!Ie)*}Z1kQn$jF3PVj*#iI=Qgr~JHulZE zs5cCI!_3#Ux3PwW`3L{#TZpi*@NoYq0z5n%JR$-j;(rhc1sM?u1ql%m`5iI}>OXj^ zp}j*z`^UWY0kDu^I$)^aRIvckSO76B!0Qlz^zD9zg?lslKfVLt5#SJEV37dGC~sm- zOaKfl0t^BI0wOFD;#*(uVBp{Zun34)lt|b(Y@)bS)EppWJaH2j8g{jy!~%RXT23)l zxB7k*0xpT<%aGaaE7PJzb&bJ!dPz-l3)duYA>`(D6@Uh(3Xp!g)d0ePJ>#u|&z<|+ ziAJ@hDl7Y}!pcEAjCmL#S7!U$gQ@z;+!XzK^Iq2x)<#F4^i;6BAwZ z@Iz7C$D3{xNBPxKqc$SB7$>i4s&)+$p9Hh^eN6*&3ExKDu~FXon3sk8r34cX;T*^} z{DJ*K5=k>U+1LnoS5h+=5ebe`UjI3rR2zYsdd5eoS#7XBgbHR*#8gE;Fw(@K!Jl#vOdk@M^swCYqtfDweBx zVi(a#m9|xm83rBjNzmlFMjDN#=NcGSgl(n#WCE%#v@(|cI0u%U5-aSevc;d`cedsWv^li%-Byx*d zmMtX+fI-N{`Xd$lgjIfsRB7PD)isqq7F@7X{o4lTQUT@1v+xurzgrCYkkfGspR|W` zTl#l`D!S6{Z*Y@J$Vp{5Y3`49@aAMvFiFQHn(IUXJ%uc4_Wl<2a|D_3O7P161{wb4 zLQ-pIqUCtB`Lp=ME8xb=-rPyyD?^~Q8`@zn!>^1^)0=)T1*;()tc4*lwFH+XimxCl z#`}>uEC-3Ab&XXuNRo!le5$JN;~?Bbps#3CMT-UXK7Pc5q{Ui0*&0}qyqUr0`$%__ z@m^o4s!16Ck!3M_C9tss5_yGc>r>YRb%P4RuH4yjoV40jKr@MV2SG}SBy)-go@Z>R zOFdbOj)o)mKRx%OZGXpb6JoA}hRRP!H3|~WjQkv`I!zxv?S6L`f$bhxk>(bzNWev-_whUJka-#s7?T$11HGV< znQsBSwXcNKmRz&^rQTG{BZ*{FWE?Nl#D@ay0AJ-3qKs-q>Y~PV+`6*>=PLk@VZFqw zI1`kZu4_k>15forsc+5XR6j41MgBzf&Up~_6K>{v0?UO5bnB_*R1NO}+yfzO^GM<^ zHdA!0-Inmm5Q<`L(`Cy;>uE9<~4SJX-LzP=QA8K;{2*LndT4w><=ZC``q=T)PfwNyxU6r?pgnjHUKt_!_8 za$3}N3>WuNB}WNE^rFOqBR*qM=geq~jqE1&X`Gp(DNys_V1k}%s5)|5N6Pi09ykWH|H^gP>1;D;H}ES2^JCtDSp3q9wY&I}fICh8QF z;A3SeE9!jSAnUEen+VTIGgNX^!O*6AR% z{Z1?Ff4HbXyy;d%hcd{s^~(=IOw0zG)iatZS+esU-!Q6_(8>?#OSJ>vyP#rKuD3ih z4;Nx8xvJj?Clh5R0>&c+RQLJ!B$}8!%M~-|8|5=_3Hc7wBbkIers{J+#2)wI&#wT7 z6!UTSP4Dfm{ZWGJZb=f-AxCC@gTEVk?%G7*A&NX?K1NVE4(@v&*C@uo?5JLE?kJr~ z5d5zb&Y`Q{QBN|LWn>c4Ihf!IC`^y#lg<#n{RmNWUr`O8AOc&fa-QBq@HyQ`{uSluAMM z{PL?8BAd~zK*;RVi67pqX4iHTbI*xGX3K_&1a@M{7b}%vHmL3G2%-9h={*@>T<#@N zs6SGho*e1tU2iaqA3vZeSuGqEdIaFT;W}t2oo~Y7y#DlW ze~X8wE}y|)%dt|b$jihXWQyKn;=fhCeN9rqAe81oBj-(kz63aSQ~HS2<&!d^tW1d3Ys;bNJJKItkfC<-DAIF!0Vj$pq{Wi-n@@fuiKax_%Xc($0N2CCV z5G&zC`H`(4-TW1Bh<5T`nxVq}tKG+z5ZSW&RfN739R}#-EJ_~7VHI{Uy7_l@Igc7}PAx6>be zuAw1iBU`S%izW0z!%H|vLAS>{ zTd!q!TwApJs4<20sj!mUF7G`#xH>w4WQz(GEpn-z!n|TGKp&7v&9nV?21}uEblchJ|;A=I294y+i&C3cKR4TnSQk zpPBKr*||SEkY9yFP==$chfqP0h5~j@t5<$6=Pv-r<>mf~p zoPAb#49sdjiVunB&()o5MKe?HRm8g3zimfy$vGE4Z_o1uY6&*weDy9iY&AQ}T7c9i z>PmkClHS`LLfObWyH9wt0}tUjO(;r|b3rGAhp61D+y1*}jPmWFuYftk_a)j#95s}R zR6B}9L8&%HOYeW`m-9OR+2xY64cb0MBb{BO{v3{yc_dA9f!sWI)C#Nlm~vvnq5=xg zeGuB4(|IoGRXV=5HG7|thc-=?Li#22!eB^Wrf7rT)IK;RSGe!^c;^rCI?#% zTKOBQM*%NXw_A{}SWW5h?dNUHpYsWA|IWkZ_SC0UF3f1*TKw+ed2dZsV3oiVxPOch zJ2YOk!9Of*%L#lOZ&jC~aL(_4B9jF=nO@J^#qwcyd{|7x(PB&%J|ki$&@DI!{u;kb%9C0I349>{x&F>0Ql3vu9)#QJW)gxu+6&3XwYC z2+fqIyv@Nx%c4d<#Yf{)rt_*=(n5(@KL=;q#?yo!{lW;7RJ);^yN=D^#qlW?y6;eX z*1}MCe5+ycWk&ZRCvS{-e?Am2MN#|f1@yjAyDfvRNInb&hmst@42wTWw$A)6(DmPE z>rUs+rFd$pQr2wPy|8WP>IKa~5&N9b@`$o+iTPo&SEqVb%-zB~QF%m{t5lr^=OH{J z&=y>XOmP>aR=A|2BblRcMXwOggGgC3#hW!}gY+Jeaw2Yaos4t6+gNEPK-e4aS!IHi zgIrK}1+V5_OA80}r0L!!XEdqk#aFUTxNn03=O*m$<5pygT3m>XeNt0LCnR+%AYQ%X z=3AARTBcbUId7UXnQDK_F!#46-S4&fceHq*X!=lWq>w+6w@2{%L-|tSrhJoshw!hP zIymkoaa{zItT9;N@{GFSl9V~fR;vwbRSJrkbvsvR&PX~gjopU|9T1IAc$iIR>k;u2 zbEI!OMzP%IuCBY}H95>cIOe{CzA>mAdm0tQJC+W=vn8<=mAPRNU08`TqBw_459Pi$ zSJk^_%xg#({Pvd=P;lNVJ@6^nn3f@jn`3IZ!!dmr^tzSRzuasWSH_7LWTO?bNTxF7 z3>i5qS(1fUA+1#|0~M#T~o z7iBjttX$8=a&Rj9ic)^F>MVG2g_iI;Lcs-kx0R-m7P{acHLA+0u?Cy7iK!x9h%T6E zC&>@7zz#C)=dYN zJs(#=`#eiAqx$OKF2}{GIxgvChGwT&iXxS??5VU=2RTTnJ}119t{hz!5yoimsean8 zROsHHDA+c$%x%*=nVe!_%hDjnJ4zqpjoPrb=kgVg>nJm*1xI2XnuL{T86lt4Cntz@m;TC z^;(Wp5r$lTWmU+P{+sfQG#m{P^6HpNQV0DCPtoe z>MZbqKjh9dl(!U9UZv({wrBa19Ke+U^%JA=o!KDhE6v?5(9N9+karMCabMgI92Sdd zB^MStQZ!AA7Q0jr=u)#K%Dm&VSXT7c3KgZxY%K1!Q!J6iQd~diT7^pY(0-1h6LabI z)2@wZlCeAW635##7Ek#XleQuQUIl6mNsD+_>2PF)$Q3&}Jg(5iKK#m3&v!>kfmF9c zMqtvDhK4XIccw@2k};ojC*R90&Q}n_v}1{fuNwN=pv^8zbPvU!k@5=^84feULUvh! z3C$J@+qKsBFIQ)?%4N>K1vKrte)m2M1ml%Y0!8GICXhq^8fAOnRpZE3A{ulbc0Tc4 zjb6@$?NoNxAbv^A{0@$lL)w4mSzEs*bZtd_3{0k@HyT1w+)3vm8oIWoJ%(eGGncA2 zXg!J8OIoK|7+1DAzP6XIw`!-C$Os%*}nv6sl`v*oQHV0Xs+`(cIYbz z5Yd1+TKBdKT^ORu%n6mGW$G7y=@MWy+}fU0uh4$V86HsSD(4(A;T@v~Yn5Bn?0LXLRyman`K>nBuEyP@u#UA06}b;a;KP0EF+WNTPt@m3|xV-YmM6Ynxx) zp$MJ(U4ZvTBs||ID*j7-R5dpGRVp+2XgQZ?E9nE4f^Em?$mZ3Ff`s|Tyw`o?Q7d^* zo^ypq0ZqoG*+4!Wf4ZX12Q|@e5bY8T7Zp&VTQJT~g~}@-XHz!|D)Z2@z4Cxv)H7nbMCT3Q;zmyb!+aVxtbZwy2w*C4 ztM-G}SKcNyHRFS~7l{%LD9b_v=o~ThM~pvNr=Lh<_u`8S0$U1u$wIlJd}l6I9>cvQ zsRBNdD2_fiLZxpQBNq<~o<(Tex??yG4x!(M1l~EQGY>2+YuwG4CFh`ghT9T(Pla>S zJEY0|kZ{Bm7)Ol6_q;XkTkNrhw~U)ocr~J_k_rlf^U)g$IDjNqJW{rbLJZAKJ#5x!YcD!@+MHrH;bA301X$e zUe%pSjcwjpBcMPQA(${rL2C1u#>pz%vQnv*ZRPiuKlZi#m%p)&6}l9Br8B5&SwMol z66Nb(9V@S36krj3`Vm%LW6{Ks;?3a{#M6LnqC4uc?3H;3$n#N*h}Ptru&?Zj zc1!H-X!#gb`d@0A`5hPItDk&GCuW@fA$i$6_1$OkX-sQ7>A@ik7QGlTFd8Dl?uRlS ztcp4wq?E&wh#ssJp9Exi$#}G}VuuZ#%Yu?iwX36hiN26Vi75_ZI^PJR(o&QAZ{5Zn zU~OQWQjm^pFb;>cm<@utGb1-2{VvHNwZRXwzB1{tf&Nz(eyFk=mp<+ zZS`}|Sr8qPB^K}!hP!`0AGebA{yjFNL3a2Fd5DXVjs_X$rv!JNRhM69Rk7RB8;Kl zC|%Kfsw^8=K8r@Qg@E9os$9s*LgDsyQ`}iz?z<#~1>7r+@1VJvoF&od?5_a3`K{6J zX_{p7-F=wZyR7chB|>el+i5(p6j0H<`(gP}wfIgyj%qkhak}diakI#{txC>Kb9|PMrtja`g;m!*XVUqoS3>UFQ9M zb(DC&dGe`uO(W;&L!aCHOf`F6yw^)nuW@eX+>TV zK}MXzF0u2q+;q!xA5_3h=(nGKq+M2XHTw+Q*&I4%%5^JNKzHwAHFT0=W&cWStlx&= zp5+Ugxv*BuV5&;mPNd2j@{?Pr_%npg^`#jmG6+hzM~PQRf@1E&=Z--7JwK?ChrY$*lvDdZtVL&)4FXrZ7AkLDo> zL|tW0LNa8yM{-G>XMme&L6<+7qMKjH7#y9U^1Gh15gP^Tm*Ti~+`)WJDY2;BplFB( z(Py~8S_P?oMqW$*9C*x0R>b<*VvR61Sz>5YF18M@zyy$mp62EdAn3+@508GP>oCe* zp>V|GojyB(1xy}~V;7_nS=c>KuT+$+G~czpXn#S&Bx@R}9^&VZQ!uEMTgSCi_ON94 z>w7_tv;a)!CZyN%(F+C``(pD1@DVa$I2_dCI%2Do$6AmNM8%^An{r^I<`bC`Z2pz0 zX=5LkXu(tbvQ#En*~>`N;hnu>140t>b&EnUcO82+G0?MK=4uu-AnJ}UtOWlq^AwIF z!_AQWo<&w?DaCHmGxeTb^XG86+9b!O&HgT}5H4C7HG7WB5<(SL7prNrZt1w|;$CM4 z?x9j@$0ls9?%-w7!hpp@X%&Vx-w4L>I~Jb`PAugr5OZxEpJRh^f-E^x3?dpy2zNI% zCTWDLK^BL9vO~H3A1>>ZZ`kR*@1Sw?sTzppd7ufA%Y!)0E~Dl3d3*VQWZYR<0#wMk z5f{T%swe};gp&I=(QBg=!Ya8qx#Y%N=-=iH0rNXKp6wuBME_Wc-SgvPxD_5!V3tU+ zE>|=L%*}pCbe!y*d1&A_rQgY%eS7Z#ag@zANgpfNRqa=Sal>)u1NBkoUzhaDfKb=q+S(D~d>q3B2(XHqb#cIRSa~v)LX$h<{ zX-HK1cE{wjQ!4|?;9WkNj~u%nF8}s|iATY)R`($^ed4@?!o0c`S^UV6ppHOcnE_Q; za0p4!+KumsB$;<504~NG{Jo{CGB?Vkkj%ykLq1e)C1Rq!nQ@>Z7+cXjjN7fQ!ub0n;EdYURAj3!c zm?}w?a>b83qNl`l38ZKaw#&zO5l>R?d>Oon=u~*PU5i2`++|(7n9}XCOJu7A0@W<$ zOp8SPj&$JPIS`-v0^&iyOX7uVVwIDd!pl?Fp^I#R^V&krbCOgF&6oNGwO&!PSmaE9@=u9J@WMdJJl@YcJ?c*Z!!aDpxltF_^@ z*x(k&-ZU%Ds`%q-#O+~6c|~F6t}EYvwI(}h`>Eq(*%UKO3fzNWX(fS<&2b(ABRko` zkky>*bh3H_1SMB#ZNPs)SKeP)5=5~{FxiO5C&c*GHmcU|Qt=ShoR5!l3DPci=hfA) z6DRudLdM-+60N!nHX{WRi^;OHTK01Z4B^w9W0T{I{gWq#xuc;st}D-3S_RJYj8wV_ z{u^drj;Nf?EC~g6uA1H*GYN$`vKI1+&M6vrTHwGzqaexN6G~EvhnF!91f=duA5`_{ zLQ-?FyL7(b+Jgi4;$6@zvzi|zQ$$qDu9tmJ3eSF;a@+^NN{>fcO4%F?l>*R4^X2(3 zoTs!rqMuGE$}50b9$+%;vJor4B$`yiM1ih|xsP}okfJZ0N?~?uC_)LX8vIFTs_;ee z^-WDV{oMk;Z{bH|Xuh7}#n9U_194ljJ~m^XVXW|8wnk)BVF{wEc+Y3UQlUz7q&HQ5 zRV`bla?gS2Zgcl9<9VoB?a-9|29+sf_%q%eSDBgxD^C&duT@8;XqLJdwdfr-4e0?1 z1#G{e7%pC>X#H{d)K)?vPZfwWfip*eca!b^OxaEE&_cV?z~SCv)U-I>GtEU1>YdoM zz__R7_92bj_hXZsKyzY}^eM@lU&-D|k=45*kwn@Q&w72v9hySh5yqr(G`hkP zL=^IDHD=w#snw>gr45}y1oFuNjkkSy1ns&~&b|Yk$mm6r3J1EO^h46n&!YQ{{TjXR zIg>NR+1D4?qIVlysvJ7tJK_`jm||#>ADZ@hc9<#=;-o00NfpmHreNfnqIBpG+$xsnZob^B$JPP{ zcWxFez+bpJDr3v<+`@1s<QB5g?Oy>^%&E=X_pBy3Ou;p_8|AY)LUTd6>Zw77fnScMFl18Y z#so%rQ;%x!&n!~Y7q!YN;{DjoWT=uqJv2QI6@k)em*#)@KDTUUs2d-5E_Bhr%6N+* zmlX>%I?2a+gk19YxJRuQJN@dJG2COuR@IU}26z34L`lh(%{CVMUYKHwlXE3+5mK8$ z>?!(u^C%8$F}h9;ac6`StYCL{u5~9Uoht6QeFNL|r*D~o(Or^p^@4p`66Gs5kJZf; zizEaP^Kjx2#-n7?Fj)@Tr?uBCQX4A4UGMq_14!M! zV`9{tnb3myB_lFfQnqvl8!*+*R_Dxy_gCJw`8ic}b5W~7%|RuRgaK2YPYwk{h(A;y zCasV@Prt;(iTA1Gvy?@XWec^X`)VHY?@eQ&x{rUusG`)9IH2@kC=wgGqhLNTY@uH- zJey}hYqXqci8GPPoJyxBm_SpBe~`KMo=6-5Z2D`{d3$nQ)TdksV)BWavyj<1tU}|Y zW>aYu-sB2QN<$cyw4kQnS0#{r|AI>@C`;?lNB6dnXw-B2)1H@q3cEot*ZOOkm|7Mp zNq!2qErHGH#)bg*{e&X3ns@i};a!}k?r?*deC9_n;6#afz`h<47d0p}j^MyAQV4#EG|73J1Y*Or7DtN_ zLg;_}UE>g_1NfBg>k(y7-)jrBRfYvKsHQ6Vev6(rVn;TiVss)bg_ni=WB|rGe;y^* z{*}erW6PQ857q**CP{LFGNXLzI=VI`>38J2WcImzBs_w+-6v4HVY|gG&*t!vFcm@5 z;X-IkWs9^~a4~aeCR_0j5QB2BW~n;-hU3rt>LoVovLMg!2Ha-~9GVbRh5Wx86y3+d zoqr`wqf}NiN}cgrvEh$n3_$^ z?qAQJg{`?eGhpLfgXfBeQJ7uD0D$m&d;B++p8Ry{N5B@*{)- z!l>$a;e@fo72%HeQJ!tpOCuoZ8-Ye1J|sqbr>_y^@N@og4w`Hd|3K$+^SX5vcLvjP zJhK<-YVHb$rL+i4fYbm`{vPIW_8 z&hUA)T-cX|Me}}`!A-4n&38Fn4Y5%8PZ7Xz@fOeObHW-8+=9>~jUQka*xsGK#|&9G z{h<&w0)9NDG&{MS>t@vy?x|Ec$s}bcihrReN(7wemjsiA4<2I9agPO+Rl!Ltnd4@c zTfl^kELivwHU`D+oA>}n9lXhsMcc^D#$smn)Qf&A%8`&N2aRlbiVglmgpRL$A0~u) zY&BMC+4a7RGTeJ4u1or)Ugt~kPiAx*bCgeLFv_UgwgA&;=QV-6C5&KvA<(wCnF?S_ zo-Ec7ceQ7!jMHyvt@7SQ`AS0sIWy@RSH-9amw~12rB8NY~{IH>Pw{4kbzU!u_ob5m}Eau)fRY&2*!+f#H=;0@9 z3m#>0)an#5J#afL;M^oYMN4(J916k~a$%7c$LpLs^$IiOtj@sE$;YUxiOk#Yx1nLD zW%rnup+=e+l=DEXn75MM^b;xfyDd_cm8NK%GKIxkqr3PeS)gkzL0Y6Vyev=Vot6PF0!wms>K z^J_G-S3)flg1@MAWVufT@#j$EOHF3aFglW{=Vf?D1kfa>eTWI;A3?`~m!Hpw;MDuE zWQm=;gg0}3ujn+|5<^4dSXAP#jw!w~U^}QL?}$hLxzRXzjs-wE|!oc?XsM^a=A7;4ZaD6gn3x{|@;MtJ^h2LK0;I-^j*j zaHr_fOripqgy>GRbr)=-p08vn@N5!L$`s8}473n$S0;ne?teE)m2@6!`NgkJ(lizZ zo_vl!pwe~mw8~*$wZ!=e+s_uRb|CsDEvcA)z-C&wljj0K{v!k?&~&nKqhYDWZsUEX zCNxfi+*nrD?<5Hd6Q%VstYRJO`=1(?~7jcQ&|8)+kL^ zQ!9wWVN~J-pm_u%7E-p?V%e$2>D;Yne@oSijKOV(@6EszET0zGQOW3=Nxzq_!jf&X zO>?NE)gaQv9osV-^7ekg3a_(ydd$DBkjcC$}UTxor0PysN+v5eX?gM`342i{pKURy*3aG{>JTt6lRbZ}}qcN-`x~X}-fBNht9}vK;o* zG*+or0W`B|p zgu9>Y!m2z+FgfvT>}xr5dS9|cxF$BH&g)r=lC%gnfOAMRVpY6YA~S(Y4z@;HA*5qj z*3dmK)G+$wsrPFkE4V4ha`O`s7~N*kELQn%f1{b(b#!;7LGw=o8D>q>1IIyy^N$_; zz#5;g*-iqDDDKp`MQk<52h;`nS(dFpZYHRKV5h|~b2e3uToyYy#`4n+3+{lklH1Hs zI$5H~XRK~K0bNou2%%yn+f(hYuP?k&-q;@LR#k5aP$n_s0lLLcZIx>Cj+UIx)q-)@7RLvrqB6#c{-$_BNho zrm1$GTmZ{bn?~#^)?757I8&*yy0$_#_|s`LMk(<#yN?xGRTc4p&hurT1}~)Yfd~`zwvkE(05wKz9{sv`&uIPZ+D$>Xw6Q(DceX1(Rewz~&NCi9CEI!Wp4+4vwRBd6&TEga!JY-_nyI zf}@;+9qG6GSefah>;6UcASXS`v*tDZCa)ei2yf(7(R{H$GVb^Nf+1Nu#=ff3I5rHXtT2ml+ST`G1cot&VMVFa=gkhBnKrdHcK&khpQb}ux}I;E3=$7 zMdi9sPIp_RhE7<{!iCwA=-ZaEbb=k%$B}JGnG-H$d5BtR3q?;jtJchOrpfnV56tW0 zAe!VnPM`&UNxcdjDvS1LFJnGy4+Fw)!#cu-kVTg-F^;BlL@mlhTDe3KnWIc^BW~~J9$w#S*D^Dy4@>Y zm*X@fos!L&Lm8Hjcf>#wb~KizG0Zj6G|{C;>nzu*k*HYsm})uy0<{i+B4#E z55{ecXs}l$IU@s|&Otg9lKHlq!9(vKD!eVFWVtYp2#B2Etm#%%0*7$`t;b9g| zP=bMC@0gSbdhhd9v#3~Y^=?p5EI&ym)3w}NPHhWOBNzn*Dl#_ZJHi@(M$`1s4%+Rf zFY^k(nYv0SFC^^%jYfUDESfLlkywxClM>-05+^PCrJ|>ynbPqtI=N-rpK2<3SjE%ARFfe_htqg_?SJ%}j~Zf1xbQet9Y?o}sfmi6nt>B1%r!6-`B zmGK0aRNy}Sp4Y_H)L@>G@Q>8y0iqF$C=^Db=Xpk`<>>=kTH1iPIDttgoB%l8? zFHOeK2Hr}WC^!doYsJ;w_Zgb`_D!>)3K`lFIi&Irg5XGRB56-SK{ZX)=j*q$LshWQ z=#H|>fiCS;mkr)$3TO%Pymq7JS(fc7+6l7Y`gZlR4cxo_Otn}s`fI#)OTJ;lB1dIU zL8WG8=jXi_QZ5~z^1E>C5-%xX-qctO#sZC555vgSb>h{S!ICh`@N%<8J$2?MTb$sfk1|1Qeq9fFGj@|PrtaUXg2Jf>|T}gE2o}p&z zu$eYErHGWAsc>#vJrzzntYJ?xWSX)~W9h$8>zXaAz3&Y&UopsD83Z=SQpOE0YKTsK zOqyjpWeg6aKYrV6x8x=J5m4tK&+Ng#-GHqLME-Mf^~72D(`HTGf_76?oI#+oo)_2A zTzYC*>4#^z--3FX2Gcn<^pVH0Hx$gPG$+bTlMvv7{dXsUGgU1Q0zdM5RTo)lesv-Rzo&Vm2A!D0Y03==`t-?FF8B}KWXA<=Nk8E z1~;wZR>KI^?ePZ}DE}Z5jIErRA3yRVdQMX`p6jZe!R{+SSHxwsV8|7CMky6D<>eC9 z6n8SWXDuv>8y=4*IuPBeH)RxwA8R}Tpg3ZSG@Pv!x;P_#E*Lne*)slWcZl|*h^iq_ zSthLT2aOdLt_WGQk~s}jnHvjStyr|E7Sb(YVzvpJgR>!quJ zOX*!{NI}IG3M65-77D~TxY$x$UJ~+N&4P}v1?gVjUM6|a#v>n5ZuAV~ufs2A@5p#K zkR6mlFvNB#0yC|6kulz#;&=FUC?rK0(4h$21~H|)ccv~{S<_k7DAW}y&_6G+jfm(s zaHIk;n_0NO>+agfVU!p$Cox5Cwbef441lT6v$wIWLdf_6$HSN>|B zRBywZA?K+O0@1c^uFu9Ht%jza>aNjM@~u}T;OJ;N3UHZ*sV0gte(t~ky$`shn-?d2 zZzqU)>UqRu=t31$+S4(~-}mJX+p0|v(Nwf-!g9q=w7mO)IPHWdr?W>cGTPyiC%m1M z;;J(~VW}(n9S?0~_z60F;FY<+4=OSK`0P-O?oVaW7W>v~dh+($S(`-BkTew2yn!Hd zRd=OJUc&D||8fE2-R$iL_F8l5y7W54Grmw-xX0Y*o%sb7B047@6!&Xn)%g5n zwsNv&f%}{3+i6u}3mM&YZa4`e@Wmd}96LLSE6PUL{leEHMrty}%60`~u5&Zf{7hvh zKcxTQ@G_rqf8u%eQS87b%<}VK6?IERb=oRT)1w;Vd8S!38E!+N)jswlMXEw_Fme!;$J;cYQD)G zf}(`F6`DKnb03u1Y)$MKGpw+a6PK6@n?8vrAZ89Sot&D~$6)90BqhoA{A0kYOjd#MfVQ&)=VUI1qM#PoqxDH?E%C=d>X!3~jSVs#IS307`e<%T4H*Zn49)%i+JHD>MhWHYgDvZdJu9M+7f)gja-L z0SaP&I@E9V^5aa3g3lrd7@t1vRbs2tW!g`+vuNS8m`cg=hBa3%-gWg`iCVN` z5mDerRgVnR^MZqtm$CG#7J1xL?MM0D^bNP&i$(hfl6{Bof9C(K0I{&60T1EQnvN55 z2%6k;sDI15M*;DF{au?=vJfgHpGT+VzYW#k*RkT3XtQrkLXyeM5Z_#gljc?9qjO7M zBBn5)R6@SJje#ROzI~JsGh@jgB%%^f#h0iCKPmL_P^9`OG#c-jX|pv;$Cjn}-LlQL zC^kc%8+AchtDWtMYT$8_r(LkY61FQ(rjPks!ur&T#i$I)TjIX$uQeMDrt5h-%_eif zaysAg(>dPfc`3A9MVdp!BiW9s{ir=Ndc0j0!r zlVUYb6*+U9gmXNmEm9nR2LfUYZkFs*R-+C(xqVYVC zNxvB(=i@f#2|8~iMQOx<97SbfI|JDDZ9+3wE~cZTEYq%NxpF&VnE?K|6t4-rdWW(= z?;UT%fNCmAEofRV(p$Bvc+j1^?a8;i&CGLSTqK`8J~TGr7w`6vKg5K4irw-oH4(D} zIAzn~!wM0YmqYaUBlQhM-C6;`bKYi=po(S9w`e7+O+K~@Y*jmA>Y3r9KK@$oj=LbcYz@L_xe z_u&aYmV>H+nJ6)+?C^t1&cste?bY3yI;5_l`o#NFqE&=kmk?2%D*k$z;xK&`eEY&F zeze8!*%qj3@g^8E$AES*F_S^QCn*n17MhI{r6fh|Yv|QHq0WquXFrvv-nL}IS+xnHOsm@b|9FFF+N`Dg`xXJ zcxG-dj#`LD4JFs<28Vz9$en!d%1U=d^SF_JmJU(n&`yO5Fl3HjkrG@n{V}ODIo6c2 za8@{^=`j8G=qmLpc5h2(kkobQ%JDI;Uc}0D7QrJNAF&+gGF*B%;Z(hZWr2os*Uwy2 zXfjp_+x0imbnr)*J)eF?_74YCGMlA+XJ2P4s#hMv3bpc4q(X!l;wk-?kib@|++~hT3t!(n+joBC*}NDYza^rLcdgzta+U*8cbFM4 zo!avsCbZ`QI5-$n9S|vqG(-pG8kGBC6t2k1K|0RFFx!spfhX z&kmeuL*>Jvg5y{TLAaShH<|i_J>;!?ou+JW-)$(p^@Ml|7mHRFY z4YFg^LR9X9nxiEHuJJ8sZSGv2jYWT@ms(d6Noh-!j&r+=46hN5&8W$lu~VXWX;A>wrAyD_}UBi_h}s2RN_4I){IxB-Nj1 zg!GHXJv}l?(&9#tz1NLKV&{j}Rsd%FW^-Kh^sLTZ$g zk``A4^VTf?x{+09WO!LZPgt#!g*7>z;zwL!fd=3~z24_ZVA#~)NXPX|5B(Wd?C{%l z^{MAk_%O_8ss!`4Z>+e6$M&p&N*ZO~X1cPIo?)>0Xau&`HB}S136|hN>MVtLKv)pU z!9yU=4Xb2sGA|@;eqGtw4Np$MlRnmjsWYTd=#czZD z3`^}dJA^rgSDz87CbJ~Wxoo7KMNM-9@8HriF2Z zW=*@94iLp^WXBWSeg6@)5%IPi7#1xTkH0069YmzA4X<>RMV@V=eFXDN)v2-SXT`%M z7aG^G>FK~_=uANY{sEs{9vRk~m~*kpNv!ch=0m!M=;`(cV}=T>hy7=hi*EQ3Dix}2 zdqqdVv*rpDj``u< zL`YspbIdXJtJRHQ8?&Fb1#8U&$|Jn67nP{!WBRqC zrFQZdZt%p-q6$qI;K0nEg?gMa*>C-#cXeXimv^Z9vnGe+fUZ?u67|RJA6#5Z{eB%} zCUM#YSuy7|qEwC$KNa~fUh{n(`ab}pKwQ6a))y*qA<2bHTB^-Ms9sens>R#3;DnJ| zJT9@kf@dxzPEc`}s$681NCqjiC-rJ|Eq687%Pgyv#OW-t@{#2oOJ^3yaNHfy$^;Z+ zE(jz?%)ZfEX{_xs?KD&>3VW@CjtU6}9RC2F7kV9|A`lC2T860+V!#v=da-+Hmb4`% zeI(b$A2_ewbXlgGb2?@YX1K>Vsx0{zlJ895;20L4OEUieW*{WZ%;)PCU7u0jzo5#)bA2=rK+~3=Na!^Com42V?Nca1ol@0v+4bW5D6vy*Zv2h}*_uvT z^y>h;K86;ggs7Y>a6Mp(#Y0dfIme`I&y;#i>6OTF+=DIW<9AW|#F-wkog8@RoDt4g z@mPD*f?#K-2O#gOru4>$SIz=1S*%(D_sdh~$kbkdDb??*nLVzk-?&cf?txJ^|S zNbpC&$2h|Zr0K~tlaF0u!%P~Si0QPpOS`B}R?Y+oG{Eva<4Ub4XS!n*xzP6t$ULRy zMVIop5xlHs$Rci>^8<#!X}tq6o{MN)jUKAq%CkPD@Q?~}A6V3hrUYk^gFVxcob>gB zrMBspodHLWX+tXbV~&JqCNfSt+`e!Rx+cy+Kdez{Rz2dg7gnP;ajUwo{`_fK!9CyFEEKz9jce1K(~y2As7R8F;RtCl&bW;j(!#Rj`b7t2 z>}qeOs8uCN+ggKKpx^CZhXBu0!4mW^AHF6B7(C&P=R>|WhP@es`-mpd)lBhmH^GAC zGJtgH1_whNgbi*?-q*A%6h;+5qjoP9l@*m!iTS{_8Kz2Mx;e&shg~3BUedc9xA()_ z!AA)z;U<_qR7hA$^y?9lI*|`r(YWl(Dx>Mt;Q2gb8;9p0584t{h}T%ETx}AdWfY%x z55eO_=V!L}5Q8+i&&n%jUU9?yqPCMQm1Q`Qi=;=guTLYGY_x zPVB{FHlW5gYVRR8Eh;fo(MUIJ*ttRp6Ad0J* zkR8(!({daoG}C7XgfkZXqqR+HM5A{(mM)twt!9sjkLw?M`y5{?-n$FzD^0xH8 zPVsp8muWVzqdmzO6HSl=G!HlxOo0Z_?klb3%#9kUDo%vOUJ}V4PEZX>jEi))lhYt% zK~Jkhau|ypM{Diuci!)-4%H%_8eB2)VSPT7W$(&y*I3o1YH7L{v9YIBYqURoI9*16 z5hRaT^Y_xWpKuKHfz4K6dBXW?l&iM7(G-#LAftCJwLOF6s4G zluCOglsNFhXUd3#ryI~%an}%n{6b1?1+8|r@#}RmkX06)bIv8Er`joH#^}iPj~dPf zH(>YoJK1ecfdH(Q&-_mZwY7Um3Uk@Xju#p3>EKj%OV}OyKc>u(kDfdZfex}nkuQrMPRCO z<`;0mCr(GKLc8IDa3V`m=d-KUHEy9+nad}Q5#l7A(|DNljpY*p2QdMv{F$&lVyUxQ zjasK>D^GC#M&hej8I?ogsFX?o&Pe)0RL^trj^jn4u%^h~gvA^YH-jPkSP4>ApBaTU zX^!{a{ow=$WaaLMywkEdZ$pi6W#R`C38A#VyNM`k$_l|RQ-Fymq^~-^25ls=r zTlq2AZMt{5<(IqAKy!03@wV4CkmG2#dbL&NC7MTs%?Py1P#6LS$vn&}rL*4qLgycW z2Qf!IKClzOOv3^jaY{}1OcePUv!I3m_cA>oTp1X}dH(T>(jJ{mHR0j(aB0fmW6Hcd@262yA zJ|QV#ETUE6Mk|u~fe{igbrH@bV&U!3mHYw z`o_f^4lJ>ku8PD7ePD=`E5-1!4%o5o?;d!7>YU;gQWX|;1WEEy;zdIL0DJ_%eBvo| z0}+}c%Pm0d`TIW`hK?acJN`BV8>dkdvPjDEcD!U(>&A=o{2Cx9)2uh9ITDZo$LAkL zdl_CPiuwH&+ga47KSy~`kHJzn7Tu_-)GEQ^K;Rg-CIw>z4pH5$J(}BeS*KE)btsw% zIO3+ERw)%VCo+I#=>^s$z{WX7x6Ow3y~Gxkz}-h}TB@f2{8YXy2_*RYz>JvEjZo~z z6U)!mEp`UbOS&}TyS?s9szfIVc4g8*Up65t%kmZ0-%~mG*J2k*{x``>DXAEtYuW72Y z;db;<@RU>K4ZZ6z)R+J@n4EvCD7$Es+g5_!#AM0CRbMYMQ*p8rY?!R`vD#G3C{kHe_Z}n9Hy?!;`DFvAC|%y(>&`xXMII?d z6YC6U%!BPuNGdEL1QH21C+YHsRP;t*SA$XYjJ;GI=z`v(E+COG#-u>YNF`6tjUTDN zq~cvaI1&*q>ooBVERKBOn@MP7?|L5iJBy`%5aD23GS>)HS~ZTCQN}gx?=`6hs!!wkA}{?Eb(CLR){%~tPvjFDy*Q#Ar@bD z$^h5*k6?O68#Lxy7>VmJIYe>gSKuMLG;YF}7CA9Haxu;`lb$rE1{fgtDw&hzh!Ul# z(gu6k(O{#QT;W5^MLzRo+7`}w#7O<2Qf#C2_>y{8iQAyc@K_IN;Z;QY6$se0u^zbM=g_SRcd-w3Kh9Z;`qyWilOF2!dVFu zOklAw$UEP>IM{W;a#JmE+M`K$qH2QVJC!Ke+QDuDRK64SYV_A?s$s!#hcX(aP7_hv7YwkSLr zy&adl7xUCB_-Mql44nt<9?ms`Gfk*n%hWcJS4gx{nZjzCc=IDV?%)Fk8ra4&72C3o z{`6+*)taniZ0PWoK{(XtGYU6}n>p(g{kF2WHg3_KE|^M9(FpMrNaaW(mH|45+54f6 zaQA0bYQ^PXsa`>GGqq9Ta8^r%NQpudxUGOB%v0{NW;z~cq;q=v)ssQX=ekZanC<&K zkW(nY8F`MdA7-5p4AJq<)-K044dDIE>v06C{hlljTbu#}5!xljK2WZP$z|Pklm7s; z7f(uHF#tn%hk~+;N_m)XPX`z=iMb!70P$7H$mC;poUkA?jK*$eBYN=!PZ%D0Lb}*3wZ#oJF}U5)pHP0lbMXM{JL5LGblYyA>I7E1(35eFBxS28~F+8ni zGU_2UZ-Bduwm(R%)KHyC$<_nL4=BYI;@zVN3X5OGxRj zmzUh&9CD3l?j&eV_Bq9Z*p^n$0_I<@$|#qj@)}IdM?4)O>1wJpkGOr5Z}txC_Eh%3 z{f#aY#mMI$KR&0aORP-gT;QD|$teH~7`;_Ch{lOU2+wk4W^C@znhxd7^8aM>DzU z6iR(fN@5fZ`5dLiC1gLUsRIgp-1o7A>&^tINigbS!LX-{C~wPEf}~E*h!Vz-b0vWt zBUUI(W(4Hx1y*T>{Jh*utq|_CLny7gfK-iNOSvvV`o*$dL+J;LVT7XwQ>Xs`0f;xx zp#5UG98UMTE*kw^+Z%YQk`vVXE4h~G^Wj4++-tl0MkXT%Sj8sHuP~6QSG+0}CD<>% z(_JG3%Y%$^fjPy!*3qv!9+gP1klt|Z4krYm=ECzVq@6iIUESWCp+?ZBuU!>pRYdB} z8zA|<{YsuthLoW$gAksg=6zvx!FAtNIx8w&1!U>0(p!C0e5Fb;Yqjl!T-Lij|m9u2vWu+lmVa-C1t#cOPPHmx7qRF`6?uI+6LnTbVh`SZ&puB*t~{JOiXJ zxDl0{{m#CTG!*#uXDZF*Dq+p6b0!RCS%^5yM6)+?qv1`)<3k2Bcg{)Y$|uP6jfRPK zTtl{Ar>t!`1ZZMmpovJq(8i~c%z8ZwDw>@mYErI}Q0MMNPWl-gU?I#x%8go-mFiY* z!?JyWAit01#d4QSB|T>cym9h^M1~4(ai|$j)+}@s0OlinA43ylFUkvk-c0h3Mx2a6 z9*<=6%wli4V|K~QG}s0peDAZfpS1dE08Zn4<3GGIMXbC%a5U=`{H{l62SRj+RBk8K zh(Ki`eqCVNUxK#?j2~ED#klvjaRmZ#&K}a$2>F^twd&?-V3Z%y0IN8eq{DMO;j0DG zk>Y3tyxvhmyVso5yEx?+t4(d`Mh{5(d)Vgka^O^KS0y1Mq`0Uq2RP-sW2ebXrw53P z9Q2C=cZYkCj^4d38kH$0ZyF%0*3<5yv{D+>4o0wgFJ=;IIz!`Gt5B@;cV9Qp8^@Q@ z7`J^X(;Xpct(i^`r+vU*;K7usl2^Mh8gheWt>-}&ZJSrF zTjJl6p>R>tQcQR%rvO#AB$$b2{os0pgE=t9t3`0L)WaXLPAR*AWVC>(j%Ei_)+J(u zxd#wkheo~`Tgy`F)d|XpORKRisu*Wb37i>3JKmUeiM`QP{{Zh*f9t@Rka~WQq=`s4 z0yrJ)(e0_Ud6cBrS5cyeis3wXio#3Ik6cxnn|i|v%{7;4m1MX` zBB~fq%84YYV2OD^Ri}~(ah{P~Ql@H0wXTRvt;+|W(mK}5*-mBN$4IV{Nzj=2v)dxG z#<|jO*%4v_AYvc;DJqANoh z263zomp{%3doU6M2P=c7V6<`9r6TI5P*w8hlqz;avSZdY zoSfnr%4Gv1n1zd(g!&kUCS>lSl-Nf&%x$E{y%EKs(ZEGx%~7maD0%~kgC~2RSTVI3 zMeMqr$lZ3F3VVcj{C_*eiM{EC>jh+P^BkevTiLSVCz;PqurQajGnkEFmJfJU*1&_ypo%3` z=qpSJ&amHR&jUBJN~GO-nC)K9HyX5Es#2S$I05?HEn}VSQ90bUJ>17bq~Od69eT&w z*3Gd|sUtef`|<_6VI1maB3NTo66Z{FjjI-wBCAX6l@!QHMIs?S?AZqpn)0IPH$P~w zTQu4|%~4X;yO!+~#gW`hA?8H0RHl|($}nSE4KSiR-@GKHS?gIfNAw$g5-Cnukku3L zl!4}wX~y)&T*kFtaZs*5drP=kGI+lhcF6e4W;T`RAmDz`WhXJxwrg>)t4TUJOpIz{ zdEXwe!zb1smiER@S5N-5Oc2xWe$a}HPBk&W_GPog-t7{hT-pUW35#~0WK9+Lv9k%L z5}jf7C`x&O7kO7>`^>?Fp?Q*E~iWzR3&I%v+QDTx) zoDB2n9(^xNLKIMQ$5C`x6u-rTLU`u_;Pb>CNCgy?$cB`0rh}vd-rnoZJh4^CnOwk+ zyR&03e4ylLVI9+22vd7Lo9jT*Jnw6rAiN()8j{@x6y(l)RbU4M&7VltaC4YxM4>HH zo_6S;6PyI%aVgA1rZvZ;Kc-vZk}3(YkbL;le9WLYKS&;bykbX)gNbvY0PjeWS!T%6E8t)O z4&`B}hBJN98>{AN2SiinCOxkA!Tns5g=fkb6qmUo~X(Y=gyh40Y| zqLk!w&_xg+5UZWh))~vleIizxB@a(H@goOVCmddp;mkmab^1g~k>%aT7dRZd%3>0BTGaXC_<&(gocB>LG;@6bru4 zaWolfQRP_XVH?f&Ptq7enuFd1rdfS47`G)Wv7F33Vm{j48md9lfRba@D6iNR9ApgS z#8mf%g+%V0YaJJ7H;Obm-7@2Bk7-Jr@K2ElZ##BH+7U1si0ITR-t?f4Nc$K4{{T9( zrKaCaS0;&AKm{@IRE}je91}EzV1uL+RIB8TW1_mNw{q1t>b~x}98k0)s8jGr1C$af z+rR_n-P6(!YK+O*~F7Hwn-pX*B`o_LUQ>;mH>5Gyq1 zN^Hz}^)XVh>S@-k>aBFK1-h&7(@kzrlBC{YFdsO@Mbx{ey%@SF)T?c}RSGj8R!JTr z!6iGB{!whSsp>eITn?fuCM@f{SO1#aox>7U~ilDM6ZEW2_{pJp-gZLRxzyGf~lAu(GLM!koIm?VjYs zPajj(Lkt(ktTnak@|iUwlxG9d5>+awv1!Ixf66teKN%(^5}b`9yoCb2deqgLkx6*r zVls*ep~yv6rE|!U0%@fKI-J4e4p@ySk4nwtbv}g?!yx*@1+lx4)Mg@>XmpDO74KrG zrsSLeb%2(XodAGlCnRPqoHUk4j1Pjh#)&~3x`7+BmpZ`fqThwa-q-66E%av05dj3f zBEm2XZ-M9{K`|X*`FRN5X|gaPU;zM;8I307V=?2%z!P&nScuD^)WEa<0K$w95O5@P zl8LNzihutAt)PL(M5#9kC%gN@8D`$;9*y^kQshQJ$;3xmn*&J8^@Pi1U4D@vUQ|Y~ zDs~6@`0d*D=owOMhGBl6Fyd5-2mkp;Ce-S_=vooag)JB zz;yXZ*9HT4202Bh*GF}!IrBBaF#eVdhdGZl#x;irx{=2$bAp|?luAMLiCIhCAP8Ep zNoQKikOwbFPe(wg4v?1RMDLOWSoU|u4<`f5C(HGOSG_uUvP7|S*?vtIU*0~{_C=?# zyLMetwC-w0X=uWxILIll1~}#3N^5URHXxIeS0Xw}^at!_cWp}9MG|PY6_Ve}gr4&U z1oeZdS>D&ztR=QsRhUerVrpMy@%2X@WGsGvrUnVbA6OvrJtLTH7K=$oZ&dA~xsgVR zlfrnKjoOHmUK65}GO=(FRdccm}ctaSz??2i;dAic3BB6g3C@=bHyp zYDQs#VmHZzW$uoVU8wCQtx=`_00-I>X_IcPPr6d)9;l%yIWb?UIh(9l?nUaT*=`%l zNM1)R5ecle>|eHLPEE!P(&iF(x4QF=6YYOd_ddlLu|*#3LH4oMZD~Q9UXeCWtbF5Z z(H48SiYRy1i%i%OpQH&{8O8(|wHs+&oqM%a-33eb{8E;DWTK679qEqf>(UjyPLf^N8EcQ_Ik7S7i-mvDN=O*0No2ntL2j9uMfqJdtA8{c;PXU2Kc}S=L>QN zGamrZSQXsATzP%HfBw95p)uT({{ZD51Of#2|k3m3;4P!Cm$i{Lp zoW`@wfq)k!sd2N*E~#LjazumyF`0Ag9XL~LO_e3W1CCK^S0MdomG^M|s{DFXyXhLpWd zQ%B4dqu$Ju_smkJ9naZ%hE_>P)! zf5nasw0c+*XFQBp>D1XxM9ra&{qGRuPO3=q5mYQhr&AG6DH*_uw$d+KQSGodWl@{7 z-Xa0v`LKO5lxmqc8Uqnh4nfI^tzqpJvr1e#V%hSDA;c=5g9>+4l6(Mp;y0vof<2jD zxTju~Dh`&VgfS19-lWOBTNLYzX{ zMASY`KR8J))nKVXGGj$N!tmh|k zUa_$N^AX8zXDeLQwJXa%QPPT>0I}pDO+KDRhFHezfc??>LVBa+sg!3(BC^Qwk=Iz2 z^*&sKrjaHGppL`-&U<#PHrg6j=_qA34fv|6zrv1veAW}~GdEIgXE*?LjW9jtTYw4j-Sp}6uCgYzL0^$eEK94DUlfF~O4-5WBT7?%LCJ%cW5t__-2f&ry*c4RUDXN10U^xU`Iv0Q`*dltFb%XE%xZ-m zcMf=f^Dt6G`t^xr=n-rLTCP&evmSaLm5u~nstS!qcqcNlNbqhX2cQqb&6d< zLh52AC!ee^Zq9jt07ZTJ#p|io-ut=;+Me2E{_u+(63pc>KR$8vzxz0LJ3!hN(dv~; zo6BKF;-!}V02_@IZKT)LZB>;tiSJK?uS`K#9HKy$CFBfz_3b}wt7!XFT=x3Qr8e`< zFi|1rbBl(|*9+3qQzwubo>5$znTV)EDRzM@T$gSnrcZ;?HJU@6Am>vkjGS~asP9E; zim??*<(LvTqHrh1kQEcfCCprD0|QagFj3Dj4=Ktbio9j?JpqOH6**TDktC$)63Au* z2}vJF`m5L;=4Cx5uDTS0g;@kRODKN^I0n{InpLHg&zVfw1LqeyNt#(fIprTiKXAPs zhF>z)bcR-nw4M3Hr;+6znzo*!ctI3))&>1wvqH48O`RmSXiYPxiw2d|MN(wtj31;g zCsIL*UH<^=?J+_7`fXuU(5N@@&`aS#X}psIdO?xY^^M!q4s?peziQHUe^aL@^+yeq zrz64(V?1m`G}+3{X8;4e)6y6tQ0~W9uHN*zJ+}4jR*JIADAgAXfJe=U=;?1fAWSim z4zLNhWXbM`steJS!#}_ewfR>+c?>?KBJVeBryw0e_bl8y(2p>K~WIhER^?=M6eNOLGU z>+1*BcRTOGl@w1rmod~^vQ3SvDpCn^kL<-tw&HGvD-^cpjovz> zV|H|~ytz2kMwFH2>kb1RBatFg91)~y_L>{ZyaahZf0>LoK>*HlGI+9`3`=e~;w~ni zmU_Wyf2?lUxRh?Har29dcZnjLyORiLH*u~Yq2WQm%Q)sE-NWe~(8ke?!Rlf%IvDh1 z=_&d~GzW7L=!Rf3h=KAwp(SJ;VLf;m;wj`A!Hp?QrDC4(>lmT422(MXBQlYp5OF=+ zk4Qa|@~UuPNv1g?F%GA_+6U4rm+e=v0wgi!h)QSH2Ch9>2?V_r9U`GbnrBLPhhDJZ zqh$9tw9*lzh~6^HdGm*5ys68P4lJt4t4+Fe!H>6p*;7|R`jwj{8W0cH2`Ys|^h@w# zk!^}YEqX@=e(26+`TD^-K_mMor%3tF{h=1qOK;lwYI{PGswTwt?ib?mV%4(sinMV! zC+~NDn2Lr+sERc&D6&r=0C~mjwN$!eG?N~Yk*UN_G{m)69Zr#@tw#>3CUQE#5j=<< z0;{5eDPk<+0EtN^CMipfP)m6mzw^7Q4uTAxoSL!{amq7A^9R;Go&Nx5_0KD7o~LN6 z!8yx@i7A!($Ic$mGjT2eq0AG;R%rUH6;N7Q#mW~0(4V6r2Kr^AkZkTXw_)2vp^ z>Th#A;;yZl#pOg!vxQM?5yE^eIBLX!)ZkzYoc_>u3^=#0YsQZ-XygYB(?U9B&DdS_hRYzEnsfyXL4C{o};WESUJWFLr|XQyl0ZRMg>%s8C-_> z;zqzrCX+ys(*2s9+7t^x`+A(|wtCfH88uF-!HmT9btT<8bi^mEfsvg6?ej2J~!bUA1gMxNb88mYxWOn8Y!jrzFB zl;bcC2c&$-?caO*{{U?*>`HpcsK$uR8C(!PG*3^Egm{y4CNlMLjAl7fOk6l$cpU^d z59Hkg1C(n;$spsb9LC-iD%)B*C~wZJ#V-Tv2`-s{N@@OCiv}h15%m86wng%$#`aHW zY*LH>QCeu8eiwtu9N=9O4%<}W~i<>6%TZ43x zdTR*Y{oxiHUWt|pJzi9@q4b6niOk9gWz1~KT{I9-`y-_aVjIkuo=gxUQjyR8kUks* z6d>a;v-o~|mpGzo;zPZURRDb0!izs>(?QJ;eDz z%pCEW@lK?35JfVlE-|LD3xzTcB5+19PIC+sLYpdNm51v9I0Vh4Lf}fV;2i`~Z+b%) zDw(BMKb&E-q)pZYdfyTmx3h?^QfdV`_hy$6&9+3m;ZE@??)>43^A}R&9+2jQ1f4M- zY=5&3W->6ZOb#46@PeI0a;>omx1=MG);F#1O)1VybHDb8`##FX^Zx*Qt)EPe9sdAI zJYQc0Sl?oIAG*=(bByG7271Lv(`FNAc=L~)5?gnLx_HubG0`$f&n&@mlaZ`9YL!7r zFhD7v6G*z++kv#0(7|xRms(kyM>N!skwl&&!|{;v;e_e$OegCp&WD_OUSsPKB98@K zV`+&pk(0_KmE5S*fF}{vJ)5gfX&XwV)fhfeH4{`wG1uoDpKO$(r4Dg2dCs|ueOJ9l z1Z&DZ+Py9tcE3_elTf6T9lJ?2X|K~>IFd=IoThO;M7a}6L@upkw#kT*&1Qtkq}qu6 z#QaqnWU5XC3Y(=4W)kV1QKf858Axzp4f902k(s^0XS|U_Q=0~P6~q+X`f~!Bl8{fz z8PQ3=$%}P~SaW&WTvv$B)pUF%kE{x`zUWsYTlIIVUM@U&D|6z0@bUT>C*P7w-Qn{80O5iNAZRfh z4y@kvw9$8IIj`oN{SEeB@18{3xD-Ck7X+snl9TDNGo4L&FGpt@qK zQ4oC^94z4` z(#feh#i5!q+%nBM9HArKW{b-vU7f0JW*7i^M3hNDn4d!uvltnL%aD?)8P0Xm9m^;n z2%CgI>_lT5{xQa2u_AcD0yV(sB1FK~NX)=vK?jaQ=@^_DkKO&Fb~5ApJ$)lc(4tA} z8G24eJz_}CrCxBr5rM3FFtKu)SdUCWl#Gs0JS=?2wm1^ak@JeXw&c!r>mE7`!6-3w z!6CvK`9XBXr+1tQJmkT1p)+yE&T|2}Z&Q>JDyQ{`W|w*cTYW>k4h$=EM5w!)Gfqyi zx-x+@MBxV<5+*$(N|moG33sIsYh!{ng*o9blj{Sv8@=WLzUE$*2so z0A(P;untC%b+)d#DAG>dtEa7#cAt#BIc^fMa<`Jqpv}5SkT7*Q7b{kbe9%4n@LUtE2}!4I+)$hII`^ew^6pPB;K)GzLeeuf6ghpS*9Yb5Q8Yx zYl!KzGA5#okWM4&o8M{IH7jS9rCG%rGCv*#K@WtieDL+MMcUE{z%rd>Jwza^%Q>wB zx^bUKOMl&0r9rzjCi^R(hl5Z-eIqEnMqG{1M^HpMtN>`^NOxSVT=Wf+)9TM|Jj(ri zc2v}esgKf~%+iF1cc~GU0}}GYQ`~z^Z5q&|D{m=qqTM35gjVw)nV2D1n}3JXTt}bs z%u}|5yR`(By4ARfl~h7rBIii*V9@+9pLFMxY42=lyZc38R(7!{z`mVee4<=6KLkOQ zpa9SauM<^e1UGGGBot%o0;YFi$w(zNH~F>EiPf*K?0Hq z4eos7d%kdh^wJzrKJVopSbGEeo}IGGp5|_}>C_ptSB|;zxknn>%}!$FIXW4H2R~T& z_ODf5w^e&qs7=ICXUi&OALGT^gpf&sa!N1+l8m3E0Wmo`!IqZ`-#g1Y{bJEc?xTS& zG=RznIg2ypi^Mb|JvEJFT3IL4);ED_kCJ+eWD%nx+p~GgBk>^gr83Pl#Zxx-AbLd7 zbAgElY@SeJMEdoKlLI3nHWNyD7$Gn9i6DSR?x&Uf zK2Ra#W6|P9_6g|`l1Ro(dNoDQ2>sZKMgW-fPuha~^nw#%fuEEIH#7B!dqG`nK!jUzW&^3M!c5BBq*ty715pIaF$5g)Fp!PosEXkyCk8C3 zRfR~2Mh500@vs~2x3fK`QEwU?oJCkY!AtQ$5SH?#D7`XeCFB9jTPoB~=wXkPexbUn zQ19lBE%^~rM*%dPrkOb6=^Rp`{YKXSP~&$v&!krF8+?g#@{iB&_L1y{q|NOEZ495N z`MOgpO{)Zl^}wxUA30sLx!ONbS!K>=?+nBL0DMS! z%0Ec1ZEt3`1vbKYZrg2@QQ&TpfvV%q{&H|DW#pMrG~{DE$4``PE(sCE=#?9S~%GjG41IjPAQ)||bRZnM>8ZW#(?7tQN0KLbP{uFvza%NJj(*e3P-H0gjVpEd} zt?IJW8=;){1sy&14{*3uzK|r(_oX6S>NLayIRu?!sCz=)7G;e@6>)6SpS!3s!!&%v zM;0fcN~)>}MC1WBrWI5^@rC}&i8z|ne>{wur724|W{$Dc=u92vQdB>gh$4;cqxQ(`WO8tATv|n_oa- zZqlYH0gh1qi=E%fJGZj!TJN6Ny8s9`X6}No8{wjS80L3fwIy9trW%nrKfGdX+#XT$ zeK=vH;Q8Ed^^2n^M4Op(IMT=xQ%BccbrF&>kv)Mz>^V^uUPbAZbl*`4zcWySP)c#D|T`@#0gXe z_A?&H#&ZPAF(*E-T2HesuqmI=M5Rz5N9q9(!Hg&`s??Iq__F^RGDg7Mo9U!8NH)3EybBPgwd3W|gU*$_dmNVTc$Qf{qeW zE|KBPN01%PEWpMlAOn-q2dwyCb{$cdZj9+To1|54XOnxXX-M^q+wT+yT*uh^6`%O; zV>G1bbuJUe>Q0{+7~prKkb~*UiRg92IF!st!93#cv&!?T?LvD>>FrJ*(-TXAimUjE zkL5*qX+*N|Q@|5vQ5I?@vB-AEXIoX<)}d9jc#WJX_E&xcYTB(lsf5(j4Ma^^$vQDdiqtQ-N26Zw2NZwN~(=s zgxo1nmxQ9ouke+Po+&0bW}8l!FqPX9wD}RnFIp|(CGw?uzSDl3>pioB{{Sq$VtQFf zr@9EwND`q>z|LSjv0B#kwOFEucO!>3&mA(i34SW6LAI!wB6BV#>58kJSL#n99PoT^uGR%4nV|hWq(DI5;wZjA^ptxeFO;-v30941qi5b+$ zxJI}c)(_q8{obCD@}o*u1BkI0QE2JX)TH+?863S}11KEj{X}lf{IrUrN3JO;zDW=3 z2ruy=Mfhbl@jKW!(8DS@22+C{MbuljKF6$T7SmsKxC$(wTrbTZNaj}6NSEeW&hXA4 z38g#7z1BWds2NjosXV=6?&%qfl8`Z^c!7hY7R8k{dPL--naS{flNo0+fj|M%ug(_- zr#c9lY9a|N7nR4>Se+)5oi|Ku9uBb#^v3fz@8T(lQ*8&OK0Du?)9A zDADb9X$amCw68}ZVp?5PDnOX(kjR6mw@k7O9h zTpm#wN=#>ZG~y5M7>wwL-+*RJVCxY`PI|yyk5dpWka_ipY7^<9f#V^%NKHJ`X}WaGU#OLh;3S*rtbU%&W8Al0l}|xO>9(uW&`+{IPvWPKDmZoWvQO8T z%O+$b=3hhW8eTTMySw=5m_=#cRjQriCe0r@Mn`>wq^}u%;>c z8>g2e9}N3V+GfVvE6IRQa;~b+li?xZ$9C9VU@p#3Puv1ilLI2}jfrA_5SNQNg;D0KsZAsI5%nHgE4%h^0?)$W1{;) z-xao=)Ck;LHmR(Wc`1`Mswj!@)K{LdM4~s976msFJB+(Pz@wGEkVZrH0@&S}XzMao-~O5_avVi(A+gz~5+AcN8*?XCy*OmRc( z%W359)>Z?c$0(0}q0s~Sz#?LK7-@2CevNqCQ|&F?LB%!RLW{Ije+5X=p-7%tcwEJLLbDjONg-^oGRjBNG?IzFMx4xaKW1xP=FcikFEx;JTWs+xAe!fj z5n3$tDz6e=9(QrhElJq&?t(z&=^YNQvNRj+I-@zwHhb6CBPWcD%(T$Wvei1 z+T}rmj?VGoDItVB9xP9A?GV-I22JCUFRrmzvuhJ;DF^e5r?lf5hR^mtO0j87JU43u ziXZqeKFUa}xGK(hdi`LTwI}NzCDo9atfPLi`M)UX?va*R0X~{WO54RN@6;i}& zOO$T|^M&%XmwT9lKehSAfd(=h5rY!S%wwEq;z5a1k6ir0mRn9OzWh+1cx zCr+^ua4`wytjr0I8K=i6jc1MmK1>PkRVFyyF}o~jpI9}3D~#imGPmU!B+L2YHh0fR zEG!Vp*yR&e`=Db;f)}ot9xoTogmXS8LSj50LmDElL+1LxBoa=av`GXY^#;mgiyC$; zjDrS5wU>c*N`b-SEd$R`;et+>iw&5=Di5r8uVi~>-`T}6w$^TCOw5&3F;zYnFPw9` z_WN3(CuWc!fJixuYl?Z6K`Js zoG}lSGlLwz+OKB2KiaxgJF>}QqbaFw)^SK`qS_?cRdq@(doiuLrG(L1ZR~(2AaxyM zH2NMC8b{1@D+1=aDy|#O*d(Gy3l(FsrFP9|b?_d^94pO|DPI-BxmPd$}=9 zo=K$6WjcJLkXV+#yOe!W_p+(DWRDe}^VWygV$vv_qjV84!Pk(3_I}{FpBd{PT5Mj7 zh1+0NZUkJa?sTbYI(&lOXA~u!BaT-OWN;*u0hzEd>6p7#iDYHrjA|mIWNl*SrO>J< zv89=08R06Y`o^_ZD5Fi4*qbwT0tdSHw|lwe(hRTGFDu^FrBdt}m2V>imG`p4n%qe9 zcgfD7<7>T*-;`}=90R_3b&8Vi_Or2>8dL7ZjvG3tBowBqsnJw{gA=E>sAWke$OpVV zAd>YAp6m#A`?nBqDoSIgb{GYzU}Jg>pU%C?&)$d9&yA zTwhe_756|}a5wl${b7@0CYTJxrrcr`kW6tM>)C$ruct+D-l4)(hZl&8RCyvHiUwIg z*AZi@I+fI*NO=yC*=rXq66m40r_yE#nSSz0L2|j3ez}P$GXOy+tZ=)Ln)C{yg%!L1 z02n}zfHMq%6wSBH9@Pf!vFf$+b>CD5TRvKsQg%MvkIiCseys43Q5VqkBq9Q%#)=;(%|D!9Z}Ku zgrLfLMk7iY2)om)YQ~;X=6b-hO*T%j(qcD(%vh;e>zKeNI+*vymJV?+z}6%a9O_I; zRT$PZdUGl7K}6_SXaOvumYWau+U?HlMETC1vY=ALp1v1FbJAn&~f@g z221|{NlrJ9KUg|7l^hJ>406OHHuQQVZZ}Rb`oUD!k|i$blt6Q6OiIb>%v=@IGvEj@_TqRo!!xCjO z;~L@&!1RdPrQ6la+Ca2@Gxdm`9boHrhb_TeN{3EGMHJ(X351(Lc_fk@K+~jHtc-#W z&Ob*sJ80~_OAVIBE;jP4i-tKxMe)xO!t3>Qi;1aH9e1_FTWdFzv~VROo}8nfv)O%4 z+`naEW!IH&Z>*xpxDMCS7fj4s348r%b2m%~u3d8pf-?@HWByPE)vpTGw)U8f9%jyI zPSRP8R7|&&ufkFrQRznn6%wuQ4>dalCWyQ<9n(jF)8 za=)9x*UJ9@r50N$is{ujvq|C1JKmY;{&8foK)k2G#)lB1?o-+NyKzka0ArP^q^>>a zQ+|__xM?b%2hNAL6wcC54g|Q}%(y!JBK7<|EeLA@8aha~E-}4@VH+BmcQz&`Pn;*L z;2mKN$Wbz`I9XL>czA{qKLZ)$3{^n zs#JK=8IHId;T4xgG->m%IO)3~sb6-j)h)8khT|v9{@mmCie+R;Ff+_~9Ryn|6^!6+ z{?OLypwOyYH>xqSEfnOc&|YO;&cB?DLY&hTB@@q)F!X}KmT5+Cbn6`Eg|s`LWwpl7 zYxI>;Z0)~jNR!SRB}HYq-Ix+N$AueQgNWAl+I`u!^mvuE6jpkF6{<=0f9j~K@sf{7 znr*YXK+n&d74C8JikP)3(u@bBh5gIj*g=WYN&rj)E9&9Q#OV}`bCP0 z?7SW6zj(J-Zz?qn+P>?UsuJ!mp0HH~$y*!8^@*z!iA0L&}F`Dh|t>MS+RLpy|pZ!90XW(Il4F zK2!kt^uXs>&~Im4#`&kZ>j0agVWBX{Ofk*_xDfj~P7vi1OIFUA=K-sxbn6lzv01K% zTtjB6{{Ti!uSgY1j`t{B<-u;WR+_CewK<8;IAt#(^ny`IWzp?39AX$bf5tnx{o^r= z6~`K7@w)}n8S$mwCInb|L~opwHO@7SDod8K9n<^3icc_`lnn9c;bW1qSr6BRj-%KS;>tBEr$wGpZW3&X7|#x@utgNWj!`fR)Or>F}Vo zUv$8($(-mjuSl}&YS+2$Ywevf+(Bg?D6rs^qK&j#hU}+$VU2pl#>$k-DBhPEdPm-} z?6u9QZc)w3x(e4BqOT4|YU-~S;m04T(D;haa3)UaJw8xi@+f%5Cd{Prg-%8#-8~^)&fTpd!#2&zyx6a_Me8#rs-?xr zhEvmc6$unf4-DY?X$oCSl0fSmmgx`0=ll+f`Q=rg1w>1~HB6*=MT&ZmYfq6}bLWq& zG_q%w%$s;koSgHErL}P==JT4q>bl+B?pdN8gq!(L;LH40fRIW?Ib`#T%(sEAV3QZQ zs|?p{q6@eQ^%}x=)aj_x4Z#TZg;zN4dUT3S<6UKJQJh>A8TgzJ5fpP9I!<*6mRU}t zoK&clncfl`@`iiXs#E)d*tb8TRWw4%ffHLPC@;QiQFERCw<+A52 zE^50r{{H~na2u`1U*Rpnip|%V0U}*93M4Gq_K>ld-0bKmRV7fqM@MNK zBA?a{rqN~~oN|cVzLIG)Bb0Exv{db+cC9<*+M?kXX>khRdA~S5j*Q98f$IugP9~c` zBB<`Aa8|-K3Jn>{R!ObHN3Rwirshc`63la?9YrJ!P9wQkmwl6eY&NZE)a`}Z-eRVj zQ!BvuG2n4FMB060HL0c}LQGXE%_{6Ftm&)D_j!W<0BlJ{{s|GC?1Pif)Wj5%r+EIc zV76;d?1!pcwyi0;Xf$8MW_~XgA)1@K4yG%Yu1F$N`a`?A_n~bH%TBl0OFF9;xKWt+ zu)bPhl|l8)B(&R3%=nq-);O=U-oO#5Y{~xA>58k{sVW`hX5_MQ)~p(;Vo@Q+vco!t z3DfqEm>H!i`lTr+9E4b@2PBiM1m_#tLzFVJ1eTgo4mAcF(cf{W-ONbD0uGTYDZ*0; zPgATmS%6wi>~x4HOzRV`N^TQX!*h-){o<=wr_Ufg-`XOW5Osy+u~{`6Ib4N6(=fRN zXOeEQJPk>GG66(fokUov2Ln^mHJEpX1Y)}0UJ7rzKz9Hpe&oG+M6Yz|(g#AQ1AW&6 zFgxjSgP0U4uik^Gue)kahT*_t02d-fp)G75mLlu8(8#1F!?Xy1#K1I_VDvf>uyl;yH)0C4U zX-4T2ay?*DCeFFi0rqmTXnRhrOK;v6TAWl^2F)3&{{YS5K@VI^guFzh9P&;eA~U2@ zJ*-+<25zK{$rATFI1d<}3?RW~){x^mi%{xp{>U<(Qd;R8++C^aDc# zOn0@LU#uwG#?7jht<>_%T?Z;RtE7sp6yRtgY8}#=l8MZ+=2Ah5?OswQ8?yd_IV-)3 z+}6|Prh=(*)4<&EGioM)7 z^`^5w_A6S|GCFF4krmK-L7(C%)x0HK|RH+YW%Ff}^;BgtZ@X}lPu_ZdF zF{u$5?{n8M-iNYl%p~@*iwP6~;7hW6FY#gul*2k05%XDD4&cNx+TPDV&ekWpTr24f5@iv6xp7u<#T59e_`DGe=u9_GbJiuNz}z9l;*MP**m^$fc}XRS(laZ8y^I|M z2VP>A47`>)azOb8pGLh69#1TEj2JmNGSuEtX79Pp7k5!M&5bw2iW=M1If zK9OLhK5X?q(=I{ltXb(*nO~74<~I^)sfk}o6;tf~oS@~{BRI%1>mK1t{{UhK?C2>b zRznfvYNEK*4pF4wZk;+o31Xg>bcK&CTpa{@-AE}YK4rX zN$D7}x23HUsE@8TU2@%<2ljrF`=CBdvuR9O)5c(YXyjK-E?UyYS%$maV&(ipjWZb8 z%#}k%{DAfMTUP;rXRZBXol71{Ftx@M_=2raVz|?f<9{wOFPxOLp=QVF?O9Azz zMwM2q(O0up6IcHLmb7BGEUYJ%d9@^FTz`~%IoH+`ZT|pfH2(l*ize5elIw=wP2-RTK=pw%-u&Xxv&sdl?FzxQ?Q~l7#?^Wh%J!;~-}CAuJSaA| zI+n5ErliJIF^NY=D4B3|9HNu5t*_M7+Y1_dJ6TkytQUCI`!{I#NTvL!m2?MXGjTi9 z06_JKBzgXjGnB`(@d83$aRZP?e{{SK+E-TWWP=;x=$jdT0Egfy-F6?C)sS zw%KS-?W>-Q-`@!}StMQ&s=7qWBBNQtiOhFN$q^uzU1j~F=GiONTTc2>7j)GcJ!bbT z(s(@Jk%CL^B0Tqj8sp~%0q7&FU+y+%wwp-}t57M^(&{vYk`*~oK2e3BDvaeR`@(GF zF{Gq|HR~2;^akt@O)If(&J|_FN!j?&reaAVLCErn-#M7eq5UK0d(P8rrR7lKG?mi4 z0;)-@c_r%yQkS1}0CBD&1`5m$x<@poKXFj4e+bn=y`44qtQ;sjr2R}gGKpm01ZNtE zW!(8kPL@h|ln;D8(0(KcdH(=r0<3^Dfgfd4_RoG%pD#zdXs`QQMw~u4PtAm8Sx+J& zItn=lBle4JowZ9JX_o8zR-h59 zfA0!gm$_*#pn}B0Zs|Orsw}w}Bcy!;U{|fH{?HHJDx2c$c!`nXBLmdQ1OQ-@M%N_3 zHTpXA^c1Jj>a>>}bM{1(TqdMxEmPe?oHV1SA|t)~#Ww5NPSPtD!}|R_6sT?(_==>8 zzHAZiF;X1*LfX)x8MzK|Ho_6w`W4oUD>n0K>5fkkMU_vSCE$(X zyns+(@qZ|rX3mRcH;L;MU`U%o);>J;pV|60PqYPUhRApdeW4HhSnd=#_tTK(2ms`1 z6<`FdI5>-(tWE(Qk+{>8Mhw92{Nhf+AT(=5lv?h}3mo;1fwPUbA+Q?lG3CKbC{ruR_hv~i31bT!G%uu{StjpG>R^M& z;vn0l?&EHC$D2E%$dyeOvjc2CSCT6ExQMOlFt&hkJj4)t<2>L#xIIr;sa#uh+VzWA zlEG7E3DX`h0at18ywtxM4ym+lZ~(U-cpU-%07%}aZj=W2pY$;f*gc|dxh;0GS@y$l zz`aHBSti&~F9i5MzOX|Zc`hauRPSSV1oPLNX-$`b-RBH81+~kD#9R2nzh^mK+pVI4 zHwsFR2@mHZ^v`4}_IL~yrAqp;)v|68Sfs0RpBfb!oU==v(0RdAQH~7S@{Y~44`>^X zvt-g(+>OvPwW%f9I0$n{K*_fPa%Ik=T*OpxGlLOr+We+pmhCR>vlgYXsU(&IMq`-% zY!^mIr!kUnNY7Cc)^|bE5y)v(+B0iaO0CChD9jfMh7UVGIG&{}+(9gpXO=_`2*#!t z3aOZH3bL3#C@eE&fv4{qR!BUEkGZc4J84hq%2&C zaS(5A%yjDqQ6)NNU)mRJzQw&ZR`tso>)zgyzD66sbwWtaqYzbRPEc#FXG(p{vX@dd zH!a);8|k2eoTEx?;;r2$^?-#|bjIihT_Mw3HtKb6&dL2uy5gm|#FMYq81_GRaxn{= zMyO`qC!A4sjK0z=hK+0)u6fa7;ZebJGB{NbJs_4Fh%=gf(U@aLv?_pa6P#-nYZKab z(6Q1=&aEh&OBn5IC_Fb`;y_I6^Cs?TNclqR%DXf9cSz-=MYNrW?CRxq(`q*Il98Sw za<$MyyHSB}Hl0jSMziUzvGMP>6IY4t#f4g7;k%+Ez%kl(dPfKh@;zYSG{F(e-%{SO zXxgH(KW2I4s~2GS@&Yt~kDt4klefT=N^{CEGrf`P8+OuppV~18vSbP?ELPyg_!A98 zVJSCGu(GUx4OQ;)5U#e)RHeueS~Cza@``0X<8a=sz?;j?u$os>r7;6BijObK8F8}z z06wvYx`+x6X0Ri(!8G*cBxH#3SN{Nt30blv_J;C-^@#75(leBB@ynz^+74ic$nn_W z9A_Ny3TSf`!QS+O$30;pNf3fZJ!4jMZt*$m5=+c|V4AOL4}znTq8u}$fhjrUJz<1j zHVv|in`)OUgKq@OihDlL0{vo}c3lB5MBhkfKr(@;0xS<_zMtK#TWuDW{j1i#8YntT zgp%oTeiTrvHF-!TOluOJW-M+QmbU{1s}$uO(kaMs5LAyQ6H}(hn+Fq2d3wMgPraZ# z;Rewzhg(TSYpV?G;oxO55 zRaa>D=&K}_sJZx267*G;o>e59L-&Sxh+AFEfHy5Osa~K zMBUs*CX;mF%lkqq1twSNG(`XnF-IR~T%qNy1yv3KI6J^1SPu<_!7`+?Z zRcaw@1Af&^SB2o1MnWzUG70+PZ&+7HAWTUxRd?F8UB1u!6;|1MB&tumBp!i`!1A=< z9r;uw4w!@Ht#?eh=@kvAw7RV+6QJF8vaMuXaFSOLYDP)B(##AlW1N!|`+DQ4S@bG` zR}*Cdh^4-YB@Gq%#EFS#oNke?&M{Cq>kIbZw;G<-nA7cgEfBU!oI;Dth{qS@2C{4< z1k7?wLlq&kHDv-*ROB%ee+s@j3 z5d{0{)7`7^f0qJ_lUx~Lvj<6|p~NKFZ?-1Nu9TcxcLT7MQ6a+MEO0UM%x0xjeBgId z=kkr#W+oYn^49{-sebCERFg}I;v`9d+cGFkzXB@92Ox5V%Ul;Nrq*{gBqn;@G2#T_ zi+AA=B`5WS^{Ulqa?YNShfnOCu2OfZ50glypOBz}v${F+gKXQNUC(A+HFBHG`KZGD>zE$BiKz2T0L*lny>`^u&d!Z9rH;x2HH2KKHJCr!=;%xMROxZe^(r!oT5)Ran z?OBfkMD8MnEd$FMyil4$rnskf(;V_?f1kL@0W>LN?N&Hn(%h_Ns_ z0|(2xY zwf1>g**c7S9mbLzLh&ChW1K-Z3aZYMZUo)K(8jY?aiI}fwmqNfw;c&I*Q9oPg)@*| z4>~oS(@ezJ9)ck@Jky>25?brZHU2F5{_x`i&`0PM({oF(n=LjKE1TYHa6ZV* z=<$_`K<`Zm>mqFE3`nWlWs|ad9iGd!m9Q8V22Yy5Oh_TjeTTXNrdq;Gf z^8OM_K~H9z0|fGglU69;9npyAf5JE6cBHFZ?F%&z2{NXNMgTd^AbNI96-@dbac^G8 zrPkO&ENY%_^u zCU4#fJj{HbDIp=L;YV1LSw=l0(IV&*!#=Sm6!O>gk4DJlEntzT%z8H~oM6Yfz^Y zevuGY?JBi(=3+2G9K;C?==^k0?D9F@`A3-?&zO*M5Y3)e@D(|StVf5-q-@-3G9pFL z4bWA`XU7O*F%}0=3>%D$2tbdH0J9P%K9kZiyJ@8%{W!5H#xtRBlp882NIJ<4N28*ml$G*sYS4zuD%XqMALZOX4gN z=N$H}ERrfF-sjQ|6aYY*PFa9$T9wT}vnW@!QK3;weGb@BOTtx15@}_fS(B9g^NhyA zQVua4cHZ`QqkBNUbGC|2z@lN(P9jZ0ygtf*1z6s&_IJ|C)@eTJ=j#I81OcRTyWaNO zHp=fhJi9}ncB*|b-vRMxmy5#uXeAcy*Gg$on1V)`<@AZI8kZCiG#TxBt+ht5*xXbW zVM!{h@mQX`Z{~mH5=&2+6-=gVZjFABcsV=6*Q9*$W7`fcT7ropuxP8Ykz%;=a}Ct1 zN}Qk)2pq&8{ALG-Hk~z#&AYMt?((C&uhQmjql$a=n!9R>{vvR56cDJ9EXM%LkVuUx zRC!y=#FT^ALl3qY?F9E?#BA>Sww6+stG*>kB@yJ7bw8{^X>zJcsVD@%VpEtEty{7k z-Pq)tLZDIDU-g>ZqcWevj_PWyOM9JsQ3X#ZRS9KO4e>4}5$AOPyto8w=wXesK)o-; z&AOdcPS(`~Raq2Q>#l|oRVGb7^q^pzW)r(&SD$!CQM2{~vz?*YHM?c%3@NpgiXkPX zTMKb@)WGc=sFdP!F*57UHVe!&))3LQGqxXRg`2NcrlnMDu)`&qO}>((Mw8Z2agiy( z9Pc7sO1Z)bxckr1mq12W*mzfWWZp_ApGJHI@s$C z=Hz3)ZStFFT(&9|yRn}U)X8xfZw#r$g)GN-8S@aSx^>b%d`aHbtxK)7Q)hj(8IwpU zi4w{A!|He@UhkxAH+p08kE_@Am2Udipi?O=5}vhLLo$QVom zDm`HKOeI!QbD{aeswHwpQf`nABZyso%Z;fG6=iL{P(Nx)q@s_9kpb1|BRCUl1J3tdxD96JqeD8t>J#KO|0g5NRo6%KD^?M zStpkv5y(ly5iPjUpw!{AhU`L~#v6RI#3r3-JZu zZu03I?D46!x%Bw_p%p;pT#rZwd51hjr41UDjx&v5W-7{=!TsV1_AlmuRl z}wRZHirzD8*r$|LYxS$e9W!FrYV=0>hQvhw| zh~A5`%0(gNC05T{yWyz)7Qgbp6N>}VD!t>8`olaO&Rrsf?5(wAHZgzKZ2FaazN5P0 z$dlC7+&(R|9QBB?rNxdcuV)Bda-B}_RRm;xiG zW>9eyEt;s`Y!{pDo>W~=Qno4FCn-`E9x5ea(lTjfz~2*UdgdM3wX6~+AFOl5wk>ek zEGky&Z63(oqvc8~eIG8l45(lv1;2+!0nBqR;0R?s`dvh(LP$kSS<>%62a!ZEWm&P z)6zIO+3nWq=u>8`)h=z8&XaPZ#MpR3H#L!rlY&GdJNx-L=N60Q#?H1aaO&ps>E>;SLq9oS)wx>x!%d@A^ie;jdhN*Pxe}8P9uQkqjXlIaWPn1XxXyezFTrqrqkTXZJrFrKLMgqrAi$tMTfa_3BQ zg6PLN)*aMriUp4Li29>#hx5}ASY@t?{{V{{)a3w;GxU#EatOpx{i*2HXSS6;Xx7a= zMFk-7R6`l!BLS^#=1`#N(gUczD-GRZPi9@LR4X<`ex+wE+8i`%#R#8@L~4^6uyoX);3L^X7BX*!E~(wBu7xJ*i_o8eY#W| z>*SFIzj;O&?(6i8{qe3he`w}AQ1)q_t2&k1ZA7x26qe(zk>Tbvo#dxbH1&no0@F-1 z&*>cVX4c=dO{BQDX>ZyoLRX(`9q-l)p#}<`B*2OD(h*H4!OXw3avyC!Xo~fa$xVue zA8UAr^qQl|;Hw=D)L|;bI|m>h==q39XF0|XIQg#GC$aElI*90$H zMV?cUoWWvYjZ9?cA|&1(v6$6wyBWy!5g8zJF&m#2L5KpOC;*r*Aj_fY6no(g&vPmg z_`Wn(-JHpj(@0h($vKB@4<4MX{{SsNNK-Pi$ftB3aV)X|2oOymA9SZQ$62A>9T{B6 zch5)^r>{85On55p;s~{w$f-Ny8ug8#r7064o2yTx6#Rs=l>YJP+Tzxn;E|9%a3EtT zf@RL|1J(}Now-W6(seCT;P-ou!^NeZ&&BOZehgLas+`n;i9tEg3~TwIaD z{8*Zr2^^rBH57VB-Ww-VWBX6DB&yqV_9>@OYr<8g26KoWsWiaob<9IrlmVo@JtO2T zuxwt{*wtpWQL6fpUM;6mg7o2UfQ});%DAzhacfXTXLf)0GO7D z2#ZeK=Rv`tQzR+`)v558$D~HIz@B}2!F5?qIY&dKT6D#%)hLCMYBo`sOM<4oBSAKY zz5Bp;&q(4v$lE?)v#q1uwk<}T!bxr_sqqu=@fx52oXUE_`uY`CdHbh~KQ zePK5#x@Ht=il;r5ZB%%g>zch_Py0_BEfl5P2o#~ zQ;C^T)kb~rP6n`|;8sDAf%!+~=eMPPhK|?jwAJcqzHqB<5*#7@Q2r5)sj}Bo%+_A! z26fM0oFq^WNaptLjZ$7y$sre3R5FU2-#oz6^ZcQj;cq;AqQg%i6ojPoh_Zc5Mvhd@ zU~x7k)W$(M8poDHb~luqjbcin<%83tMC=JFF9xDJLQ`OgshEk+JU+$`#Wjm{g9ZoJ>GHA+iQg zb2M10gLY2tpGb`8GYr`(fNnwO=>Q^TB;@86``27!_K6xYr>3qIrj;ZlTVVK%7V1$X2OaQQ5t-YbRAn z`-M?WzZ{PdB!G@fS*M8oSK%MUfu?aW8W;`rCS}fL z^^VcBU4v8h##~C>WWDB+-KLhe;}2MbRk5TWMxz{S`^845v|XlbXJ;#HilJ+iYiD~;Sos>N-D-Wt;Y5)wm3ZUISm`J+Zbt^3agI>djz;0uJ9fkN zpK@52)XW;)oHQ8WMP)?j68`|+E7FX-n?A5Cz!E_b^ga7-x7&TL`5L?A_v#4_5|OFh z8k|Hv=Od7cuFZB?XzX(B2-IlZr70Q&mytoC{$vMHsqX3{-shjzK7+Suw&cB*<+j+M zq5)qWsRKMHD%`ncAcKh9QL+86-Zt81$ZgBfobpp!hG}OgaQdbAQ6$wMbEFx=OlhPe zmuDC3l8Ge^a0Ul<1}7&mJ!Z50(fUH$@j9a^=~U`PMK-EGDe0dz7!s+R>DD!*5JBEO zI>q*1s`fG6!Ry|S4 z!5M<8z!9K}ZMaeFQX!s5>lz7&mzm`Yz&X@KMv}aWZNcjbg*`d*Px~VNvFc?@#K90f zdAOSx*XbPBV%GGk?b`CMv2Gtt5(iDH7Eu-AgB3IzcooB-Scddj;55Q*OFang0O2(kpMK24ZqR%w}*k z1`VO1mK=F>mK{^mlv8E|^y?AFlShE>v>VM8?q)kX zv+6uYl^1IyRL_(6v1p}^?nvp@52XwoMc-x@6|H1j%28`K6Ez&G;VL+~6@GE6^OI@@$ITMgXE<3>Ko^X3@jqIxMqoqZw zvu`utm)g-&ML3?ZJv(~@5z|N|is56dBaxNSvskPqM4_Rg&{dUsC~0!z7cW z8hL5y7LB#t8!D$*$vL`D?l(TjDf~JEHhrk5 z@56^y-BWf_Co!!Y;PZQdm8HQL5yAG+aov{I(wbg2 zkDB$7mR&6!z}P#d_axG9w?OZJ6S`oYqu0MzsO!TOCe z3U=XP*|%k`{k?UJiU81*lmb0Gf^7u4K(lU%Nf^!}i+dWjyHifBXbN~vmil4?#XQ(P zk4+#P@-b3SoXvyl6n|=Mj@CAeokH1`=Pg?#u2J!PHB}u9TJ5JYAv}{5!98^838&PU z`AYh$C12W8wofcZ_OE1MlNSt`qv0#U_|esB7BOI?+^D{kDJ0;6G{k0~$mh}* zf=+<`kl?cz-XKP^b1|Z+5Uxgt5H3%w7bw8x6`Q}_FIPn+mhyaq>n4Vo@GPRgYCdXKs7`5+sFv7iD0#FFo5dkMBSY=Qta8XEj zs)$Am+MJ$IlBS%Ym9~afNYBfQ0M!=FBQ$VimqzDs(WNTYqLM*GIGs zh{-0-SaDRTQdgVIJ!5K%=c5vC9DIZ{pkPXJdPmRcF|)SP%Iv!B#U`dMoj|#!Orx%6 z@M9urhB8miHan-DBI&X3Yx>o%Ms2d{-3dThs+^BrCGe5?#+5hPgS-1d7#qC0Ma$Z@ zmYthQX}9f{-l6i2KuOa;xBmc6Je6A~cXJ<b%wAY(d=f*@YI`f6(N)8SqpWGI$KwWhTlNETB*~fs;4;d(o(+;E5fmfEoEmYrSf- zQs{19Gg$c?NLa*?KBf?g)W&QK^NMcDJ=JhBd3>)>dAYz@CDP13eTk*cdP6V{Gl=Py zg=VlU#*{jReM#w!O0&}%AB73(1mFT;aa8B8>l`C&qQ1V@+sd6qXRO^O6)2!|k~1`& z;B%%Sy%i}y);^=Ns!3LC_K#*yaQ0nOF_5X<=lMov(^`50!K&yeql7Wm7>bAk0OAo%MFf)^T1LuUmy!4X02WT&Qd7VQ!zyi8 zgr9JZ?4w-3=87U3pR$!3Z}u$cTvN)%qQT;cQtIJ6EjnL?7Fu4@XJW1-n3-mmy)Jaj zDXk205y(BPb~kctciGCHV#!re-u-PZ+;QPSH0#ATujW@6?j7A=svr|ebk32{zuCQN z?Crf6+_?UpZj#;~;=-_^S+y|l^d_Ny)v(7$DPl&R^( z^@~Q$)O1l2FFu1&lhPLM%sNLUv_&=R$s~GsDRNs_==B8yB4bEu405tXCG zH&xLkxI^a}%aQ>-L>Vlz6ZcQ)6^fRw^f0cmlgc1_8n7-9ao`NZvi;%piCIaeu;YO& z+K~;zKrl!n>LW3PzR=)IhLH_=i7qp|GxdlFIXXdz_F(B;m`gmf0CFNcl5v=MYbz=% zBD;a%@wE_+s<9NAzJ@Ng1*a>CcZlg9SXrBFv25n)v#wAlSL|sgPgewR(T*KhtF1L| zY#ygD%6caZoQz}EI_;J1U9oxSNz*5*FOr5hYPW^6BB@h&W1m9+OyGb(KeQm)_Qb8t zt6R=?mqV+r-lI}1;!3+jQfW~VZ2C^vIPeR(a+WVnNe$dT-!&Ww@RVZ7!`a=Pn2n}yx zOUj{JtZfebzgi~tqQ4R9V?i~P_-1B1{ zV)*|6+Fxv2TU|!dS{xN=DgOXd10`-WO;M9~82qY)>L68V9ja~o^@^(vy(eu{rnm0LC@A4o zv{@x_gy6KFf;q;OfB?ig+N~zvz4m(}=8i&ZDdMwHBdksRod-w=9eKqYVp~Udv#Q(O zoZPg9XHvMIXJuD-zZE$@6;JUZ0#8#0gpNM+S`V|`(J|hZ`geoN#fS^td6%2K$YjoT`%kTs4%LK+mUGv&&kS0BId=tz4yC&uQ||W#5rR z{8YkxJ`@E}B4RgVd;_i`mvYlv?Aq~`tp1*x#2lPve}xd#vmpl^BOQwxf@7(s@q;F+ zBHCh{oGtWzP&aBLyAUeyC^t!pRk?h(xhl>n3?y)z$)6TwQou0Amdq2*1X-^aBp==h zq~EkldY~xvBvjz2nw(V*iT-d)rgDx)_l21|-1@~*wRl^Vd-jmRf)Y-4tMOM-PO<3{ zQbcAm9SG73!6TG)wlun8w)!t+M0hLlbd7iCmV6V;K=sNe^eLDR+Bl!LRTahiVKlbs z%@f>N+C{>Ec~HiPp+UzIVsZwbI90PrbeK#!9&oGJ4#ID3Q>s;xzZ1qS(Ed`fWUSV= zw`Apklk|nPCUftd4>KPx`*v)~y|aCzn%jWsR#gW|&h1=yBhoB;Kdm8nA`_5+WWXM< zI0PPDW0zT!ie=w+H>DAk#%pfm2=Oe5& zWXuIZSxZkt6Iw`$f}O895}1}(xDaCc5h>}Wkz{tfujCCS#$|}6crz1Gi)PMpsL9X% zaaOMxg-%I#j)pWY_0&emtc!_8IbsX00q)sw2PoQINQsN%h}3QZul;sqX~ki1gv z!ezInJhU-(vTK5hGGpysrTZ?nyODKQU=yaUnW)1Hpq?3J45m6x%+qU_eGYtCc3+O0J=w@u|>m7cleKN77r&?6%a;l`5 z;nYI8@l%7UG~MjYpQIWkGR=TG`b4$LF3v0)NbNq0d?>+>WLUIG6Xh!b>oMIhZ~zSB zq!qK>uh|=1v1yfyjDb*K^8%yz&^<<&LGJbRjXm+5F&Bq-3)$+Sjcp#$N+XNJ9$abe z>L=U$ zz?6DcGXOQ^0-7#+#6=OF$7c3b+Vh>FRcm|p?3cxVzFzFc4oD#^1CHD;+bfY zSyV##q?DZKBO{oPq-i@>XSN-f)95cJO|3OIYEGMJ)8VL);;GaA`9V&Q3kg62K?me+ z=z2#sxHe<6w04rQdd<783f;n@KlNZQcMxeCuXC+Kv@V4^cfLC{HdS1G zmy7sN!ktmT!5^$C-Xd;&VfN1MYSm_>yN_rJAPS>c3a+&=KMGIqqbI%j!D6UD#XXW4I_na=)>0wu z`1XZIY#-DcB$IVj!po`2C|I61{{T3yr%xht^@>$$+NV&b_oG#la>AeoWLX2B6pbK? zpup484n>KSWSEy@wTI0U?A2taO+-qmt;HPk$|9!gq4m}X6`~FfVtc0G?T!UEA$d;3A5vwQH;s;vAs2yt2vmzJ~}Phw>_C#H}j#DGR%3)|Xu&$}%o?FYLxs`kf9 zW#vUAycCg%CZK{bld0#JUq{YPe|SYix2rcD(?-1Q%1WZ1{Dw_)5|$FAl*vyvvg%A& z>1JGNM14B?qJ;s2OF0(+uOJ*mbJhcR4CJZ?p0T|6G@=YHz3bMyT32bf5KnPW32roH z3etvs**bE>D5FWt332&FBVhjau z_Y6tx;j+7G=GhyRE@s(8^ zaYSoo)q6~%bb&5(0P=&|u2Pe99%3$@z}6+HdEc*)z9{H9ZYi8i)p|iUoz~`**aQ_a zoa0D<(Y47jSyskzQrm4}%C~9d7R%KZ>}5ng968yo*Sl_UC!btvtV(Fxqa;J!u-MeA z5rqPd&2-n9+UqK#vka_Ds%pJ{V?5Z$sfETMc1vexZ=?o=mX&3@SugV#0-)$Q$ zza*`u@|aX&!^3G-SrOieYPA&xF*c`|5MJoUOuYV3J;}05TWfndUWGxaB>tYT;-Uh) zwSa`g9q53PPBYdxkF}MG>txpIHdf55&QNgaWS1=&d?;s2B5%Ee^^DBJf!;73pSKOS zY?oke*Sni6{hRf|Y#qGwo9W6lsnaByY|4K~j%t8IyO9a@CwyH<-ZaYV>!r(jPiI+r zk_dU9Sk;X$BOAZ04ezs@Vmn^PHo*I6)i*L)m%UGMGDAMthYB~InSsg;6@o`7?$=eE zt@E>~Et{C8;m2o7#D(0Z{Nq^S7QeAP*6r%z?oR04;vWbD!^9d?$iW$c<>Wq*ci1M( zFKvkJMxlH(x|VdcTe$6MhImjFPrLvU{*jpH+eh09TP?h*bcY0{y0fjoBg;`PENLx7 z=r#I424W6D>jr-jT6LM`t5WOLO5DOu&dDkM8mbN|u*O}&2Pl+R^WEL~bBb-Pu?Jgk zudusTxzm-sJu^SM^M!j?<3zPuNZs!K&|kTU8{eFBi-Dflt?QBHE$z_Z6q0-7E_jHn zAz&vs-s|fD9S$P-CGO?KfqAV2^EeY8_pCJ!h!D&fdJ*|YPT5}8E&JKZ3>(=E+tnmI zBJm*!)k=9j@`oOVG7P!Yh_~$x-NgP`=xWk}jS3zD$EkuTboovu&bj3RRq^kD2g(vt zY)ji`wygn<&?tzq59*4zO-?5fB$I+Fj8jr+igRZY#P=#hQ^5le?`o2-JvBAjOTwI- zg;DDYX_JH|B4hf%Zw4hAYaH6w+igPfs{a5ARa>@ECXRbLvty8hCf%14f^~x^nuDK6 z?)FV4ipe)KvZtbwN}TT$xy1DqG5`mpOE&gTIOH2bv0Cj``u7qIM*^OzO0M$}s%mg# z6BEyrFM5&BD1CLSXHxBzZ7NYoS7@cfSu~N-GB(%I|REMJh?TDgG=drqx9GOv}>{L&-=R zu`bnVuP%!@P~8NSS0O={=Qv$~a5-ft+GH!1N>pPWN^)X5;{Us&~eQU;R# z(Ma~ep|`a5@l}5-KkH19b)fXp4zQ}b$#;+HV_GOVdd*BkD=63s%Uqle5%aFBQLtx~3{sDNNdd%tLAw!6i0+ z@E@Ff`+aOOuX0`v-rHy9AEy=m1;AI@6}RC`XhwlRrOUb!h*n8Ig}sDC#=>90$hBff$g_ydo1t|I%BZN}<21BJ7}CVj>o@NL3JIIMKh7^V6xOcGHe|xBOR`j`F4givYLZERSsqpl zF!!{%AQ2IncSf@EivufHWE4vg?%K9|kYehbrsJAgi+M_`1DW!7N#_L7>i}sm{bJQ> zdqmLXwbP!pYt|XOO+5_0B5OeALT1Q=^POUWv<u5j4M@6VqSFWjON$piNRAbsX4k}($Fs9Y_2?Xj!nK8fdrUvij6n5-x zXB4Lu9}eJXP)WnbZ1wDgSj|4%nqf5g&s`%q&c3h^x2S|?wmAJENq9jc2SXdtgvX(d z$+C(&6mG|tEe79_gEiOk{whmBwSq*OvrUtT+O$YI97WMRr`u~@M$4=CYp23gDzBFl zTW@9w?}4W%5>jTZ44jA$X!}cjw2EZAKeDMRD&;A=Gpd3fB4P`bE*UB*Hkil;EEhDA znsC-7+5=bZc61U(MI63tmwSiwiu1YnOKG4c6+Qc+IKIzqmhPyEUzD11fpb#+l4=I2 z7$C1OoF-3A3>QSu9QsGp_8#=q*2Yv-2q>OU5(ua$d1e?Kb&7V_A1$&;o!>Ni4<88O z+Hnid6a>uw07zc-AbMsgc8dz_Ogz2n$s{Cw-$^b;B4*$!LU}rKF%P;9Gpt`&*i5b} zQV32KZ6_Ovh$?yUDFa-HE{<>xPwNQwpL*MSHKD0&F5h}i2Y_+qeBo6pmokcPXRLYd z58eHtO|f(^aYbh{cbq`6)EI3ud=r^qx?d>h_PXoLgPb#;4T4->1_zjAfeR|x-q+SN zzE?uEXuD>C;`n7X{!yZI@)QL6!aC5;=^rg@_S#Eh4lB1Lw5JIq@~V=hbq|`1U5!*z zs8WDIAVM)jpE<#SHh=8BCT6Ft(+dQ!Bmu8_auqh_VRKmPnm84 zim&l_uys0Z*>##AxD-C>(DL+&Hl1T%J42v7VRX zsIa#$D{=CDrBbU^lK90airJWq>l)K&#D8Ww$FU8yYg~TLbh^<+RURaV4^=bb^NQv0 z@nTf?DJ)`tCpVNprZ$hsPp-##+2%eq?u;N=NpNz0N(xLmvsA6UfT?-DNnc&b6J+- zYLnJHWOPL+m)x>X-oVqGMswFN-c7h{%WpK=eY0%83|zZo#d@M%9|>>5jY?EGH8N^G zP{xhAeIn&$?B`_eZA*cp<_4oOXz$HalACpgR%Z=E8~?A~cxM5w-?+xI-L*uG1&yDV?e}jgWoF`?Baae85mf2&2|*K#n3la?C%Y*9BY;b?IqoWrQkP#)((8&b z;!quhxI>DUD1=Fqx=sn@tV9zt54q3f7J4OK!M@U_TOQK1wUfE1DERdfmQr+=M5EOy zrKA~UQ0ty>rr@_{2Y5<-c}FZR9Zz~zD7!4Zo!ivpmfYb;m)U9yXT%@$q2!fuNYY8P zBcu*0a{+=5pD6Bh>MbMP=x-&H!Ivk3Jp>XZqRcX7=kklizO;lL2k8y=1#&-lYZMpA z$`ncJib}B<%r31NMhNO573dE3gRe+CYqn$8EZtR@Fiv+0wBcqVqRs@s6V@l8(Ln%{ z`NhX%_EH-z*~?0KZE)OV zbJjTV^!s6LN{`S^b+~uIhPjv2M^v@eRcb7Xly@dZ4P~e~*GNTKIO`k(+E%@Jw7VV)b+TnO z83yhGjrg7xVmdsa^XI)0(RYd0F=uD6sx1rnTWCy@b0ql+s+5Pr<3Uv_xjV_}=?=07 zSnPB~xKzp3{6uwuyMM|dtbj%_6uOMgE%h!6i{+Foz)ElgNGd{XN(3zTFefHHSlWi! zC%&#JDe|>)oiWi_5YrzQ@nOv=JV}yraSQ~KWA2aAKDXKQjhO6;fZS8OPj@6Tpoo;w zQ;ju`5Co@pO(8?8`rEPF1+FCcV7Mue28%%gS*H85boGjq^ipRh=M{NCxT{PZTeiOq zy;WW+I8@vN@+Hs>(4~2^00iWjdF9VB=T@)3hc* zUE`i{^9QmL_2yewtJ-z@XtZ6(9Bj?c#W2?AsskV(^os-faY8@@UA?{b3gv4dh23vA zF6F08uWVpv<_tw`)quz|VhCcivW`)A_6fI5f$aFvwN+WdiYwYuDs&!@1<3UmQyHWh z#+4UfXkgp;TXp@fvRShawj_6)tdZoGI2M$G&LlGL;6Mi_tX?Fd(JtC#)Qaq?xL~rW z;W8mXGs!-6(8QvOawg1GJ+1a3J?})N)9s6SIo-5ZC@YUCIB1>BK*98lt1{pL9H-g) z*(#N@ircyFcM>~z@l;A<@S`(a^2{(L9H6Q-9PZ~mBj{>FTSsOUiiI9_{6PL*)Odme zB+sbRSYI|w#AKagbjkDzyfd z!Zqr1*Da~Z5j! zFE$CJx=&_FHIW`>ePc?*z|1!Z#v|2$3Dk9m8)B?in6h$d>*%5>rSy+c#HL}NSkZTc zV*)xQCZ@Z6o3}yZbk$aNV>tOi4n}7uC!7$)?qwkQMJC#Q&bM#Q`eZma+h zS+NMF-rqd=#~RvAo3wg8=;G(4w@k4}BvIl0BSurFG=@{o8A;MQ#?L*WtM{ahsI}Sw zZtWzuJ7?m@l|orEMEM?&&a_78*Q7bx75@Nj+jMmvUUh!ziS}?m76yEr(-0F76DZ=g zRrN}=Zy75|B;{s~)!bjgw$yqy3_2o{{U!R+K8&EAA}&AW={@jur$m%qA?f*j*;{e$r!InlA4lWBoqB0 zN9=JiGaj*;%Rmlu5w%K6Wh^&IOh`vq^ClS_pizQ3#V+r-6qz~cH1ry&I)}tfb-AS) zOHaYxBtq_(kZuo&n*@$=bDpiB%{?EG^au%dZ;Ae2tl<=UafYj-i2+-nVdaGJa`>71iH;PPKF^Y zNaiv5MAp5}aM}{Iwtt5Aq~dVuDuLx5ku=(j??yWq^&g~IYm6BqH0~;mJ3OPrB=sE( zXgTQ`jnVgU`9~+%b@{WMs%=)_e`K{wG^ZVv%fLL-2UPcjgF5Cl-6xofe%2qdtA>;Z z)CDSS)OW&DhXYDT1c|X86k(oX73_WOdW$V`%DZh>1xm+AC zG@WA$jEv*4Z)JFyKQ#Y9rhZFw*8aMZ8#$lBo%fUS&#qAYLex07J%Rz6%s5NA_0|WU`Orwx64I+!ZG5W{H zTRPb_M(nq1HB{=nZpe=nRFD|)mHb$ooJ5rhegVW;c15yl{#vTcsFr0lX72GKlPr9b z_^>4P=Y#tu2BhgM!1@^aSK2zqeSCX6)~Hm53HF0R;S7EuN+6P@FrQF$Fl~dR$3DGd zaxEVIiOu|04*=*0NyF6Op zUV;&H)i1U1&odfLJ`N#h6616c98RUS8Vk*_uz7ZD_ufb_c()mum(BUWl^TJ@1Tdpn zWcR-~J8D}^p=~++HrchQN+sEUt+r9053_ijqB+zDLC?|+G%+rOfekMmgIT*$+1p!o zwMdqSR8NGMbHm1BMh}G2Zjpn_F@r{s0z|?%ZD(Y+R?IGc;aWR+m39%~GjvCWuNE{i ziDt%`gcEZ)^^Di8I?Z~t-KFJjs{W-!9y1`9#)(Zh_2@Z7m_CrMYjy5V{{W*0T;N@Q zx_?-Th;-*2!)7}`MaI^j+BF6WCe1O$8ThM1g_7_$$2c(Vo_L2|&{gIC0ECrpg591) z7E2$^)+4m!1x%5iakWEp8e%$kYI=5Lg4Fa#nKmf`yyKRC>_JWd;vAm5qe^^p9hW0r zwXD@ry%gl@aI&p54ZS7r_G8)0|Jqs8n#A}7?uDep->Jz#o# zx$7L=g)rNpe{hWAxQQ3?`yuNb!A{ zNCWhWqxKVV2D)Y_Z>-7%J8hEPYJi)UEVyW@tWRZ`kxYrXW-O8%N-%nQ$4^0Uy)s3m zah1HiAbR#fnEAl9V>hXQFCN;`fX!4~P6|tS+$5ojcq5lc9*Rjin5t2%r?jQqTsI{_ zH;$Ys!)N@c3aL28B^U#oH*@`1{UPcc12pTbkBkV1HObz3WAxk3hr3fo>ERt$0w*LSTFGxhmDT;&)^MO6`D<^hdo{&b* zYb#fr)!fb`Q3`sQMSsRl8C1Kt&!lQ-#0=!cvuXD=gS1;bQEdBR+c$Hihc4aE5X({^ zjKGXp5Oq9^alMgj0^jy_yQ;NoY083+a~?9_k1c2}YS^A!P0|YYpc-IDNPN96jIs@b z9wh$&eg!0+v8Xc>&Kg=(DrLgswmo9xHk-uYlwd9Cgu`C36=Y43p@d%2^3p4tHf=7) zmQjVwwM21KNA7U`FaH3C58rn{-o`N!r;rAHA@0s;wW;j{DbE$1H;$2!GMtB}{_zs^ z30w`(Aelg#LytoR)u|OG)H;JE(oZt&RN=ed_-cCokP_7XG~3yV)h3R3gv@`n);Rvi zX!m75X|)FxZv5rPj)I<$X~2*VmXO)vLUG+Zhe+$!W3}0~ozCc2hK``bAQE6(e&7I* zW97ZPY=)~(*=^131GCMcD@$znsI^Xvkl}e>{{Ye_l#GdH5iLRRCm_c#_IqZd2Z> z6O~=e1EP@;n3I@-S~SBGYo@W!cH3szGz*G_RH{B@EkV-dyFJDDYh^ehQJnzO=?`i5 zWR3AG*p4MxxpslG%enO?^lA3gQb|OfaJ5k{g%!J!S>&zmogjO$^sjumzeuXz-qia? zTDaY?QdyfLHxQ(xzHBx3eB=#2u%CWm{j>VVOZH~l4R38#hxX0t5?w@)-)4_z^1nEd zD}HId@%f0JUiTv%exFmetCJ|B6z@D>ebqba3mZje`tZ#r=}Ccx^)mmXdLp6$4j|s?X23X!8a8)!0#vO zAbFej!1ajO%ZW~%Bjl@k{{XFB`&mofi>oA_DM6a2Q-cRGKqi6Tm!~)qnN^q)2tS;C z4^FIAQ1@~bIcIr0pO=*jsFLK(15_UpbRA(QwFSzB4gDz@JU5DXXsApwqRGG~9J;|2 zd5-YR-@Hxi(ObN$6l$GPw)9SlZizt*=Z0b{m`mFv-2BWQzr) zsGo%KI9SOMBDoUln3CFQ!cfhfGnn?pYBcv%Dz(2%UnMic8vXI>8(gQm4xc=gB==?4 zPLTer#;WCmnk_L-8-+$wo)=O`$t1!?H6HPl^)XbaZ7Qg}%}TNB4pWsWl;B{FO8nrS z%5|6+VeW87_sT7{g+1+7pyBO(^ySiMaGCIYwBk&UQ5w>Q4=8zF6*?$QR~^B@-^zay zAbE}KxgvSgiNyTkE3MHc)x^>O^i00R(RIKbWX=?zwGQl``As8e6? zT&$i^P(d{EH*#PKK7Y0Q!u_1RyB=F_9^94H7kyGyZ+S1r^I|HMOA`PD3tP;mBi1?9 z?RQiXMy6=g*8--RoG#c0!-FIsfs>>R(x*D|nNOr!wqtZJb=e_G*)zCV9C3beBo9ZU zbC}01_JOxvGuisId#>elD9Fr`wM4+tRAXnyTm!6ap7t}=IHeb3_cqnGii_=(S5skZ zTgjx^x{Q1-)f<{%5@v2@9ZCiUgOq(HHiv3j2?{Me#O7J)+NCMSc~4| zoMJgww{FfE-p;Le>RslLt4gQY-Gc{GW&jX>c#ZWwbVl^EeBnK7XZ3f~*GSc-6>5a+ zk_?`^am^&6y>cW?XdZt!iHpgeoKH6>;TvGKUsIK%F>JxBWvU2a6<1T7G%qH^qj#ha zSXEymL=K8VgRNx^R6uK^APoQcOO+U0#+g{JZOI!9iE( zqV$Ci#a0tlH>I1q)(AB%PkJBA?H^p0Q7q{<-UD9uSddCFsEV|tf-ri-_MN=FuU9IN zbXStmW}a>NaSp`ibDv1OS+^Yb1+3xf)Naz+N1PRtROSPmc3JT(*f`P;qf05Hl0b{- zwDx^cx9SyoZK}~}-BI{Srm|Q$h>cNA;VGZ4uni>t07_#qNwO}sa#Pvc4;VUb@e|^r zxP|IdrZXAykbNMku$1%>TH5r_8`h+7t1q)Aj(E^gI5OZE){D*orVxYP&@b1{v39CXzsya)4Bn4Cx<0+jQoN)r!Op8e_sULhF0_srAON zGQ&fpabIgYE$z>DG-=110Oc+m8p?4hvq02hPIZdDz?@uGL4MxVeyWM4?}bxMBW+k4jD zl&w}>a+=Mh^!Y%QN^H|;V-x~SN`2ySlgnOZjwqUDI zFod|ch3sg3Yp+f>;qO)rv~uG+1`B*ef<5R)G`HmEQL202C6nzJTt z7YxAMMDl=U0|!o!s=Pi?TAHCvN>^_T!-_)O6o`mh5@yzJuq`NPbm;-uOq?>=^G9JU zPNK$q`a?$8z}6Tt1Kmm-bc8 zf4v;@*+QP{W4_N5T=!FXQk_o!03A=4{*cM>Gc}hUk!Ox8WTi@|?O<&(y?CgSRVvcc ztj$BBDCPsH9_}&HF*hUhkF}_ly`fOIXK_wqnut{;;_*Fyn+nX+Z{U~*`(K=CvRh?^ z68f6WX8!=b`6EAwzm*M%$j&-JKn!OB6>W~vWpk-bbm0!roi4DFh6M!5NX{XI-|(}a zNG{;Fn7)=wBOnPO!$t(ans7sz@$@9 zkjM_1hBu(Zx(<=Au|=s(s^3m7S@^RtXwQhMsG;EJjSwSC-kW=-AypX6GC@3|+wFS6 zwGpdpqK=0VW}vmm^noh$%n)%Kl5%yAj}*A6#Yu^*InGXe2-s7OIT#8)@VmhNI0FM1 zh9mAndS5TfIv&fJGxsXvvL%i;;fMuNeR@NBAN(4Bp^HTdSwo{J10IkHKYA0;zvEN= zOmlsxODwxhXS*mG^bpyQ1p|==Jmx;JQQIHh6oUCPyP}4MilGyhr2b_&1Esv z@Ke?Upm{TWU}d=&Q*}!$*XkS6gW;ZHCPl1xUXw&b0aoByDfHtb&jW{W3`NU2+!=_rMbLkf= z&;eOQ0oVN_RKL~{R6g;IZ=G1X2mb)N6^k6-a6~PmkL-8@vF5;!`Nd#oK728w0q*(q z=@mK<2K=l_MuKGUBWL=!8Hi}#*QWZ%&{rI?jhQ@@N-^0^n2bLIv&*C-bV;hqll`bx z-8nzqi(cUVs-I7sEy>^=dPS*k_++0!46SerhS?osN)aV_vUNdEu^ zGh6<&AR7Mw-il+1rZ!4M%zTenCSU5($EY8AESm)b_%(e$=N10|D4A|heNUt}wKa0M zKi+^>=K)rL13>`o4VytyqhYFJFI43qfgmbRSek?Yv>O0EDTd4-)BgYrFop{{{Wmpgr}S?~VEg_GKCxqumMGuwe{{SMF`of1=C~@lmBln=Xmv?P#jJkhD9#GYf-Gfo&A;oA9aJbW~ zM^XO(&KNw>isK%F6fLTV=h7Fa{boq1Q2zkqW9u9X+VLcY$*LGmU-+V5*^4TkU+E7n z@4NXxe!{O_C9%Ds1f8oc88yc0gnU?GN!2;C=pj8Q3>`WcvU^NxvqDb2)u39K8@!-t Xxu2|jcAS!M Date: Fri, 24 Jan 2025 19:22:56 +0100 Subject: [PATCH 046/174] colour: use suggested rendering intent as fallback (#4347) When the requested rendering intent is not supported by the profile, fallback to the profile's suggested intent. An error will only be raised if the suggested intent is also unsupported. Resolves: #3475. --- ChangeLog | 1 + libvips/colour/icc_transform.c | 38 ++++++++++++++++++++++---------- libvips/include/vips/colour.h | 2 ++ test/test-suite/test_resample.py | 2 +- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index f6ec1fb46b..0383a9c26c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,7 @@ - gifsave: add support for eval callback, ensure correct return code [lovell] - tiffsave: honor disc threshold during pyramid save [kleisauke] - fill_nearest: fix a leak +- colour: use suggested rendering intent as fallback [kleisauke] 10/10/24 8.16.0 diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 28ef2eae8d..d8263642bb 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -159,6 +159,8 @@ typedef struct _VipsIcc { int depth; gboolean black_point_compensation; + VipsIntent selected_intent; + VipsBlob *in_blob; cmsHPROFILE in_profile; VipsBlob *out_blob; @@ -446,7 +448,7 @@ vips_icc_build(VipsObject *object) if (!(icc->trans = cmsCreateTransform( icc->in_profile, icc->in_icc_format, icc->out_profile, icc->out_icc_format, - icc->intent, flags))) + icc->selected_intent, flags))) return -1; if (VIPS_OBJECT_CLASS(vips_icc_parent_class)->build(object)) @@ -596,8 +598,8 @@ vips_image_is_profile_compatible(VipsImage *image, int profile_bands) * Don't set any errors since this is used to test compatibility. */ static cmsHPROFILE -vips_icc_load_profile_blob(VipsBlob *blob, - VipsImage *image, VipsIntent intent, int direction) +vips_icc_load_profile_blob(VipsIcc *icc, VipsBlob *blob, + VipsImage *image, int direction) { const void *data; size_t size; @@ -607,7 +609,7 @@ vips_icc_load_profile_blob(VipsBlob *blob, #ifdef DEBUG printf("loading %s profile, intent %s, from blob %p\n", direction == LCMS_USED_AS_INPUT ? _("input") : _("output"), - vips_enum_nick(VIPS_TYPE_INTENT, intent), + vips_enum_nick(VIPS_TYPE_INTENT, icc->intent), blob); #endif /*DEBUG*/ @@ -617,6 +619,18 @@ vips_icc_load_profile_blob(VipsBlob *blob, return NULL; } + icc->selected_intent = icc->intent; + if (!cmsIsIntentSupported(profile, icc->intent, direction)) { + icc->selected_intent = (VipsIntent) cmsGetHeaderRenderingIntent( + profile); + + g_warning(_("fallback to suggested %s intent, as profile " + "does not support %s %s intent"), + vips_enum_nick(VIPS_TYPE_INTENT, icc->selected_intent), + vips_enum_nick(VIPS_TYPE_INTENT, icc->intent), + direction == LCMS_USED_AS_INPUT ? _("input") : _("output")); + } + #ifdef DEBUG vips_icc_print_profile("loaded from blob to make", profile); #endif /*DEBUG*/ @@ -634,10 +648,10 @@ vips_icc_load_profile_blob(VipsBlob *blob, return NULL; } - if (!cmsIsIntentSupported(profile, intent, direction)) { + if (!cmsIsIntentSupported(profile, icc->selected_intent, direction)) { VIPS_FREEF(cmsCloseProfile, profile); g_warning(_("profile does not support %s %s intent"), - vips_enum_nick(VIPS_TYPE_INTENT, intent), + vips_enum_nick(VIPS_TYPE_INTENT, icc->selected_intent), direction == LCMS_USED_AS_INPUT ? _("input") : _("output")); return NULL; } @@ -654,8 +668,8 @@ vips_icc_verify_blob(VipsIcc *icc, VipsBlob **blob) { if (*blob) { VipsColourCode *code = (VipsColourCode *) icc; - cmsHPROFILE profile = vips_icc_load_profile_blob(*blob, - code->in, icc->intent, LCMS_USED_AS_INPUT); + cmsHPROFILE profile = vips_icc_load_profile_blob(icc, *blob, + code->in, LCMS_USED_AS_INPUT); if (!profile) { vips_area_unref((VipsArea *) *blob); @@ -1024,8 +1038,8 @@ vips_icc_export_build(VipsObject *object) } if (icc->out_blob && - !(icc->out_profile = vips_icc_load_profile_blob(icc->out_blob, - NULL, icc->intent, LCMS_USED_AS_OUTPUT))) { + !(icc->out_profile = vips_icc_load_profile_blob(icc, icc->out_blob, + NULL, LCMS_USED_AS_OUTPUT))) { vips_error(class->nickname, "%s", _("no output profile")); return -1; } @@ -1188,8 +1202,8 @@ vips_icc_transform_build(VipsObject *object) } if (icc->out_blob) - icc->out_profile = vips_icc_load_profile_blob(icc->out_blob, - NULL, icc->intent, LCMS_USED_AS_OUTPUT); + icc->out_profile = vips_icc_load_profile_blob(icc, icc->out_blob, + NULL, LCMS_USED_AS_OUTPUT); if (!icc->out_profile) { vips_error(class->nickname, "%s", _("no output profile")); diff --git a/libvips/include/vips/colour.h b/libvips/include/vips/colour.h index 895f25e1dd..ed52ccfe56 100644 --- a/libvips/include/vips/colour.h +++ b/libvips/include/vips/colour.h @@ -93,6 +93,8 @@ extern "C" { #define VIPS_D3250_Y0 (100.0) #define VIPS_D3250_Z0 (45.8501) +/* Note: constants align with those defined in lcms2.h. + */ typedef enum { VIPS_INTENT_PERCEPTUAL = 0, VIPS_INTENT_RELATIVE, diff --git a/test/test-suite/test_resample.py b/test/test-suite/test_resample.py index 7bb65b2fc5..51b41072ab 100644 --- a/test/test-suite/test_resample.py +++ b/test/test-suite/test_resample.py @@ -239,7 +239,7 @@ def test_thumbnail(self): @pytest.mark.skipif(not pyvips.at_least_libvips(8, 5), reason="requires libvips >= 8.5") def test_thumbnail_icc(self): - im = pyvips.Image.thumbnail(JPEG_FILE_XYB, 442, export_profile="srgb", intent="perceptual") + im = pyvips.Image.thumbnail(JPEG_FILE_XYB, 442, export_profile="srgb") assert im.width == 290 assert im.height == 442 From dc21cfb06fa0cb4b1d942f4f40f8da64161d352e Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 26 Jan 2025 11:32:37 +0000 Subject: [PATCH 047/174] improve operation cache touch (#4359) On a operation cache hit, we were only touching the hit itself. As a result, after some operations on a loaded image, the image itself could be forced out by the operations that had been performed on it, even though the underlying image was still being used. This PR makes cache touches also update the timestamps on all upstream operations, since the upstream operations are also being used (indirectly). --- libvips/iofuncs/cache.c | 72 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 5 deletions(-) diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index 33df752c33..5a0f8bdca2 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -546,6 +546,11 @@ vips_object_unref_arg(VipsObject *object, g_object_get(G_OBJECT(object), g_param_spec_get_name(pspec), &value, NULL); + /* This operation is probably going, so we must wipe the operation + * pointer on the object. + */ + g_object_set_data(value, "libvips-operation", NULL); + /* Drop the ref we just got, then drop the ref we make when we * added to the cache. */ @@ -565,7 +570,7 @@ vips_cache_unref(VipsOperation *operation) #endif /*DEBUG*/ (void) vips_argument_map(VIPS_OBJECT(operation), - vips_object_unref_arg, NULL, NULL); + vips_object_unref_arg, operation, NULL); g_object_unref(operation); } @@ -607,6 +612,8 @@ vips_object_ref_arg(VipsObject *object, VipsArgumentInstance *argument_instance, void *a, void *b) { + VipsOperation *operation = VIPS_OPERATION(a); + if ((argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && (argument_class->flags & VIPS_ARGUMENT_OUTPUT) && argument_instance->assigned && @@ -617,18 +624,20 @@ vips_object_ref_arg(VipsObject *object, */ g_object_get(G_OBJECT(object), g_param_spec_get_name(pspec), &value, NULL); + + /* This object has been made by this operation. + */ + g_object_set_data(value, "libvips-operation", operation); } return NULL; } static void -vips_operation_touch(VipsOperation *operation) +vips_operation_touch_operation(VipsOperation *operation) { VipsOperationCacheEntry *entry = vips_cache_operation_get(operation); - vips_cache_time += 1; - /* Don't up the time for invalid items -- we want them to fall out of * cache. */ @@ -636,6 +645,58 @@ vips_operation_touch(VipsOperation *operation) entry->time = vips_cache_time; } +static void * +vips_image_touch_cb(VipsImage *image, void *a, void *b) +{ + VipsOperation *operation = + VIPS_OPERATION(g_object_get_data(G_OBJECT(image), "libvips-operation")); + + if (operation) + vips_operation_touch_operation(operation); + + return NULL; +} + +static void * +vips_object_touch_arg(VipsObject *object, + GParamSpec *pspec, + VipsArgumentClass *argument_class, + VipsArgumentInstance *argument_instance, + void *a, void *b) +{ + if ((argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && + (argument_class->flags & VIPS_ARGUMENT_INPUT) && + argument_instance->assigned && + g_type_is_a(G_PARAM_SPEC_VALUE_TYPE(pspec), VIPS_TYPE_IMAGE)) { + VipsImage *image; + + g_object_get(G_OBJECT(object), + g_param_spec_get_name(pspec), &image, NULL); + + (void) vips__link_map(image, TRUE, + (VipsSListMap2Fn) vips_image_touch_cb, NULL, NULL); + + VIPS_UNREF(image); + } + + return NULL; +} + +static void +vips_operation_touch(VipsOperation *operation) +{ + vips_cache_time += 1; + + /* Touch the operations on the upstream trees on all input images. + */ + (void) vips_argument_map(VIPS_OBJECT(operation), + vips_object_touch_arg, NULL, NULL); + + /* And this operation. + */ + vips_operation_touch_operation(operation); +} + /* Ref an operation for the cache. The operation itself, plus all the output * objects it makes. */ @@ -649,7 +710,8 @@ vips_cache_ref(VipsOperation *operation) g_object_ref(operation); (void) vips_argument_map(VIPS_OBJECT(operation), - vips_object_ref_arg, NULL, NULL); + vips_object_ref_arg, operation, NULL); + vips_operation_touch(operation); } From 962ea79c2767919cc0a7f8e0fbc996770dfd5f86 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 26 Jan 2025 12:33:41 +0100 Subject: [PATCH 048/174] Ensure `VIPS_ARG_*` defaults are in-sync with `_init()` (#4355) --- libvips/arithmetic/clamp.c | 2 +- libvips/arithmetic/hough_circle.c | 2 +- libvips/arithmetic/max.c | 2 +- libvips/arithmetic/min.c | 2 +- libvips/conversion/cache.c | 2 +- libvips/conversion/gamma.c | 2 +- libvips/conversion/msb.c | 2 +- libvips/foreign/csvload.c | 2 +- libvips/foreign/tiffsave.c | 2 +- libvips/mosaicing/match.c | 4 ++-- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libvips/arithmetic/clamp.c b/libvips/arithmetic/clamp.c index 5b53f75663..aab866e725 100644 --- a/libvips/arithmetic/clamp.c +++ b/libvips/arithmetic/clamp.c @@ -170,7 +170,7 @@ vips_clamp_class_init(VipsClampClass *class) _("Maximum value"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsClamp, max), - -INFINITY, INFINITY, 0.0); + -INFINITY, INFINITY, 1.0); } static void diff --git a/libvips/arithmetic/hough_circle.c b/libvips/arithmetic/hough_circle.c index 9bcbcfabb6..73032b355c 100644 --- a/libvips/arithmetic/hough_circle.c +++ b/libvips/arithmetic/hough_circle.c @@ -234,7 +234,7 @@ vips_hough_circle_class_init(VipsHoughClass *class) _("Scale down dimensions by this factor"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsHoughCircle, scale), - 1, 100000, 3); + 1, 100000, 1); VIPS_ARG_INT(class, "min_radius", 120, _("Min radius"), diff --git a/libvips/arithmetic/max.c b/libvips/arithmetic/max.c index ad27f45b60..cbf0e417fa 100644 --- a/libvips/arithmetic/max.c +++ b/libvips/arithmetic/max.c @@ -474,7 +474,7 @@ vips_max_class_init(VipsMaxClass *class) _("Number of maximum values to find"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsMax, size), - 1, 1000000, 10); + 1, 1000000, 1); VIPS_ARG_BOXED(class, "out_array", 6, _("Output array"), diff --git a/libvips/arithmetic/min.c b/libvips/arithmetic/min.c index 3b7800d453..27ccf194c0 100644 --- a/libvips/arithmetic/min.c +++ b/libvips/arithmetic/min.c @@ -474,7 +474,7 @@ vips_min_class_init(VipsMinClass *class) _("Number of minimum values to find"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsMin, size), - 1, 1000000, 10); + 1, 1000000, 1); VIPS_ARG_BOXED(class, "out_array", 6, _("Output array"), diff --git a/libvips/conversion/cache.c b/libvips/conversion/cache.c index f7e6b57012..6644411974 100644 --- a/libvips/conversion/cache.c +++ b/libvips/conversion/cache.c @@ -129,7 +129,7 @@ vips_cache_class_init(VipsCacheClass *class) _("Maximum number of tiles to cache"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsCache, max_tiles), - -1, 1000000, 1000); + -1, 1000000, 250); } static void diff --git a/libvips/conversion/gamma.c b/libvips/conversion/gamma.c index 92f8debd59..e709c54ac3 100644 --- a/libvips/conversion/gamma.c +++ b/libvips/conversion/gamma.c @@ -149,7 +149,7 @@ vips_gamma_class_init(VipsGammaClass *class) _("Gamma factor"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsGamma, exponent), - 0.000001, 1000.0, 2.4); + 0.000001, 1000.0, 1.0 / 2.4); } static void diff --git a/libvips/conversion/msb.c b/libvips/conversion/msb.c index f27bc7ef33..87046600ff 100644 --- a/libvips/conversion/msb.c +++ b/libvips/conversion/msb.c @@ -254,7 +254,7 @@ vips_msb_class_init(VipsMsbClass *class) _("Band to msb"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsMsb, band), - 0, 100000000, 0); + -1, 100000000, -1); } static void diff --git a/libvips/foreign/csvload.c b/libvips/foreign/csvload.c index bb344fb7f6..1615ad225c 100644 --- a/libvips/foreign/csvload.c +++ b/libvips/foreign/csvload.c @@ -500,7 +500,7 @@ vips_foreign_load_csv_class_init(VipsForeignLoadCsvClass *class) _("Read this many lines from the file"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsForeignLoadCsv, lines), - -1, 10000000, 0); + -1, 10000000, -1); VIPS_ARG_STRING(class, "whitespace", 22, _("Whitespace"), diff --git a/libvips/foreign/tiffsave.c b/libvips/foreign/tiffsave.c index 4075631861..6de1f84cb0 100644 --- a/libvips/foreign/tiffsave.c +++ b/libvips/foreign/tiffsave.c @@ -365,7 +365,7 @@ vips_foreign_save_tiff_class_init(VipsForeignSaveTiffClass *class) _("Deflate (1-9, default 6) or ZSTD (1-22, default 9) compression level"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsForeignSaveTiff, level), - 1, 22, 6); + 0, 22, 0); VIPS_ARG_BOOL(class, "lossless", 24, _("Lossless"), diff --git a/libvips/mosaicing/match.c b/libvips/mosaicing/match.c index 662046992e..dd5ca6d735 100644 --- a/libvips/mosaicing/match.c +++ b/libvips/mosaicing/match.c @@ -271,14 +271,14 @@ vips_match_class_init(VipsMatchClass *class) _("Half window size"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsMatch, hwindow), - 0, 1000000000, 1); + 0, 1000000000, 5); VIPS_ARG_INT(class, "harea", 14, _("harea"), _("Half area size"), VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsMatch, harea), - 0, 1000000000, 1); + 0, 1000000000, 15); VIPS_ARG_BOOL(class, "search", 15, _("Search"), From 9622ea2af98fc3f21483a9e548420f53a68a8a26 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 26 Jan 2025 23:33:30 +0100 Subject: [PATCH 049/174] Add missing FIXMEs (#4361) --- libvips/arithmetic/find_trim.c | 2 +- libvips/colour/icc_transform.c | 2 +- libvips/foreign/magick7load.c | 2 +- libvips/foreign/webpload.c | 2 +- libvips/resample/thumbnail.c | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libvips/arithmetic/find_trim.c b/libvips/arithmetic/find_trim.c index 892c93d507..ba86869f41 100644 --- a/libvips/arithmetic/find_trim.c +++ b/libvips/arithmetic/find_trim.c @@ -93,7 +93,7 @@ vips_find_trim_build(VipsObject *object) * for this interpretation. */ if (!vips_object_argument_isset(object, "background")) - find_trim->background = vips_array_double_newv(1, + find_trim->background = vips_array_double_newv(1, // FIXME: Invalidates operation cache vips_interpretation_max_alpha(find_trim->in->Type)); /* Flatten out alpha, if any. diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 6be79ab516..54047353a8 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -1000,7 +1000,7 @@ vips_icc_export_build(VipsObject *object) if (!vips_object_argument_isset(object, "pcs") && code->in && code->in->Type == VIPS_INTERPRETATION_XYZ) - icc->pcs = VIPS_PCS_XYZ; + icc->pcs = VIPS_PCS_XYZ; // FIXME: Invalidates operation cache if (icc->pcs == VIPS_PCS_LAB) { cmsCIExyY white; diff --git a/libvips/foreign/magick7load.c b/libvips/foreign/magick7load.c index 45d2819258..0dc7bd0716 100644 --- a/libvips/foreign/magick7load.c +++ b/libvips/foreign/magick7load.c @@ -310,7 +310,7 @@ vips_foreign_load_magick7_build(VipsObject *object) return -1; if (magick7->all_frames) - magick7->n = -1; + magick7->n = -1; // FIXME: Invalidates operation cache /* Canvas resolution for rendering vector formats like SVG. */ diff --git a/libvips/foreign/webpload.c b/libvips/foreign/webpload.c index 9438e44b9d..9a67a31545 100644 --- a/libvips/foreign/webpload.c +++ b/libvips/foreign/webpload.c @@ -104,7 +104,7 @@ vips_foreign_load_webp_build(VipsObject *object) if (!vips_object_argument_isset(VIPS_OBJECT(webp), "scale") && vips_object_argument_isset(VIPS_OBJECT(webp), "shrink") && webp->shrink != 0) - webp->scale = 1.0 / webp->shrink; + webp->scale = 1.0 / webp->shrink; // FIXME: Invalidates operation cache if (VIPS_OBJECT_CLASS(vips_foreign_load_webp_parent_class)->build(object)) return -1; diff --git a/libvips/resample/thumbnail.c b/libvips/resample/thumbnail.c index 195f20636f..dd6de13a76 100644 --- a/libvips/resample/thumbnail.c +++ b/libvips/resample/thumbnail.c @@ -680,10 +680,10 @@ vips_thumbnail_build(VipsObject *object) * auto_rotate. */ if (vips_object_argument_isset(object, "no_rotate")) - thumbnail->auto_rotate = !thumbnail->no_rotate; + thumbnail->auto_rotate = !thumbnail->no_rotate; // FIXME: Invalidates operation cache if (!vips_object_argument_isset(object, "height")) - thumbnail->height = thumbnail->width; + thumbnail->height = thumbnail->width; // FIXME: Invalidates operation cache /* Open and do any pre-shrinking. */ From ca7d276d589d24d30e52bbc157101117614795f4 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 27 Jan 2025 17:34:04 +0100 Subject: [PATCH 050/174] Prefer use of statically allocated mutexes (#4362) Mutexes in static storage are initialised to all-zeros, which would avoid the need for explicit calls to `g_mutex_init()` and `g_mutex_clear()`. --- doc/using-threads.xml | 2 - libvips/convolution/convi.c | 8 ++-- libvips/create/text.c | 17 ++++---- libvips/deprecated/rename.c | 8 ++-- libvips/foreign/archive.c | 32 +++------------ libvips/foreign/pdfiumload.c | 47 ++++++++------------- libvips/freqfilt/fwfft.c | 40 +++++------------- libvips/freqfilt/invfft.c | 22 +++++----- libvips/freqfilt/pfreqfilt.h | 4 +- libvips/include/vips/internal.h | 2 +- libvips/include/vips/private.h | 2 - libvips/iofuncs/buffer.c | 16 ++++---- libvips/iofuncs/cache.c | 28 ++++++------- libvips/iofuncs/error.c | 28 ++++++------- libvips/iofuncs/gate.c | 6 +-- libvips/iofuncs/generate.c | 12 +++--- libvips/iofuncs/header.c | 23 ++++------- libvips/iofuncs/image.c | 12 +++--- libvips/iofuncs/init.c | 10 +---- libvips/iofuncs/memory.c | 73 ++++++++++----------------------- libvips/iofuncs/object.c | 29 ++++++------- libvips/iofuncs/region.c | 16 ++++---- libvips/iofuncs/sinkscreen.c | 51 ++++++++++------------- libvips/iofuncs/type.c | 20 ++++----- libvips/iofuncs/window.c | 12 +++--- libvips/morphology/morph.c | 4 +- libvips/resample/reducev.cpp | 4 +- 27 files changed, 201 insertions(+), 327 deletions(-) diff --git a/doc/using-threads.xml b/doc/using-threads.xml index 9d55875909..409dc2d8a2 100644 --- a/doc/using-threads.xml +++ b/doc/using-threads.xml @@ -216,8 +216,6 @@ main(int argc, char **argv) if (VIPS_INIT(argv[0])) vips_error_exit(NULL); - g_mutex_init(&allocation_lock); - for (i = 0; i < NUM_IN_PARALLEL; i++) workers[i] = g_thread_new(NULL, (GThreadFunc) worker, argv[1]); diff --git a/libvips/convolution/convi.c b/libvips/convolution/convi.c index 0df48e20ae..141d7c72ec 100644 --- a/libvips/convolution/convi.c +++ b/libvips/convolution/convi.c @@ -498,9 +498,9 @@ vips_convi_compile_section(VipsConvi *convi, VipsImage *in, Pass *pass) /* Some orcs seem to be unstable with many compilers active at once. */ - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); result = orc_program_compile(p); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL(result)) return -1; @@ -549,9 +549,9 @@ vips_convi_compile_clip(VipsConvi *convi) /* Some orcs seem to be unstable with many compilers active at once. */ - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); result = orc_program_compile(p); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL(result)) return -1; diff --git a/libvips/create/text.c b/libvips/create/text.c index 71b1325f6d..e1454da350 100644 --- a/libvips/create/text.c +++ b/libvips/create/text.c @@ -131,7 +131,7 @@ static PangoFontMap *vips_text_fontmap = NULL; /* ... single-thread vips_text_fontfiles with this. */ -static GMutex *vips_text_lock = NULL; +static GMutex vips_text_lock; /* All the fontfiles we've loaded. fontconfig lets you add a fontfile * repeatedly, and we obviously don't want that. @@ -376,7 +376,6 @@ vips_text_autofit(VipsText *text) static void * vips_text_init_once(void *client) { - vips_text_lock = vips_g_mutex_new(); vips_text_fontmap = pango_cairo_font_map_new(); vips_text_fontfiles = g_hash_table_new(g_str_hash, g_str_equal); @@ -416,7 +415,7 @@ vips_text_build(VipsObject *object) * between all vips_text instances, we must lock all the way to the * end of text rendering. */ - g_mutex_lock(vips_text_lock); + g_mutex_lock(&vips_text_lock); #ifdef HAVE_FONTCONFIG if (text->fontfile && @@ -451,7 +450,7 @@ vips_text_build(VipsObject *object) if (vips_object_argument_isset(object, "height") && !vips_object_argument_isset(object, "dpi")) { if (vips_text_autofit(text)) { - g_mutex_unlock(vips_text_lock); + g_mutex_unlock(&vips_text_lock); return -1; } } @@ -459,13 +458,13 @@ vips_text_build(VipsObject *object) /* Layout. Can fail for "", for example. */ if (vips_text_get_extents(text, &extents)) { - g_mutex_unlock(vips_text_lock); + g_mutex_unlock(&vips_text_lock); return -1; } if (extents.width == 0 || extents.height == 0) { - g_mutex_unlock(vips_text_lock); + g_mutex_unlock(&vips_text_lock); vips_error(class->nickname, "%s", _("no text to render")); return -1; } @@ -480,7 +479,7 @@ vips_text_build(VipsObject *object) if (vips_image_pipelinev(t[0], VIPS_DEMAND_STYLE_ANY, NULL) || vips_image_write_prepare(t[0])) { - g_mutex_unlock(vips_text_lock); + g_mutex_unlock(&vips_text_lock); return -1; } in = t[0]; @@ -494,7 +493,7 @@ vips_text_build(VipsObject *object) status = cairo_surface_status(surface); if (status) { cairo_surface_destroy(surface); - g_mutex_unlock(vips_text_lock); + g_mutex_unlock(&vips_text_lock); vips_error(class->nickname, "%s", cairo_status_to_string(status)); return -1; @@ -509,7 +508,7 @@ vips_text_build(VipsObject *object) cairo_destroy(cr); - g_mutex_unlock(vips_text_lock); + g_mutex_unlock(&vips_text_lock); if (text->rgba) { /* Cairo makes pre-multipled BRGA -- we must byteswap and diff --git a/libvips/deprecated/rename.c b/libvips/deprecated/rename.c index 4ac3209b38..dd638530bb 100644 --- a/libvips/deprecated/rename.c +++ b/libvips/deprecated/rename.c @@ -774,13 +774,13 @@ void vips_vinfo(const char *domain, const char *fmt, va_list ap) { if (vips__info) { - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); (void) fprintf(stderr, _("%s: "), _("info")); if (domain) (void) fprintf(stderr, _("%s: "), domain); (void) vfprintf(stderr, fmt, ap); (void) fprintf(stderr, "\n"); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } } @@ -799,13 +799,13 @@ vips_vwarn(const char *domain, const char *fmt, va_list ap) { if (!g_getenv("IM_WARNING") && !g_getenv("VIPS_WARNING")) { - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); (void) fprintf(stderr, _("%s: "), _("vips warning")); if (domain) (void) fprintf(stderr, _("%s: "), domain); (void) vfprintf(stderr, fmt, ap); (void) fprintf(stderr, "\n"); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } if (vips__fatal) diff --git a/libvips/foreign/archive.c b/libvips/foreign/archive.c index ad16e114cd..6a2f7bb716 100644 --- a/libvips/foreign/archive.c +++ b/libvips/foreign/archive.c @@ -56,7 +56,7 @@ #include #include -static GMutex *vips_libarchive_mutex = NULL; +static GMutex vips_libarchive_mutex; struct _VipsArchive { // prepend filenames with this for filesystem output @@ -102,30 +102,12 @@ zip_close_target_cb(struct archive *a, void *client_data) return ARCHIVE_OK; } -static void * -vips__archive_once_init(void *client) -{ - vips_libarchive_mutex = vips_g_mutex_new(); - - return NULL; -} - -static void -vips__archive_init(void) -{ - static GOnce once = G_ONCE_INIT; - - VIPS_ONCE(&once, vips__archive_once_init, NULL); -} - // write to a filesystem directory VipsArchive * vips__archive_new_to_dir(const char *base_dirname) { VipsArchive *archive; - vips__archive_init(); - if (!(archive = VIPS_NEW(NULL, VipsArchive))) return NULL; @@ -146,8 +128,6 @@ vips__archive_new_to_target(VipsTarget *target, base_dirname, compression); #endif /*DEBUG*/ - vips__archive_init(); - if (!(archive = VIPS_NEW(NULL, VipsArchive))) return NULL; @@ -254,11 +234,11 @@ vips__archive_mkfile_zip(VipsArchive *archive, { struct archive_entry *entry; - vips__worker_lock(vips_libarchive_mutex); + vips__worker_lock(&vips_libarchive_mutex); if (!(entry = archive_entry_new())) { vips_error("archive", "%s", _("unable to create entry")); - g_mutex_unlock(vips_libarchive_mutex); + g_mutex_unlock(&vips_libarchive_mutex); return -1; } @@ -275,7 +255,7 @@ vips__archive_mkfile_zip(VipsArchive *archive, if (archive_write_header(archive->archive, entry)) { vips_error("archive", "%s", _("unable to write header")); archive_entry_free(entry); - g_mutex_unlock(vips_libarchive_mutex); + g_mutex_unlock(&vips_libarchive_mutex); return -1; } @@ -283,11 +263,11 @@ vips__archive_mkfile_zip(VipsArchive *archive, if (archive_write_data(archive->archive, buf, len) != len) { vips_error("archive", "%s", _("unable to write data")); - g_mutex_unlock(vips_libarchive_mutex); + g_mutex_unlock(&vips_libarchive_mutex); return -1; } - g_mutex_unlock(vips_libarchive_mutex); + g_mutex_unlock(&vips_libarchive_mutex); return 0; } diff --git a/libvips/foreign/pdfiumload.c b/libvips/foreign/pdfiumload.c index 07d09b012c..5379460cb8 100644 --- a/libvips/foreign/pdfiumload.c +++ b/libvips/foreign/pdfiumload.c @@ -182,7 +182,7 @@ static char *vips_pdfium_errors[] = { "page not found or content error" }; -static GMutex *vips_pdfium_mutex = NULL; +static GMutex vips_pdfium_mutex; static void vips_pdfium_error(void) @@ -199,14 +199,14 @@ vips_pdfium_error(void) static void vips_foreign_load_pdf_close(VipsForeignLoadPdf *pdf) { - g_mutex_lock(vips_pdfium_mutex); + g_mutex_lock(&vips_pdfium_mutex); VIPS_FREEF(FPDF_ClosePage, pdf->page); VIPS_FREEF(FPDFDOC_ExitFormFillEnvironment, pdf->form); VIPS_FREEF(FPDF_CloseDocument, pdf->doc); VIPS_UNREF(pdf->source); - g_mutex_unlock(vips_pdfium_mutex); + g_mutex_unlock(&vips_pdfium_mutex); } static void @@ -297,11 +297,11 @@ vips_foreign_load_pdf_build(VipsObject *object) pdf->file_access.m_GetBlock = vips_pdfium_GetBlock; pdf->file_access.m_Param = pdf; - g_mutex_lock(vips_pdfium_mutex); + g_mutex_lock(&vips_pdfium_mutex); if (!(pdf->doc = FPDF_LoadCustomDocument(&pdf->file_access, pdf->password))) { - g_mutex_unlock(vips_pdfium_mutex); + g_mutex_unlock(&vips_pdfium_mutex); vips_pdfium_error(); vips_error("pdfload", _("%s: unable to load"), @@ -312,7 +312,7 @@ vips_foreign_load_pdf_build(VipsObject *object) if (!(pdf->form = FPDFDOC_InitFormFillEnvironment(pdf->doc, &pdf->form_callbacks))) { - g_mutex_unlock(vips_pdfium_mutex); + g_mutex_unlock(&vips_pdfium_mutex); vips_pdfium_error(); vips_error("pdfload", _("%s: unable to initialize form fill environment"), @@ -321,7 +321,7 @@ vips_foreign_load_pdf_build(VipsObject *object) return -1; } - g_mutex_unlock(vips_pdfium_mutex); + g_mutex_unlock(&vips_pdfium_mutex); } if (VIPS_OBJECT_CLASS(vips_foreign_load_pdf_parent_class)->build(object)) @@ -350,7 +350,7 @@ vips_foreign_load_pdf_get_page(VipsForeignLoadPdf *pdf, int page_no) if (pdf->current_page != page_no) { VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(pdf); - g_mutex_lock(vips_pdfium_mutex); + g_mutex_lock(&vips_pdfium_mutex); VIPS_FREEF(FPDF_ClosePage, pdf->page); pdf->current_page = -1; @@ -360,7 +360,7 @@ vips_foreign_load_pdf_get_page(VipsForeignLoadPdf *pdf, int page_no) #endif /*DEBUG*/ if (!(pdf->page = FPDF_LoadPage(pdf->doc, page_no))) { - g_mutex_unlock(vips_pdfium_mutex); + g_mutex_unlock(&vips_pdfium_mutex); vips_pdfium_error(); vips_error(class->nickname, _("unable to load page %d"), page_no); @@ -368,7 +368,7 @@ vips_foreign_load_pdf_get_page(VipsForeignLoadPdf *pdf, int page_no) } pdf->current_page = page_no; - g_mutex_unlock(vips_pdfium_mutex); + g_mutex_unlock(&vips_pdfium_mutex); } return 0; @@ -412,7 +412,7 @@ vips_foreign_load_pdf_set_image(VipsForeignLoadPdf *pdf, VipsImage *out) vips_image_set_int(out, "pdf-n_pages", pdf->n_pages); vips_image_set_int(out, VIPS_META_N_PAGES, pdf->n_pages); - g_mutex_lock(vips_pdfium_mutex); + g_mutex_lock(&vips_pdfium_mutex); for (i = 0; i < n_metadata; i++) { VipsForeignLoadPdfMetadata *metadata = @@ -436,7 +436,7 @@ vips_foreign_load_pdf_set_image(VipsForeignLoadPdf *pdf, VipsImage *out) } } - g_mutex_unlock(vips_pdfium_mutex); + g_mutex_unlock(&vips_pdfium_mutex); /* We need pixels/mm for vips. */ @@ -463,9 +463,9 @@ vips_foreign_load_pdf_header(VipsForeignLoad *load) printf("vips_foreign_load_pdf_header: %p\n", pdf); #endif /*DEBUG*/ - g_mutex_lock(vips_pdfium_mutex); + g_mutex_lock(&vips_pdfium_mutex); pdf->n_pages = FPDF_GetPageCount(pdf->doc); - g_mutex_unlock(vips_pdfium_mutex); + g_mutex_unlock(&vips_pdfium_mutex); /* @n == -1 means until the end of the doc. */ @@ -594,7 +594,7 @@ vips_foreign_load_pdf_generate(VipsRegion *out_region, if (vips_foreign_load_pdf_get_page(pdf, pdf->page_no + i)) return -1; - vips__worker_lock(vips_pdfium_mutex); + vips__worker_lock(&vips_pdfium_mutex); /* 4 means RGBA. */ @@ -626,7 +626,7 @@ vips_foreign_load_pdf_generate(VipsRegion *out_region, FPDFBitmap_Destroy(bitmap); - g_mutex_unlock(vips_pdfium_mutex); + g_mutex_unlock(&vips_pdfium_mutex); top += rect.height; i += 1; @@ -670,28 +670,13 @@ vips_foreign_load_pdf_load(VipsForeignLoad *load) return 0; } -static void * -vips_foreign_load_pdf_once_init(void *client) -{ - /* We must make the mutex on class init (not _build) since we - * can lock even if build is not called. - */ - vips_pdfium_mutex = vips_g_mutex_new(); - - return NULL; -} - static void vips_foreign_load_pdf_class_init(VipsForeignLoadPdfClass *class) { - static GOnce once = G_ONCE_INIT; - GObjectClass *gobject_class = G_OBJECT_CLASS(class); VipsObjectClass *object_class = (VipsObjectClass *) class; VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; - VIPS_ONCE(&once, vips_foreign_load_pdf_once_init, NULL); - gobject_class->dispose = vips_foreign_load_pdf_dispose; gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; diff --git a/libvips/freqfilt/fwfft.c b/libvips/freqfilt/fwfft.c index daadc29271..6aea0ece14 100644 --- a/libvips/freqfilt/fwfft.c +++ b/libvips/freqfilt/fwfft.c @@ -95,23 +95,7 @@ G_DEFINE_TYPE(VipsFwfft, vips_fwfft, VIPS_TYPE_FREQFILT); /* Everything in fftw3 except execute has to be behind a mutex. */ -GMutex *vips__fft_lock = NULL; - -static void * -vips__fft_thread_init(void *data) -{ - vips__fft_lock = vips_g_mutex_new(); - - return NULL; -} - -void -vips__fft_init(void) -{ - static GOnce once = G_ONCE_INIT; - - VIPS_ONCE(&once, vips__fft_thread_init, NULL); -} +GMutex vips__fft_lock; /* Real to complex forward transform. */ @@ -152,23 +136,23 @@ rfwfft1(VipsObject *object, VipsImage *in, VipsImage **out) if (!(half_complex = VIPS_ARRAY(fwfft, in->Ysize * half_width * 2, double))) return -1; - g_mutex_lock(vips__fft_lock); + g_mutex_lock(&vips__fft_lock); if (!(plan = fftw_plan_dft_r2c_2d(in->Ysize, in->Xsize, planner_scratch, (fftw_complex *) half_complex, 0))) { - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); vips_error(class->nickname, "%s", _("unable to create transform plan")); return -1; } - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); fftw_execute_dft_r2c(plan, (double *) t[1]->data, (fftw_complex *) half_complex); - g_mutex_lock(vips__fft_lock); + g_mutex_lock(&vips__fft_lock); fftw_destroy_plan(plan); - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); /* Write to out as another memory buffer. */ @@ -271,25 +255,25 @@ cfwfft1(VipsObject *object, VipsImage *in, VipsImage **out) /* Make the plan for the transform. */ - g_mutex_lock(vips__fft_lock); + g_mutex_lock(&vips__fft_lock); if (!(plan = fftw_plan_dft_2d(in->Ysize, in->Xsize, (fftw_complex *) planner_scratch, (fftw_complex *) planner_scratch, FFTW_FORWARD, 0))) { - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); vips_error(class->nickname, "%s", _("unable to create transform plan")); return -1; } - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); fftw_execute_dft(plan, (fftw_complex *) t[1]->data, (fftw_complex *) t[1]->data); - g_mutex_lock(vips__fft_lock); + g_mutex_lock(&vips__fft_lock); fftw_destroy_plan(plan); - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); /* Write to out as another memory buffer. */ @@ -332,8 +316,6 @@ vips_fwfft_build(VipsObject *object) VipsImage *in; - vips__fft_init(); - if (VIPS_OBJECT_CLASS(vips_fwfft_parent_class)->build(object)) return -1; diff --git a/libvips/freqfilt/invfft.c b/libvips/freqfilt/invfft.c index 874df553c5..bd73d33f2a 100644 --- a/libvips/freqfilt/invfft.c +++ b/libvips/freqfilt/invfft.c @@ -113,25 +113,25 @@ cinvfft1(VipsObject *object, VipsImage *in, VipsImage **out) if (!(planner_scratch = VIPS_ARRAY(invfft, VIPS_IMAGE_N_PELS(in) * 2, double))) return -1; - g_mutex_lock(vips__fft_lock); + g_mutex_lock(&vips__fft_lock); if (!(plan = fftw_plan_dft_2d(in->Ysize, in->Xsize, (fftw_complex *) planner_scratch, (fftw_complex *) planner_scratch, FFTW_BACKWARD, 0))) { - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); vips_error(class->nickname, "%s", _("unable to create transform plan")); return -1; } - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); fftw_execute_dft(plan, (fftw_complex *) (*out)->data, (fftw_complex *) (*out)->data); - g_mutex_lock(vips__fft_lock); + g_mutex_lock(&vips__fft_lock); fftw_destroy_plan(plan); - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); (*out)->Type = VIPS_INTERPRETATION_B_W; @@ -194,23 +194,23 @@ rinvfft1(VipsObject *object, VipsImage *in, VipsImage **out) if (!(planner_scratch = VIPS_ARRAY(invfft, t[1]->Ysize * half_width * 2, double))) return -1; - g_mutex_lock(vips__fft_lock); + g_mutex_lock(&vips__fft_lock); if (!(plan = fftw_plan_dft_c2r_2d(t[1]->Ysize, t[1]->Xsize, (fftw_complex *) planner_scratch, (double *) (*out)->data, 0))) { - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); vips_error(class->nickname, "%s", _("unable to create transform plan")); return -1; } - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); fftw_execute_dft_c2r(plan, (fftw_complex *) half_complex, (double *) (*out)->data); - g_mutex_lock(vips__fft_lock); + g_mutex_lock(&vips__fft_lock); fftw_destroy_plan(plan); - g_mutex_unlock(vips__fft_lock); + g_mutex_unlock(&vips__fft_lock); return 0; } @@ -224,8 +224,6 @@ vips_invfft_build(VipsObject *object) VipsImage *in; - vips__fft_init(); - if (VIPS_OBJECT_CLASS(vips_invfft_parent_class)->build(object)) return -1; diff --git a/libvips/freqfilt/pfreqfilt.h b/libvips/freqfilt/pfreqfilt.h index 768b1e316f..097d1cdb8c 100644 --- a/libvips/freqfilt/pfreqfilt.h +++ b/libvips/freqfilt/pfreqfilt.h @@ -37,9 +37,7 @@ extern "C" { /* All fftw3 calls except execute() need to be locked. */ -extern GMutex *vips__fft_lock; - -void vips__fft_init(void); +extern GMutex vips__fft_lock; #define VIPS_TYPE_FREQFILT (vips_freqfilt_get_type()) #define VIPS_FREQFILT(obj) \ diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 2c4a3299f1..74e08093dd 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -218,7 +218,7 @@ VIPS_API int vips__write_header_bytes(VipsImage *im, unsigned char *to); int vips__image_meta_copy(VipsImage *dst, const VipsImage *src); -extern GMutex *vips__global_lock; +extern GMutex vips__global_lock; int vips_image_written(VipsImage *image); void vips_image_preeval(VipsImage *image); diff --git a/libvips/include/vips/private.h b/libvips/include/vips/private.h index 766c455c97..c6f2bc5fa6 100644 --- a/libvips/include/vips/private.h +++ b/libvips/include/vips/private.h @@ -218,8 +218,6 @@ int vips__view_image(struct _VipsImage *image); VIPS_API int _vips__argument_id; -void vips__meta_init(void); - // autoptr needs typed functions for autofree ... this needs to be in the // public API since downstream projects can use our auto defs VIPS_API diff --git a/libvips/iofuncs/buffer.c b/libvips/iofuncs/buffer.c index 3b0acac999..de486474af 100644 --- a/libvips/iofuncs/buffer.c +++ b/libvips/iofuncs/buffer.c @@ -206,12 +206,12 @@ vips_buffer_free(VipsBuffer *buffer) g_free(buffer); #ifdef DEBUG - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); g_assert(g_slist_find(vips__buffer_all, buffer)); vips__buffer_all = g_slist_remove(vips__buffer_all, buffer); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); #endif /*DEBUG*/ #ifdef DEBUG_VERBOSE @@ -234,10 +234,10 @@ buffer_cache_free(VipsBufferCache *cache) GSList *p; #ifdef DEBUG_CREATE - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); vips__buffer_cache_all = g_slist_remove(vips__buffer_cache_all, cache); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); printf("buffer_cache_free: freeing cache %p on thread %p\n", cache, g_thread_self()); @@ -283,10 +283,10 @@ buffer_cache_new(VipsBufferThread *buffer_thread, VipsImage *im) cache->n_reserve = 0; #ifdef DEBUG_CREATE - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); vips__buffer_cache_all = g_slist_prepend(vips__buffer_cache_all, cache); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); printf("buffer_cache_new: new cache %p for thread %p on image %p\n", cache, g_thread_self(), im); @@ -537,10 +537,10 @@ vips_buffer_new(VipsImage *im, VipsRect *area) buffer->bsize = 0; #ifdef DEBUG - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); vips__buffer_all = g_slist_prepend(vips__buffer_all, buffer); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); #endif /*DEBUG*/ } diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index 5a0f8bdca2..ceacbe6c36 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -103,7 +103,7 @@ static int vips_cache_time = 0; /* Protect cache access with this. */ -static GMutex *vips_cache_lock = NULL; +static GMutex vips_cache_lock; /* A cache entry. */ @@ -471,8 +471,6 @@ vips_operation_copy(VipsOperation *operation) void * vips__cache_once_init(void *data) { - vips_cache_lock = vips_g_mutex_new(); - vips_cache_table = g_hash_table_new( (GHashFunc) vips_operation_hash, (GEqualFunc) vips_operation_equal); @@ -521,11 +519,11 @@ vips_cache_print_nolock(void) void vips_cache_print(void) { - g_mutex_lock(vips_cache_lock); + g_mutex_lock(&vips_cache_lock); vips_cache_print_nolock(); - g_mutex_unlock(vips_cache_lock); + g_mutex_unlock(&vips_cache_lock); } static void * @@ -786,7 +784,7 @@ vips_cache_drop_all(void) printf("vips_cache_drop_all:\n"); #endif /*VIPS_DEBUG*/ - g_mutex_lock(vips_cache_lock); + g_mutex_lock(&vips_cache_lock); if (vips_cache_table) { VipsOperation *operation; @@ -804,7 +802,7 @@ vips_cache_drop_all(void) VIPS_FREEF(g_hash_table_unref, vips_cache_table); } - g_mutex_unlock(vips_cache_lock); + g_mutex_unlock(&vips_cache_lock); } static void @@ -842,7 +840,7 @@ vips_cache_trim(void) { VipsOperation *operation; - g_mutex_lock(vips_cache_lock); + g_mutex_lock(&vips_cache_lock); while (vips_cache_table && (g_hash_table_size(vips_cache_table) > vips_cache_max || @@ -857,7 +855,7 @@ vips_cache_trim(void) vips_cache_remove(operation); } - g_mutex_unlock(vips_cache_lock); + g_mutex_unlock(&vips_cache_lock); } /** @@ -899,7 +897,7 @@ vips_cache_operation_buildp(VipsOperation **operation) vips_object_print_dump(VIPS_OBJECT(*operation)); #endif /*VIPS_DEBUG*/ - g_mutex_lock(vips_cache_lock); + g_mutex_lock(&vips_cache_lock); hit = vips_cache_operation_get(*operation); @@ -930,7 +928,7 @@ vips_cache_operation_buildp(VipsOperation **operation) } } - g_mutex_unlock(vips_cache_lock); + g_mutex_unlock(&vips_cache_lock); /* If there was a miss, we need to build this operation and add * it to the cache, if appropriate. @@ -981,7 +979,7 @@ vips_cache_operation_buildp(VipsOperation **operation) */ flags = vips_operation_get_flags(*operation); - g_mutex_lock(vips_cache_lock); + g_mutex_lock(&vips_cache_lock); /* If two threads build the same operation at the same time, * we can get multiple adds. Let the first one win. See @@ -1002,7 +1000,7 @@ vips_cache_operation_buildp(VipsOperation **operation) vips_cache_insert(*operation); } - g_mutex_unlock(vips_cache_lock); + g_mutex_unlock(&vips_cache_lock); } vips_cache_trim(); @@ -1098,13 +1096,13 @@ vips_cache_get_size(void) { guint size; - g_mutex_lock(vips_cache_lock); + g_mutex_lock(&vips_cache_lock); size = 0; if (vips_cache_table) size = g_hash_table_size(vips_cache_table); - g_mutex_unlock(vips_cache_lock); + g_mutex_unlock(&vips_cache_lock); return size; } diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index 586f4ac625..9821294f2d 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -144,10 +144,10 @@ static int vips_error_freeze_count = 0; void vips_error_freeze(void) { - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); g_assert(vips_error_freeze_count >= 0); vips_error_freeze_count += 1; - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } /** @@ -158,10 +158,10 @@ vips_error_freeze(void) void vips_error_thaw(void) { - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); vips_error_freeze_count -= 1; g_assert(vips_error_freeze_count >= 0); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } /** @@ -179,9 +179,9 @@ vips_error_buffer(void) { const char *msg; - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); msg = vips_buf_all(&vips_error_buf); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); return msg; } @@ -198,10 +198,10 @@ vips_error_buffer_copy(void) { char *msg; - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); msg = g_strdup(vips_buf_all(&vips_error_buf)); vips_buf_rewind(&vips_error_buf); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); return msg; } @@ -242,7 +242,7 @@ vips_verror(const char *domain, const char *fmt, va_list ap) } #endif /*VIPS_DEBUG*/ - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); g_assert(vips_error_freeze_count >= 0); if (!vips_error_freeze_count) { if (domain) @@ -250,7 +250,7 @@ vips_verror(const char *domain, const char *fmt, va_list ap) vips_buf_vappendf(&vips_error_buf, fmt, ap); vips_buf_appends(&vips_error_buf, "\n"); } - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); if (vips__fatal) vips_error_exit("vips__fatal"); @@ -340,9 +340,9 @@ vips_error_g(GError **error) /* glib does not expect a trailing '\n' and vips always has one. */ - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); vips_buf_removec(&vips_error_buf, '\n'); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); g_set_error(error, vips_domain, -1, "%s", vips_error_buffer()); vips_error_clear(); @@ -379,9 +379,9 @@ vips_g_error(GError **error) void vips_error_clear(void) { - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); vips_buf_rewind(&vips_error_buf); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } /** diff --git a/libvips/iofuncs/gate.c b/libvips/iofuncs/gate.c index ea9f914b90..8f33747296 100644 --- a/libvips/iofuncs/gate.c +++ b/libvips/iofuncs/gate.c @@ -136,7 +136,7 @@ vips_thread_profile_save_cb(gpointer key, gpointer value, gpointer data) static void vips_thread_profile_save(VipsThreadProfile *profile) { - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); VIPS_DEBUG_MSG("vips_thread_profile_save: %s\n", profile->name); @@ -144,7 +144,7 @@ vips_thread_profile_save(VipsThreadProfile *profile) vips__thread_fp = vips__file_open_write("vips-profile.txt", TRUE); if (!vips__thread_fp) { - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); g_warning("unable to create profile log"); return; } @@ -157,7 +157,7 @@ vips_thread_profile_save(VipsThreadProfile *profile) vips_thread_profile_save_cb, vips__thread_fp); vips_thread_profile_save_gate(profile->memory, vips__thread_fp); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } static void diff --git a/libvips/iofuncs/generate.c b/libvips/iofuncs/generate.c index 8941762f75..d087ea3feb 100644 --- a/libvips/iofuncs/generate.c +++ b/libvips/iofuncs/generate.c @@ -181,7 +181,7 @@ vips__link_break_rev(VipsImage *image_down, VipsImage *image_up, void *b) void vips__link_break_all(VipsImage *image) { - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); vips_slist_map2(image->upstream, (VipsSListMap2Fn) vips__link_break, image, NULL); @@ -191,7 +191,7 @@ vips__link_break_all(VipsImage *image) g_assert(!image->upstream); g_assert(!image->downstream); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } typedef struct _LinkMap { @@ -261,7 +261,7 @@ vips__link_map(VipsImage *image, gboolean upstream, * member. There will be intense confusion if two threads try to do * this at the same time. */ - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); serial += 1; map.serial = serial; @@ -271,7 +271,7 @@ vips__link_map(VipsImage *image, gboolean upstream, for (p = images; p; p = p->next) g_object_ref(p->data); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); result = vips_slist_map2(images, fn, a, b); @@ -330,10 +330,10 @@ vips__demand_hint_array(VipsImage *image, /* im depends on all these ims. */ - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); for (i = 0; i < len; i++) vips__link_make(in[i], image); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); /* Set a flag on the image to say we remembered to call this thing. * vips_image_generate() and friends check this. diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 8aca9821eb..3071dd34d9 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -136,7 +136,7 @@ /* Use in various small places where we need a mutex and it's not worth * making a private one. */ -static GMutex *vips__meta_lock = NULL; +static GMutex vips__meta_lock; /* We have to keep the gtype as a string, since we statically init this. */ @@ -1143,11 +1143,11 @@ vips__image_meta_copy(VipsImage *dst, const VipsImage *src) /* We lock with vips_image_set() to stop races in highly- * threaded applications. */ - g_mutex_lock(vips__meta_lock); + g_mutex_lock(&vips__meta_lock); meta_init(dst); vips_slist_map2(src->meta_traverse, (VipsSListMap2Fn) meta_cp_field, dst, NULL); - g_mutex_unlock(vips__meta_lock); + g_mutex_unlock(&vips__meta_lock); } return 0; @@ -1242,10 +1242,10 @@ vips_image_set(VipsImage *image, const char *name, GValue *value) * metadata copy on another -- this can lead to crashes in * highly-threaded applications. */ - g_mutex_lock(vips__meta_lock); + g_mutex_lock(&vips__meta_lock); meta_init(image); (void) meta_new(image, name, value); - g_mutex_unlock(vips__meta_lock); + g_mutex_unlock(&vips__meta_lock); /* If we're setting an EXIF data block, we need to automatically expand * out all the tags. This will set things like xres/yres too. @@ -1453,9 +1453,9 @@ vips_image_remove(VipsImage *image, const char *name) * racing with metadata copy on another -- this can lead to * crashes in highly-threaded applications. */ - g_mutex_lock(vips__meta_lock); + g_mutex_lock(&vips__meta_lock); result = g_hash_table_remove(image->meta, name); - g_mutex_unlock(vips__meta_lock); + g_mutex_unlock(&vips__meta_lock); } return result; @@ -2280,12 +2280,3 @@ vips_image_get_history(VipsImage *image) return image->Hist ? image->Hist : ""; } - -/* Called during vips_init(). - */ -void -vips__meta_init(void) -{ - if (!vips__meta_lock) - vips__meta_lock = vips_g_mutex_new(); -} diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 7794a0bf1c..5081c9d886 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -388,7 +388,7 @@ char *vips__disc_threshold = NULL; /* Minimise needs a lock. */ -static GMutex *vips__minimise_lock = NULL; +static GMutex vips__minimise_lock; static guint vips_image_signals[SIG_LAST] = { 0 }; @@ -698,7 +698,7 @@ vips_image_sanity(VipsObject *object, VipsBuf *buf) /* Must lock around inter-image links. */ - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); if (vips_slist_map2(image->upstream, (VipsSListMap2Fn) vips_image_sanity_upstream, image, NULL)) @@ -707,7 +707,7 @@ vips_image_sanity(VipsObject *object, VipsBuf *buf) (VipsSListMap2Fn) vips_image_sanity_downstream, image, NULL)) vips_buf_appends(buf, "downstream broken\n"); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); VIPS_OBJECT_CLASS(vips_image_parent_class)->sanity(object, buf); } @@ -1326,8 +1326,6 @@ vips_image_class_init(VipsImageClass *class) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - - vips__minimise_lock = vips_g_mutex_new(); } static void @@ -1446,12 +1444,12 @@ vips_image_minimise_all(VipsImage *image) /* Minimisation will modify things like sources, so we can't run it * from many threads. */ - g_mutex_lock(vips__minimise_lock); + g_mutex_lock(&vips__minimise_lock); (void) vips__link_map(image, TRUE, (VipsSListMap2Fn) vips_image_minimise_all_cb, NULL, NULL); - g_mutex_unlock(vips__minimise_lock); + g_mutex_unlock(&vips__minimise_lock); } /** diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 75a81abfb2..97ef911b2d 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -107,7 +107,7 @@ int vips__fatal = 0; /* Use in various small places where we need a mutex and it's not worth * making a private one. */ -GMutex *vips__global_lock = NULL; +GMutex vips__global_lock; /* A debugging timer, zero at library init. */ @@ -510,10 +510,6 @@ vips_init(const char *argv0) vips__thread_init(); vips__threadpool_init(); vips__buffer_init(); - vips__meta_init(); - - if (!vips__global_lock) - vips__global_lock = vips_g_mutex_new(); if (!vips__global_timer) vips__global_timer = g_timer_new(); @@ -749,10 +745,6 @@ vips_shutdown(void) vips__thread_profile_stop(); vips__threadpool_shutdown(); - /* Don't free vips__global_lock -- we want to be able to use - * vips_error_buffer() after vips_shutdown(), since vips_leak() can - * call it. - */ VIPS_FREE(vips__argv0); VIPS_FREE(vips__prgname); VIPS_FREEF(g_timer_destroy, vips__global_timer); diff --git a/libvips/iofuncs/memory.c b/libvips/iofuncs/memory.c index ac9e517e6f..3ac06db669 100644 --- a/libvips/iofuncs/memory.c +++ b/libvips/iofuncs/memory.c @@ -115,7 +115,7 @@ static int vips_tracked_allocs = 0; static size_t vips_tracked_mem = 0; static int vips_tracked_files = 0; static size_t vips_tracked_mem_highwater = 0; -static GMutex *vips_tracked_mutex = NULL; +static GMutex vips_tracked_mutex; /** * VIPS_NEW: @@ -238,7 +238,7 @@ vips_tracked_free(void *s) void *start = (void *) ((char *) s - 16); size_t size = *((size_t *) start); - g_mutex_lock(vips_tracked_mutex); + g_mutex_lock(&vips_tracked_mutex); #ifdef DEBUG_VERBOSE_MEM printf("vips_tracked_free: %p, %zd bytes\n", s, size); @@ -252,7 +252,7 @@ vips_tracked_free(void *s) vips_tracked_mem -= size; vips_tracked_allocs -= 1; - g_mutex_unlock(vips_tracked_mutex); + g_mutex_unlock(&vips_tracked_mutex); g_free(start); @@ -275,7 +275,7 @@ vips_tracked_aligned_free(void *s) void *start = (size_t *) s - 1; size_t size = *((size_t *) start); - g_mutex_lock(vips_tracked_mutex); + g_mutex_lock(&vips_tracked_mutex); #ifdef DEBUG_VERBOSE printf("vips_tracked_aligned_free: %p, %zd bytes\n", s, size); @@ -289,7 +289,7 @@ vips_tracked_aligned_free(void *s) vips_tracked_mem -= size; vips_tracked_allocs -= 1; - g_mutex_unlock(vips_tracked_mutex); + g_mutex_unlock(&vips_tracked_mutex); #ifdef HAVE__ALIGNED_MALLOC _aligned_free(start); @@ -300,23 +300,6 @@ vips_tracked_aligned_free(void *s) VIPS_GATE_FREE(size); } -static void * -vips_tracked_init_mutex(void *data) -{ - vips_tracked_mutex = vips_g_mutex_new(); - - return NULL; -} - -static void -vips_tracked_init(void) -{ - static GOnce vips_tracked_once = G_ONCE_INIT; - - VIPS_ONCE(&vips_tracked_once, - vips_tracked_init_mutex, NULL); -} - /** * vips_tracked_malloc: * @size: number of bytes to allocate @@ -338,8 +321,6 @@ vips_tracked_malloc(size_t size) { void *buf; - vips_tracked_init(); - /* Need an extra sizeof(size_t) bytes to track * size of this block. Ask for an extra 16 to make sure we don't break * alignment rules. @@ -360,7 +341,7 @@ vips_tracked_malloc(size_t size) return NULL; } - g_mutex_lock(vips_tracked_mutex); + g_mutex_lock(&vips_tracked_mutex); *((size_t *) buf) = size; buf = (void *) ((char *) buf + 16); @@ -374,7 +355,7 @@ vips_tracked_malloc(size_t size) printf("vips_tracked_malloc: %p, %zd bytes\n", buf, size); #endif /*DEBUG_VERBOSE_MEM*/ - g_mutex_unlock(vips_tracked_mutex); + g_mutex_unlock(&vips_tracked_mutex); VIPS_GATE_MALLOC(size); @@ -404,8 +385,6 @@ vips_tracked_aligned_alloc(size_t size, size_t align) { void *buf; - vips_tracked_init(); - g_assert(!(align & (align - 1))); /* Need an extra sizeof(size_t) bytes to track @@ -437,7 +416,7 @@ vips_tracked_aligned_alloc(size_t size, size_t align) memset(buf, 0, size); - g_mutex_lock(vips_tracked_mutex); + g_mutex_lock(&vips_tracked_mutex); *((size_t *) buf) = size; @@ -450,7 +429,7 @@ vips_tracked_aligned_alloc(size_t size, size_t align) printf("vips_tracked_aligned_alloc: %p, %zd bytes\n", buf, size); #endif /*DEBUG_VERBOSE*/ - g_mutex_unlock(vips_tracked_mutex); + g_mutex_unlock(&vips_tracked_mutex); VIPS_GATE_MALLOC(size); @@ -484,9 +463,7 @@ vips_tracked_open(const char *pathname, int flags, int mode) if ((fd = vips__open(pathname, flags, mode)) == -1) return -1; - vips_tracked_init(); - - g_mutex_lock(vips_tracked_mutex); + g_mutex_lock(&vips_tracked_mutex); vips_tracked_files += 1; #ifdef DEBUG_VERBOSE_FD @@ -494,7 +471,7 @@ vips_tracked_open(const char *pathname, int flags, int mode) pathname, fd, vips_tracked_files); #endif /*DEBUG_VERBOSE_FD*/ - g_mutex_unlock(vips_tracked_mutex); + g_mutex_unlock(&vips_tracked_mutex); return fd; } @@ -519,7 +496,7 @@ vips_tracked_close(int fd) { int result; - g_mutex_lock(vips_tracked_mutex); + g_mutex_lock(&vips_tracked_mutex); /* libvips uses fd -1 to mean invalid descriptor. */ @@ -532,7 +509,7 @@ vips_tracked_close(int fd) printf(" from thread %p\n", g_thread_self()); #endif /*DEBUG_VERBOSE_FD*/ - g_mutex_unlock(vips_tracked_mutex); + g_mutex_unlock(&vips_tracked_mutex); result = close(fd); @@ -553,13 +530,11 @@ vips_tracked_get_mem(void) { size_t mem; - vips_tracked_init(); - - g_mutex_lock(vips_tracked_mutex); + g_mutex_lock(&vips_tracked_mutex); mem = vips_tracked_mem; - g_mutex_unlock(vips_tracked_mutex); + g_mutex_unlock(&vips_tracked_mutex); return mem; } @@ -578,13 +553,11 @@ vips_tracked_get_mem_highwater(void) { size_t mx; - vips_tracked_init(); - - g_mutex_lock(vips_tracked_mutex); + g_mutex_lock(&vips_tracked_mutex); mx = vips_tracked_mem_highwater; - g_mutex_unlock(vips_tracked_mutex); + g_mutex_unlock(&vips_tracked_mutex); return mx; } @@ -601,13 +574,11 @@ vips_tracked_get_allocs(void) { int n; - vips_tracked_init(); - - g_mutex_lock(vips_tracked_mutex); + g_mutex_lock(&vips_tracked_mutex); n = vips_tracked_allocs; - g_mutex_unlock(vips_tracked_mutex); + g_mutex_unlock(&vips_tracked_mutex); return n; } @@ -624,13 +595,11 @@ vips_tracked_get_files(void) { int n; - vips_tracked_init(); - - g_mutex_lock(vips_tracked_mutex); + g_mutex_lock(&vips_tracked_mutex); n = vips_tracked_files; - g_mutex_unlock(vips_tracked_mutex); + g_mutex_unlock(&vips_tracked_mutex); return n; } diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 489a2573b8..53c3525a1e 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -213,7 +213,7 @@ enum { /* Table of all objects, handy for debugging. */ static GHashTable *vips__object_all = NULL; -static GMutex *vips__object_all_lock = NULL; +static GMutex vips__object_all_lock; static guint vips_object_signals[SIG_LAST] = { 0 }; @@ -558,9 +558,9 @@ vips__argument_table_lookup(VipsArgumentTable *table, GParamSpec *pspec) { VipsArgument *argument; - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); argument = (VipsArgument *) g_hash_table_lookup(table, pspec); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); return argument; } @@ -1046,9 +1046,9 @@ vips_object_finalize(GObject *gobject) * from finalize, sadly. */ - g_mutex_lock(vips__object_all_lock); + g_mutex_lock(&vips__object_all_lock); g_hash_table_remove(vips__object_all, object); - g_mutex_unlock(vips__object_all_lock); + g_mutex_unlock(&vips__object_all_lock); G_OBJECT_CLASS(vips_object_parent_class)->finalize(gobject); } @@ -1563,11 +1563,8 @@ vips_object_class_init(VipsObjectClass *class) */ vips_check_init(); - if (!vips__object_all) { - vips__object_all = g_hash_table_new( - g_direct_hash, g_direct_equal); - vips__object_all_lock = vips_g_mutex_new(); - } + if (!vips__object_all) + vips__object_all = g_hash_table_new(g_direct_hash, g_direct_equal); gobject_class->dispose = vips_object_dispose; gobject_class->finalize = vips_object_finalize; @@ -1681,9 +1678,9 @@ vips_object_init(VipsObject *object) printf("\n"); #endif /*DEBUG*/ - g_mutex_lock(vips__object_all_lock); + g_mutex_lock(&vips__object_all_lock); g_hash_table_insert(vips__object_all, object, object); - g_mutex_unlock(vips__object_all_lock); + g_mutex_unlock(&vips__object_all_lock); } static void * @@ -1727,7 +1724,7 @@ vips_object_class_install_argument(VipsObjectClass *object_class, /* object_class->argument* is shared, so we must lock. */ - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); /* Must be a new one. */ @@ -1826,7 +1823,7 @@ vips_object_class_install_argument(VipsObjectClass *object_class, } #endif /*DEBUG*/ - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } static void @@ -2744,10 +2741,10 @@ vips_object_map(VipsSListMap2Fn fn, void *a, void *b) * only created when the first object is created. */ if (vips__object_all) { - g_mutex_lock(vips__object_all_lock); + g_mutex_lock(&vips__object_all_lock); g_hash_table_foreach(vips__object_all, (GHFunc) vips_object_map_sub, &args); - g_mutex_unlock(vips__object_all_lock); + g_mutex_unlock(&vips__object_all_lock); } return args.result; diff --git a/libvips/iofuncs/region.c b/libvips/iofuncs/region.c index a951e35388..f1a34bb6bf 100644 --- a/libvips/iofuncs/region.c +++ b/libvips/iofuncs/region.c @@ -213,9 +213,9 @@ vips_region_finalize(GObject *gobject) #endif /*VIPS_DEBUG*/ #ifdef VIPS_DEBUG - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); vips__regions_all = g_slist_remove(vips__regions_all, gobject); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); #endif /*VIPS_DEBUG*/ G_OBJECT_CLASS(vips_region_parent_class)->finalize(gobject); @@ -483,11 +483,11 @@ vips_region_init(VipsRegion *region) region->type = VIPS_REGION_NONE; #ifdef VIPS_DEBUG - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); vips__regions_all = g_slist_prepend(vips__regions_all, region); printf("vips_region_init: %d regions in vips\n", g_slist_length(vips__regions_all)); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); #endif /*VIPS_DEBUG*/ } @@ -2055,13 +2055,13 @@ vips_region_dump_all(void) { size_t alive; - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); alive = 0; printf("%d regions in vips\n", g_slist_length(vips__regions_all)); vips_slist_map2(vips__regions_all, (VipsSListMap2Fn) vips_region_dump_all_cb, &alive, NULL); printf("%gMB alive\n", alive / (1024 * 1024.0)); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } #endif /*VIPS_DEBUG*/ @@ -2073,12 +2073,12 @@ vips__region_count_pixels(VipsRegion *region, const char *nickname) VipsImagePixels *pixels = g_object_get_qdata(G_OBJECT(image), vips__image_pixels_quark); - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); if (!pixels->tpels) pixels->tpels = VIPS_IMAGE_N_PELS(image); if (!pixels->nickname) pixels->nickname = nickname; pixels->npels += region->valid.width * region->valid.height; - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } #endif /*DEBUG_LEAK*/ diff --git a/libvips/iofuncs/sinkscreen.c b/libvips/iofuncs/sinkscreen.c index d881640e72..f719d0e5ae 100644 --- a/libvips/iofuncs/sinkscreen.c +++ b/libvips/iofuncs/sinkscreen.c @@ -179,7 +179,7 @@ static gboolean render_kill = FALSE; /* All the renders with dirty tiles, and a semaphore that the bg render thread * waits on. */ -static GMutex *render_dirty_lock = NULL; +static GMutex render_dirty_lock; static GSList *render_dirty_all = NULL; static VipsSemaphore n_render_dirty_sem; @@ -232,7 +232,7 @@ render_free(Render *render) g_assert(render->ref_count == 0); #endif - g_mutex_lock(render_dirty_lock); + g_mutex_lock(&render_dirty_lock); if (g_slist_find(render_dirty_all, render)) { render_dirty_all = g_slist_remove(render_dirty_all, render); @@ -241,7 +241,7 @@ render_free(Render *render) * render_dirty_all is NULL. */ } - g_mutex_unlock(render_dirty_lock); + g_mutex_unlock(&render_dirty_lock); #if !GLIB_CHECK_VERSION(2, 58, 0) vips_g_mutex_free(render->ref_count_lock); @@ -442,26 +442,21 @@ vips__render_shutdown(void) { /* We may come here without having inited. */ - if (render_dirty_lock) { - g_mutex_lock(render_dirty_lock); + if (render_thread) { + g_mutex_lock(&render_dirty_lock); - if (render_thread) { - GThread *thread; + GThread *thread; - thread = render_thread; - render_reschedule = TRUE; - render_kill = TRUE; + thread = render_thread; + render_reschedule = TRUE; + render_kill = TRUE; - g_mutex_unlock(render_dirty_lock); + g_mutex_unlock(&render_dirty_lock); - vips_semaphore_up(&n_render_dirty_sem); + vips_semaphore_up(&n_render_dirty_sem); - (void) g_thread_join(thread); - } - else - g_mutex_unlock(render_dirty_lock); + (void) g_thread_join(thread); - VIPS_FREEF(vips_g_mutex_free, render_dirty_lock); vips_semaphore_destroy(&n_render_dirty_sem); } } @@ -477,7 +472,7 @@ render_dirty_sort(Render *a, Render *b, void *user_data) static void render_dirty_put(Render *render) { - g_mutex_lock(render_dirty_lock); + g_mutex_lock(&render_dirty_lock); if (render->dirty) { if (!g_slist_find(render_dirty_all, render)) { @@ -493,7 +488,7 @@ render_dirty_put(Render *render) } } - g_mutex_unlock(render_dirty_lock); + g_mutex_unlock(&render_dirty_lock); } static guint @@ -979,7 +974,7 @@ render_dirty_get(void) */ vips_semaphore_down(&n_render_dirty_sem); - g_mutex_lock(render_dirty_lock); + g_mutex_lock(&render_dirty_lock); /* Just take the head of the jobs list ... we sort when we add. */ @@ -995,7 +990,7 @@ render_dirty_get(void) render_dirty_all = g_slist_remove(render_dirty_all, render); } - g_mutex_unlock(render_dirty_lock); + g_mutex_unlock(&render_dirty_lock); return render; } @@ -1047,9 +1042,7 @@ static void * vips__sink_screen_once(void *data) { g_assert(!render_thread); - g_assert(!render_dirty_lock); - render_dirty_lock = vips_g_mutex_new(); vips_semaphore_init(&n_render_dirty_sem, 0, "n_render_dirty"); /* Don't use vips_thread_execute(), since this thread will only be @@ -1177,15 +1170,13 @@ vips__print_renders(void) } #endif /*VIPS_DEBUG_AMBER*/ - if (render_dirty_lock) { - g_mutex_lock(render_dirty_lock); + g_mutex_lock(&render_dirty_lock); - n_leaks += g_slist_length(render_dirty_all); - if (render_dirty_all) - printf("dirty renders\n"); + n_leaks += g_slist_length(render_dirty_all); + if (render_dirty_all) + printf("dirty renders\n"); - g_mutex_unlock(render_dirty_lock); - } + g_mutex_unlock(&render_dirty_lock); return n_leaks; } diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index d6797ae661..0b1334b3cd 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -186,9 +186,9 @@ vips_area_unref(VipsArea *area) #endif /*DEBUG*/ if (vips__leak) { - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); g_assert(g_slist_find(vips_area_all, area)); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } if (area->count == 0) { @@ -201,16 +201,16 @@ vips_area_unref(VipsArea *area) g_free(area); if (vips__leak) { - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); vips_area_all = g_slist_remove(vips_area_all, area); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } #ifdef DEBUG - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); printf("vips_area_unref: free .. total = %d\n", g_slist_length(vips_area_all)); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); #endif /*DEBUG*/ } else @@ -264,17 +264,17 @@ vips_area_new(VipsCallbackFn free_fn, void *data) area->sizeof_type = 0; if (vips__leak) { - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); vips_area_all = g_slist_prepend(vips_area_all, area); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } #ifdef DEBUG - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); printf("vips_area_new: %p count = %d (%d in total)\n", area, area->count, g_slist_length(vips_area_all)); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); #endif /*DEBUG*/ return area; diff --git a/libvips/iofuncs/window.c b/libvips/iofuncs/window.c index 43b35fab7d..6bd2ce466c 100644 --- a/libvips/iofuncs/window.c +++ b/libvips/iofuncs/window.c @@ -93,10 +93,10 @@ vips_window_unmap(VipsWindow *window) return -1; #ifdef DEBUG_TOTAL - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); total_mmap_usage -= window->length; g_assert(total_mmap_usage >= 0); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); #endif /*DEBUG_TOTAL*/ window->data = NULL; @@ -166,7 +166,7 @@ vips_window_unref(VipsWindow *window) static void trace_mmap_usage(void) { - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); { static int last_total = 0; int total = total_mmap_usage / (1024 * 1024); @@ -179,7 +179,7 @@ trace_mmap_usage(void) last_total = total; } } - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); } #endif /*DEBUG_TOTAL*/ @@ -252,11 +252,11 @@ vips_window_set(VipsWindow *window, int top, int height) vips__read_test &= window->data[0]; #ifdef DEBUG_TOTAL - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); total_mmap_usage += window->length; if (total_mmap_usage > max_mmap_usage) max_mmap_usage = total_mmap_usage; - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); trace_mmap_usage(); #endif /*DEBUG_TOTAL*/ diff --git a/libvips/morphology/morph.c b/libvips/morphology/morph.c index 6f4570e6da..b7e77750a4 100644 --- a/libvips/morphology/morph.c +++ b/libvips/morphology/morph.c @@ -506,9 +506,9 @@ vips_morph_compile_section(VipsMorph *morph, Pass *pass, gboolean first_pass) /* Some orcs seem to be unstable with many compilers active at once. */ - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); result = orc_program_compile(p); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL(result)) return -1; diff --git a/libvips/resample/reducev.cpp b/libvips/resample/reducev.cpp index 3d19cb856e..fd98398393 100644 --- a/libvips/resample/reducev.cpp +++ b/libvips/resample/reducev.cpp @@ -354,9 +354,9 @@ vips_reducev_compile_section(VipsReducev *reducev, Pass *pass, gboolean first) /* Some orcs seem to be unstable with many compilers active at once. */ - g_mutex_lock(vips__global_lock); + g_mutex_lock(&vips__global_lock); result = orc_program_compile(p); - g_mutex_unlock(vips__global_lock); + g_mutex_unlock(&vips__global_lock); if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL(result)) return -1; From 516fee518ef310af7c1d28e979f1f4db0d20e3e9 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 28 Jan 2025 11:50:29 +0100 Subject: [PATCH 051/174] morph: fix Orc path with large masks (#4365) Resolves: #4363. --- ChangeLog | 1 + libvips/morphology/morph.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0383a9c26c..ae0098ca47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,7 @@ - tiffsave: honor disc threshold during pyramid save [kleisauke] - fill_nearest: fix a leak - colour: use suggested rendering intent as fallback [kleisauke] +- morph: fix Orc path with large masks [kleisauke] 10/10/24 8.16.0 diff --git a/libvips/morphology/morph.c b/libvips/morphology/morph.c index 6f4570e6da..59f0f59c15 100644 --- a/libvips/morphology/morph.c +++ b/libvips/morphology/morph.c @@ -94,6 +94,7 @@ typedef struct { int r; /* Set previous result in this var */ int d1; /* The destination var */ + int n_const; int n_scanline; /* The associated line corresponding to the scanline. @@ -426,6 +427,7 @@ vips_morph_compile_section(VipsMorph *morph, Pass *pass, gboolean first_pass) CONST("zero", 0, 1); CONST("one", 255, 1); + pass->n_const += 2; /* Init the sum. If this is the first pass, it's a constant. If this * is a later pass, we have to init the sum from the result @@ -465,8 +467,10 @@ vips_morph_compile_section(VipsMorph *morph, Pass *pass, gboolean first_pass) */ if (x > 0) { g_snprintf(offset, 256, "c%db", x); - if (orc_program_find_var_by_name(p, offset) == -1) + if (orc_program_find_var_by_name(p, offset) == -1) { CONST(offset, morphology->in->Bands * x, 1); + pass->n_const++; + } ASM3("loadoffb", "value", source, offset); } else @@ -493,6 +497,12 @@ vips_morph_compile_section(VipsMorph *morph, Pass *pass, gboolean first_pass) ASM3("andb", "sum", "sum", "value"); } + /* orc allows up to 8 constants, so break early once we + * approach this limit. + */ + if (pass->n_const >= 7 /*ORC_MAX_CONST_VARS - 1*/) + break; + /* You can have 8 sources, and pass->r counts as one of them, * so +1 there. */ @@ -553,6 +563,7 @@ vips_morph_compile(VipsMorph *morph) pass->first = i; pass->last = i; pass->r = -1; + pass->n_const = 0; pass->n_scanline = 0; if (vips_morph_compile_section(morph, pass, morph->n_pass == 1)) From 917d6f019c043648a1d371bb31f5d5970d83d2ba Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 29 Jan 2025 15:48:56 +0100 Subject: [PATCH 052/174] colour: add support for auto-selecting the rendering intent (#4366) * colour: add support for auto-selecting the rendering intent Via the `VIPS_INTENT_AUTO` enum value. Resolves: #3475. * colour: leave room for possible new rendering intents --- ChangeLog | 1 + libvips/colour/icc_transform.c | 7 +++++-- libvips/include/vips/colour.h | 7 ++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 18cb56c99c..55109778fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ - tiffload: add support for fail_on flag [lovell] - tiffload: add support for unlimited flag (requires libtiff 4.7.0+) [lovell] - much more reliable operation caching +- colour: add support for auto-selecting the rendering intent [kleisauke] 8.16.1 diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 81e4a42469..6f0660a159 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -106,6 +106,7 @@ * @VIPS_INTENT_RELATIVE: relative colorimetric rendering intent * @VIPS_INTENT_SATURATION: saturation rendering intent * @VIPS_INTENT_ABSOLUTE: absolute colorimetric rendering intent + * @VIPS_INTENT_AUTO: the rendering intent that the profile suggests * * The rendering intent. #VIPS_INTENT_ABSOLUTE is best for * scientific work, #VIPS_INTENT_RELATIVE is usually best for @@ -620,16 +621,18 @@ vips_icc_load_profile_blob(VipsIcc *icc, VipsBlob *blob, } icc->selected_intent = icc->intent; - if (!cmsIsIntentSupported(profile, icc->intent, direction)) { + if (icc->intent == VIPS_INTENT_AUTO || + !cmsIsIntentSupported(profile, icc->intent, direction)) icc->selected_intent = (VipsIntent) cmsGetHeaderRenderingIntent( profile); + if (icc->intent != VIPS_INTENT_AUTO && + icc->selected_intent != icc->intent) g_warning(_("fallback to suggested %s intent, as profile " "does not support %s %s intent"), vips_enum_nick(VIPS_TYPE_INTENT, icc->selected_intent), vips_enum_nick(VIPS_TYPE_INTENT, icc->intent), direction == LCMS_USED_AS_INPUT ? _("input") : _("output")); - } #ifdef DEBUG vips_icc_print_profile("loaded from blob to make", profile); diff --git a/libvips/include/vips/colour.h b/libvips/include/vips/colour.h index ed52ccfe56..4433f85cfc 100644 --- a/libvips/include/vips/colour.h +++ b/libvips/include/vips/colour.h @@ -93,13 +93,18 @@ extern "C" { #define VIPS_D3250_Y0 (100.0) #define VIPS_D3250_Z0 (45.8501) -/* Note: constants align with those defined in lcms2.h. +/* Note: constants align with those defined in lcms2.h, except for + * VIPS_INTENT_AUTO, which is libvips-specific. */ typedef enum { VIPS_INTENT_PERCEPTUAL = 0, VIPS_INTENT_RELATIVE, VIPS_INTENT_SATURATION, VIPS_INTENT_ABSOLUTE, + /* Leave room for possible new rendering intents beyond the + * four standard ones. + */ + VIPS_INTENT_AUTO = 32, VIPS_INTENT_LAST } VipsIntent; From da5803e0cf6cfef134fde0289f2c7a5b834b475a Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Thu, 30 Jan 2025 12:17:45 +0000 Subject: [PATCH 053/174] Ensure g_warning messages use consistent i18n policy (#4369) Where the policy in this case, for warnings, is none --- libvips/colour/icc_transform.c | 6 +- libvips/conversion/copy.c | 3 +- libvips/create/text.c | 3 +- libvips/foreign/cgifsave.c | 3 +- libvips/foreign/exif.c | 4 +- libvips/foreign/foreign.c | 10 ++-- libvips/foreign/jpeg2vips.c | 2 +- libvips/foreign/jxlload.c | 4 +- libvips/foreign/magick.c | 8 +-- libvips/foreign/ppmsave.c | 7 +-- libvips/foreign/spngsave.c | 3 +- libvips/foreign/tiff2vips.c | 4 +- libvips/foreign/vips2jpeg.c | 24 ++++---- libvips/foreign/vips2tiff.c | 18 +++--- libvips/foreign/vipspng.c | 3 +- libvips/iofuncs/generate.c | 2 +- libvips/iofuncs/memory.c | 8 +-- libvips/mosaicing/global_balance.c | 2 +- po/de.po | 35 ------------ po/en_GB.po | 88 ------------------------------ po/malkovich.po | 4 -- tools/vips.c | 4 +- tools/vipsthumbnail.c | 5 +- 23 files changed, 53 insertions(+), 197 deletions(-) diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 6f0660a159..7723938700 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -616,7 +616,7 @@ vips_icc_load_profile_blob(VipsIcc *icc, VipsBlob *blob, data = vips_blob_get(blob, &size); if (!(profile = cmsOpenProfileFromMem(data, size))) { - g_warning("%s", _("corrupt profile")); + g_warning("corrupt profile"); return NULL; } @@ -640,14 +640,14 @@ vips_icc_load_profile_blob(VipsIcc *icc, VipsBlob *blob, if (!(info = vips_icc_info(cmsGetColorSpace(profile)))) { VIPS_FREEF(cmsCloseProfile, profile); - g_warning("%s", _("unsupported profile")); + g_warning("unsupported profile"); return NULL; } if (image && !vips_image_is_profile_compatible(image, info->bands)) { VIPS_FREEF(cmsCloseProfile, profile); - g_warning("%s", _("profile incompatible with image")); + g_warning("profile incompatible with image"); return NULL; } diff --git a/libvips/conversion/copy.c b/libvips/conversion/copy.c index c8cfadbb35..288cbeccca 100644 --- a/libvips/conversion/copy.c +++ b/libvips/conversion/copy.c @@ -178,8 +178,7 @@ vips_copy_build(VipsObject *object) return -1; if (copy->swap) - g_warning("%s", - _("copy swap is deprecated, use byteswap instead")); + g_warning("copy swap is deprecated, use byteswap instead"); if (vips_image_pipelinev(conversion->out, VIPS_DEMAND_STYLE_THINSTRIP, copy->in, NULL)) diff --git a/libvips/create/text.c b/libvips/create/text.c index e1454da350..db380d4cc3 100644 --- a/libvips/create/text.c +++ b/libvips/create/text.c @@ -440,8 +440,7 @@ vips_text_build(VipsObject *object) } #else /*!HAVE_FONTCONFIG*/ if (text->fontfile) - g_warning("%s", - _("ignoring fontfile (no fontconfig support)")); + g_warning("ignoring fontfile (no fontconfig support)"); #endif /*HAVE_FONTCONFIG*/ /* If our caller set height and not dpi, we adjust dpi until diff --git a/libvips/foreign/cgifsave.c b/libvips/foreign/cgifsave.c index cc72a985dc..f73ea50229 100644 --- a/libvips/foreign/cgifsave.c +++ b/libvips/foreign/cgifsave.c @@ -683,8 +683,7 @@ vips_foreign_save_cgif_write_frame(VipsForeignSaveCgif *cgif) #ifdef HAVE_CGIF_FRAME_ATTR_INTERLACED frame_config.attrFlags |= CGIF_FRAME_ATTR_INTERLACED; #else /*!HAVE_CGIF_FRAME_ATTR_INTERLACED*/ - g_warning("%s: cgif >= v0.3.0 required for interlaced GIF write", - class->nickname); + g_warning("cgif >= v0.3.0 required for interlaced GIF write"); #endif /*HAVE_CGIF_FRAME_ATTR_INTERLACED*/ } diff --git a/libvips/foreign/exif.c b/libvips/foreign/exif.c index a73afbf85e..13c00d6dc9 100644 --- a/libvips/foreign/exif.c +++ b/libvips/foreign/exif.c @@ -491,7 +491,7 @@ vips_image_resolution_from_exif(VipsImage *image, ExifData *ed) break; default: - g_warning("%s", _("unknown EXIF resolution unit")); + g_warning("unknown EXIF resolution unit"); return -1; } @@ -1066,7 +1066,7 @@ vips_exif_resolution_from_image(ExifData *ed, VipsImage *image) break; default: - g_warning("%s", _("unknown EXIF resolution unit")); + g_warning("unknown EXIF resolution unit"); return 0; } diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 01de82b2ca..861e9ab55f 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1093,9 +1093,8 @@ vips_foreign_load_build(VipsObject *object) if ((flags & VIPS_FOREIGN_PARTIAL) && (flags & VIPS_FOREIGN_SEQUENTIAL)) { - g_warning("%s", - _("VIPS_FOREIGN_PARTIAL and VIPS_FOREIGN_SEQUENTIAL " - "both set -- using SEQUENTIAL")); + g_warning("VIPS_FOREIGN_PARTIAL and VIPS_FOREIGN_SEQUENTIAL " + "both set -- using SEQUENTIAL"); flags ^= VIPS_FOREIGN_PARTIAL; } @@ -1121,9 +1120,8 @@ vips_foreign_load_build(VipsObject *object) return -1; if (load->sequential) - g_warning("%s", - _("ignoring deprecated \"sequential\" mode -- " - "please use \"access\" instead")); + g_warning("ignoring deprecated \"sequential\" mode -- " + "please use \"access\" instead"); g_object_set(object, "out", vips_image_new(), NULL); diff --git a/libvips/foreign/jpeg2vips.c b/libvips/foreign/jpeg2vips.c index 2a4c28d60d..5fc88a79b5 100644 --- a/libvips/foreign/jpeg2vips.c +++ b/libvips/foreign/jpeg2vips.c @@ -654,7 +654,7 @@ read_jpeg_header(ReadJpeg *jpeg, VipsImage *out) break; default: - g_warning("%s", _("unknown JFIF resolution unit")); + g_warning("unknown JFIF resolution unit"); break; } diff --git a/libvips/foreign/jxlload.c b/libvips/foreign/jxlload.c index 446950d7af..dad4b6f1d9 100644 --- a/libvips/foreign/jxlload.c +++ b/libvips/foreign/jxlload.c @@ -643,7 +643,7 @@ vips_foreign_load_jxl_fix_exif(VipsForeignLoadJxl *jxl) return 0; if (jxl->exif_size < 4) { - g_warning("%s: invalid data in EXIF box", class->nickname); + g_warning("invalid data in EXIF box"); return -1; } @@ -651,7 +651,7 @@ vips_foreign_load_jxl_fix_exif(VipsForeignLoadJxl *jxl) */ size_t offset = GUINT32_FROM_BE(*((guint32 *) jxl->exif_data)); if (offset > jxl->exif_size - 4) { - g_warning("%s: invalid data in EXIF box", class->nickname); + g_warning("invalid data in EXIF box"); return -1; } diff --git a/libvips/foreign/magick.c b/libvips/foreign/magick.c index f4e39ce3b4..59f83ec734 100644 --- a/libvips/foreign/magick.c +++ b/libvips/foreign/magick.c @@ -654,8 +654,8 @@ magick_optimize_image_layers(Image **images, ExceptionInfo *exception) return MagickTrue; #else /*!HAVE_OPTIMIZEPLUSIMAGELAYERS*/ - g_warning("%s", _("layer optimization is not supported by " - "your version of libMagick")); + g_warning("layer optimization is not supported by " + "your version of libMagick"); return MagickTrue; #endif /*HAVE_OPTIMIZEPLUSIMAGELAYERS*/ @@ -670,8 +670,8 @@ magick_optimize_image_transparency(const Image *images, return exception->severity == UndefinedException; #else /*!HAVE_OPTIMIZEIMAGETRANSPARENCY*/ - g_warning("%s", _("transparency optimization is not supported by " - "your version of libMagick")); + g_warning("transparency optimization is not supported by " + "your version of libMagick"); return MagickTrue; #endif /*HAVE_OPTIMIZEIMAGETRANSPARENCY*/ diff --git a/libvips/foreign/ppmsave.c b/libvips/foreign/ppmsave.c index 57e6cc5631..b8f8872611 100644 --- a/libvips/foreign/ppmsave.c +++ b/libvips/foreign/ppmsave.c @@ -335,7 +335,7 @@ vips_foreign_save_ppm_build(VipsObject *object) if (ppm->ascii && image->BandFmt == VIPS_FORMAT_FLOAT) { - g_warning("%s", _("float images must be binary -- disabling ascii")); + g_warning("float images must be binary -- disabling ascii"); ppm->ascii = FALSE; } @@ -344,9 +344,8 @@ vips_foreign_save_ppm_build(VipsObject *object) if (ppm->bitdepth && (image->Bands != 1 || image->BandFmt != VIPS_FORMAT_UCHAR)) { - g_warning("%s", - _("can only save 1 band uchar images as 1 bit -- " - "disabling 1 bit save")); + g_warning("can only save 1 band uchar images as 1 bit -- " + "disabling 1 bit save"); ppm->bitdepth = 0; } diff --git a/libvips/foreign/spngsave.c b/libvips/foreign/spngsave.c index 10ecbb30c2..12762117c5 100644 --- a/libvips/foreign/spngsave.c +++ b/libvips/foreign/spngsave.c @@ -431,8 +431,7 @@ vips_foreign_save_spng_write(VipsForeignSaveSpng *spng, VipsImage *in) ihdr.color_type = SPNG_COLOR_TYPE_INDEXED; #else if (spng->palette) - g_warning("%s", - _("ignoring palette (no quantisation support)")); + g_warning("ignoring palette (no quantisation support)"); #endif /*HAVE_QUANTIZATION*/ ihdr.compression_method = 0; diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index a3ecdcbb45..fb7b4eba86 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -1621,7 +1621,7 @@ rtiff_parse_palette(Rtiff *rtiff, VipsImage *out) read->blue8[i] = read->blue16[i] >> 8; } else { - g_warning("%s", _("assuming 8-bit palette")); + g_warning("assuming 8-bit palette"); for (i = 0; i < len; i++) { read->red8[i] = read->red16[i] & 0xff; @@ -3330,7 +3330,7 @@ rtiff_header_read(Rtiff *rtiff, RtiffHeader *header) for (i = 0; i < extra_samples_count; i++) if (extra_samples_types[i] == EXTRASAMPLE_ASSOCALPHA) { if (header->alpha_band != -1) - g_warning("%s", _("more than one alpha -- ignoring")); + g_warning("more than one alpha -- ignoring"); header->alpha_band = header->samples_per_pixel - extra_samples_count + i; diff --git a/libvips/foreign/vips2jpeg.c b/libvips/foreign/vips2jpeg.c index abeb2e537d..0388d43111 100644 --- a/libvips/foreign/vips2jpeg.c +++ b/libvips/foreign/vips2jpeg.c @@ -314,7 +314,7 @@ write_xmp(Write *write, VipsImage *in) * error with large chunks. */ if (data_length > 60000) { - g_warning("%s", _("VipsJpeg: large XMP not saved")); + g_warning("large XMP not saved"); return 0; } @@ -607,7 +607,7 @@ set_cinfo(struct jpeg_compress_struct *cinfo, cinfo->optimize_coding = TRUE; } else - g_warning("%s", _("trellis_quant unsupported")); + g_warning("trellis_quant unsupported"); } /* Apply overshooting to samples with extreme values e.g. 0 & 255 @@ -619,8 +619,7 @@ set_cinfo(struct jpeg_compress_struct *cinfo, jpeg_c_set_bool_param(cinfo, JBOOLEAN_OVERSHOOT_DERINGING, TRUE); else - g_warning("%s", - _("overshoot_deringing unsupported")); + g_warning("overshoot_deringing unsupported"); } /* Split the spectrum of DCT coefficients into separate scans. @@ -634,12 +633,10 @@ set_cinfo(struct jpeg_compress_struct *cinfo, jpeg_c_set_bool_param(cinfo, JBOOLEAN_OPTIMIZE_SCANS, TRUE); else - g_warning("%s", - _("ignoring optimize_scans")); + g_warning("ignoring optimize_scans"); } else - g_warning("%s", - _("ignoring optimize_scans for baseline")); + g_warning("ignoring optimize_scans for baseline"); } /* Use predefined quantization table. @@ -650,21 +647,20 @@ set_cinfo(struct jpeg_compress_struct *cinfo, jpeg_c_set_int_param(cinfo, JINT_BASE_QUANT_TBL_IDX, quant_table); else - g_warning("%s", - _("setting quant_table unsupported")); + g_warning("setting quant_table unsupported"); } #else /* Using jpeglib.h without extension parameters, warn of ignored * options. */ if (trellis_quant) - g_warning("%s", _("ignoring trellis_quant")); + g_warning("ignoring trellis_quant"); if (overshoot_deringing) - g_warning("%s", _("ignoring overshoot_deringing")); + g_warning("ignoring overshoot_deringing"); if (optimize_scans) - g_warning("%s", _("ignoring optimize_scans")); + g_warning("ignoring optimize_scans"); if (quant_table > 0) - g_warning("%s", _("ignoring quant_table")); + g_warning("ignoring quant_table"); #endif /* Set compression quality. Must be called after setting params above. diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 7c3071d5f0..d70291bdca 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -601,7 +601,7 @@ wtiff_embed_iptc(Wtiff *wtiff, TIFF *tif) * long, not byte. */ if (size & 3) { - g_warning("%s", _("rounding up IPTC data length")); + g_warning("rounding up IPTC data length"); size /= 4; size += 1; } @@ -1480,8 +1480,7 @@ wtiff_new(VipsImage *input, VipsTarget *target, !(wtiff->bitdepth == 1 || wtiff->bitdepth == 2 || wtiff->bitdepth == 4)) { - g_warning("%s", - _("bitdepth 1, 2 or 4 only -- disabling bitdepth")); + g_warning("bitdepth 1, 2 or 4 only -- disabling bitdepth"); wtiff->bitdepth = 0; } @@ -1492,16 +1491,14 @@ wtiff_new(VipsImage *input, VipsTarget *target, !(wtiff->ready->Coding == VIPS_CODING_NONE && wtiff->ready->BandFmt == VIPS_FORMAT_UCHAR && wtiff->ready->Bands == 1)) { - g_warning("%s", - ("can only set bitdepth for 1-band uchar and " - "3-band float lab -- disabling bitdepth")); + g_warning("can only set bitdepth for 1-band uchar and " + "3-band float lab -- disabling bitdepth"); wtiff->bitdepth = 0; } if (wtiff->bitdepth && wtiff->compression == COMPRESSION_JPEG) { - g_warning("%s", - _("can't have <8 bit JPEG -- disabling JPEG")); + g_warning("can't have <8 bit JPEG -- disabling JPEG"); wtiff->compression = COMPRESSION_NONE; } @@ -1511,9 +1508,8 @@ wtiff_new(VipsImage *input, VipsTarget *target, (wtiff->ready->Coding != VIPS_CODING_NONE || vips_band_format_iscomplex(wtiff->ready->BandFmt) || wtiff->ready->Bands > 2)) { - g_warning("%s", - _("can only save non-complex greyscale images " - "as miniswhite -- disabling miniswhite")); + g_warning("can only save non-complex greyscale images " + "as miniswhite -- disabling miniswhite"); wtiff->miniswhite = FALSE; } diff --git a/libvips/foreign/vipspng.c b/libvips/foreign/vipspng.c index b5dc7a8bae..d3286ad7e5 100644 --- a/libvips/foreign/vipspng.c +++ b/libvips/foreign/vipspng.c @@ -1149,8 +1149,7 @@ write_vips(Write *write, color_type = PNG_COLOR_TYPE_PALETTE; #else if (palette) - g_warning("%s", - _("ignoring palette (no quantisation support)")); + g_warning("ignoring palette (no quantisation support)"); #endif /*HAVE_QUANTIZATION*/ interlace_type = interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE; diff --git a/libvips/iofuncs/generate.c b/libvips/iofuncs/generate.c index d087ea3feb..6f3b991b71 100644 --- a/libvips/iofuncs/generate.c +++ b/libvips/iofuncs/generate.c @@ -421,7 +421,7 @@ vips_image_pipelinev(VipsImage *image, VipsDemandStyle hint, ...) ; va_end(ap); if (i == MAX_IMAGES) { - g_warning("%s", _("too many images")); + g_warning("too many images"); /* Make sure we have a sentinel there. */ diff --git a/libvips/iofuncs/memory.c b/libvips/iofuncs/memory.c index 3ac06db669..1c3b500a52 100644 --- a/libvips/iofuncs/memory.c +++ b/libvips/iofuncs/memory.c @@ -245,9 +245,9 @@ vips_tracked_free(void *s) #endif /*DEBUG_VERBOSE_MEM*/ if (vips_tracked_allocs <= 0) - g_warning("%s", _("vips_free: too many frees")); + g_warning("vips_free: too many frees"); if (vips_tracked_mem < size) - g_warning("%s", _("vips_free: too much free")); + g_warning("vips_free: too much free"); vips_tracked_mem -= size; vips_tracked_allocs -= 1; @@ -282,9 +282,9 @@ vips_tracked_aligned_free(void *s) #endif /*DEBUG_VERBOSE*/ if (vips_tracked_allocs <= 0) - g_warning("%s", _("vips_free: too many frees")); + g_warning("vips_free: too many frees"); if (vips_tracked_mem < size) - g_warning("%s", _("vips_free: too much free")); + g_warning("vips_free: too much free"); vips_tracked_mem -= size; vips_tracked_allocs -= 1; diff --git a/libvips/mosaicing/global_balance.c b/libvips/mosaicing/global_balance.c index b7f39d5253..5052e788ec 100644 --- a/libvips/mosaicing/global_balance.c +++ b/libvips/mosaicing/global_balance.c @@ -1103,7 +1103,7 @@ find_image_stats(VipsImage *mem, #ifdef DEBUG if (count == 0) - g_warning("global_balance %s", _("empty overlap!")); + g_warning("global_balance empty overlap"); #endif /*DEBUG*/ return t[4]; diff --git a/po/de.po b/po/de.po index a42e64f172..b50b9d2344 100644 --- a/po/de.po +++ b/po/de.po @@ -1832,14 +1832,6 @@ msgstr "Lesen ergab %ld Warnungen" msgid "error reading resolution" msgstr "Fehler beim Lesen der Auflösung" -#: libvips/foreign/jpeg2vips.c:510 -msgid "unknown EXIF resolution unit" -msgstr "unbekannte EXIF-Auflösungseinheit" - -#: libvips/foreign/jpeg2vips.c:718 -msgid "unknown JFIF resolution unit" -msgstr "unbekannte JFIF-Auflösungseinheit" - #: libvips/foreign/fits.c:240 msgid "dimensions above 3 must be size 1" msgstr "Dimensionen größer drei müssen die Größe eins haben" @@ -1933,10 +1925,6 @@ msgid "can only pyramid LABQ and non-complex images" msgstr "" "nur LABQ und nicht-komplexe Bilder können pyramidenartig verwendet werden" -#: libvips/foreign/vips2tiff.c:1285 -msgid "can't have 1-bit JPEG -- disabling JPEG" -msgstr "1-Bit-JPEG nicht möglich – JPEG wird ausgeschaltet" - #: libvips/foreign/vips2tiff.c:1463 msgid "unsigned 8-bit int, 16-bit int, and 32-bit float only" msgstr "nur vorzeichenlose 8-Bit-Ganzzahl und 32-Bit-Fließkommazahl" @@ -2024,13 +2012,6 @@ msgstr "»%s« ist kein bekanntes Dateiformat" msgid "images do not match" msgstr "Bilder passen nicht zusammen" -#: libvips/foreign/foreign.c:826 -msgid "" -"VIPS_FOREIGN_PARTIAL and VIPS_FOREIGN_SEQUENTIAL both set -- using SEQUENTIAL" -msgstr "" -"sowohl VIPS_FOREIGN_PARTIAL als auch VIPS_FOREIGN_SEQUENTIAL setzen – " -"verwenden Sie SEQUENTIAL" - #: libvips/foreign/foreign.c:894 msgid "file loaders" msgstr "Dateilader" @@ -2234,14 +2215,6 @@ msgstr "»start«-Funktion für Bild »%s« fehlgeschlagen" msgid "per-thread state for sink" msgstr "Status pro Thread für »sink«" -#: libvips/iofuncs/memory.c:231 -msgid "vips_free: too many frees" -msgstr "vips_free: zu viele Frees" - -#: libvips/iofuncs/memory.c:235 -msgid "vips_free: too much free" -msgstr "vips_free: zu viel frei" - #: libvips/iofuncs/memory.c:295 libvips/iofuncs/memory.c:298 #, c-format msgid "out of memory --- size == %dMB" @@ -2302,10 +2275,6 @@ msgstr "Daten für »%s« können nicht gelesen werden, %s" msgid "error reading XML: %s" msgstr "Fehler beim Lesen von XML: %s" -#: libvips/iofuncs/generate.c:343 libvips/iofuncs/header.c:611 -msgid "too many images" -msgstr "zu viele Bilder" - #: libvips/iofuncs/generate.c:606 msgid "demand hint not set" msgstr "Hinweisanfrage nicht gesetzt" @@ -3105,10 +3074,6 @@ msgstr "" msgid "more than one root" msgstr "mehr als eine Wurzel" -#: libvips/mosaicing/global_balance.c:1053 -msgid "empty overlap!" -msgstr "leere Überlappung!" - #: libvips/mosaicing/im_avgdxdy.c:64 msgid "no points to average" msgstr "keine Punkte zum Mitteln" diff --git a/po/en_GB.po b/po/en_GB.po index de7c19c669..8a779a3d34 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -1189,10 +1189,6 @@ msgstr "" msgid "Background value" msgstr "" -#: ../libvips/conversion/copy.c:181 -msgid "copy swap is deprecated, use byteswap instead" -msgstr "" - #: ../libvips/conversion/copy.c:235 msgid "must not change pel size" msgstr "" @@ -2638,16 +2634,6 @@ msgstr "" msgid "images do not match" msgstr "" -#: ../libvips/foreign/foreign.c:880 -msgid "" -"VIPS_FOREIGN_PARTIAL and VIPS_FOREIGN_SEQUENTIAL both set -- using SEQUENTIAL" -msgstr "" - -#: ../libvips/foreign/foreign.c:900 -msgid "" -"ignoring deprecated \"sequential\" mode -- please use \"access\" instead" -msgstr "" - #: ../libvips/foreign/foreign.c:979 msgid "file loaders" msgstr "" @@ -2730,10 +2716,6 @@ msgstr "" msgid "write error" msgstr "" -#: ../libvips/foreign/ppm.c:803 -msgid "float images must be binary -- disabling ascii" -msgstr "" - #: ../libvips/foreign/ppm.c:813 ../libvips/foreign/vips2tiff.c:1001 msgid "can only squash 1 band uchar images -- disabling squash" msgstr "" @@ -3262,38 +3244,6 @@ msgstr "" msgid "field \"%s\" is too large for a single JPEG marker, ignoring" msgstr "" -#: ../libvips/foreign/vips2jpeg.c:496 -msgid "trellis_quant unsupported" -msgstr "" - -#: ../libvips/foreign/vips2jpeg.c:509 -msgid "overshoot_deringing unsupported" -msgstr "" - -#: ../libvips/foreign/vips2jpeg.c:523 ../libvips/foreign/vips2jpeg.c:550 -msgid "ignoring optimize_scans" -msgstr "" - -#: ../libvips/foreign/vips2jpeg.c:527 -msgid "ignoring optimize_scans for baseline" -msgstr "" - -#: ../libvips/foreign/vips2jpeg.c:539 -msgid "setting quant_table unsupported" -msgstr "" - -#: ../libvips/foreign/vips2jpeg.c:546 -msgid "ignoring trellis_quant" -msgstr "" - -#: ../libvips/foreign/vips2jpeg.c:548 -msgid "ignoring overshoot_deringing" -msgstr "" - -#: ../libvips/foreign/vips2jpeg.c:552 -msgid "ignoring quant_table" -msgstr "" - #: ../libvips/foreign/ppmload.c:119 msgid "load ppm from file" msgstr "" @@ -3492,10 +3442,6 @@ msgstr "" msgid "unable to init exif" msgstr "" -#: ../libvips/foreign/exif.c:413 ../libvips/foreign/exif.c:788 -msgid "unknown EXIF resolution unit" -msgstr "" - #: ../libvips/foreign/exif.c:918 ../libvips/foreign/exif.c:928 #: ../libvips/foreign/exif.c:933 #, c-format @@ -3642,10 +3588,6 @@ msgstr "" msgid "read gave %ld warnings" msgstr "" -#: ../libvips/foreign/jpeg2vips.c:387 -msgid "unknown JFIF resolution unit" -msgstr "" - #: ../libvips/foreign/tiffsave.c:172 ../libvips/foreign/tiffsave.c:358 msgid "save image to tiff file" msgstr "" @@ -4154,16 +4096,6 @@ msgstr "" msgid "can only pyramid LABQ and non-complex images" msgstr "" -#: ../libvips/foreign/vips2tiff.c:1009 -msgid "can't have 1-bit JPEG -- disabling JPEG" -msgstr "" - -#: ../libvips/foreign/vips2tiff.c:1020 -msgid "" -"can only save non-complex greyscale images as miniswhite -- disabling " -"miniswhite" -msgstr "" - #: ../libvips/foreign/vips2tiff.c:1043 msgid "image over 4gb, enabling bigtiff" msgstr "" @@ -4717,10 +4649,6 @@ msgstr "" msgid "per-thread state for sinkmemory" msgstr "" -#: ../libvips/iofuncs/generate.c:425 -msgid "too many images" -msgstr "" - #: ../libvips/iofuncs/generate.c:690 msgid "demand hint not set" msgstr "" @@ -5188,14 +5116,6 @@ msgstr "" msgid "unable to form filename" msgstr "" -#: ../libvips/iofuncs/memory.c:251 -msgid "vips_free: too many frees" -msgstr "" - -#: ../libvips/iofuncs/memory.c:253 -msgid "vips_free: too much free" -msgstr "" - #: ../libvips/iofuncs/sinkscreen.c:188 msgid "per-thread state for render" msgstr "" @@ -5555,10 +5475,6 @@ msgstr "" msgid "more than one root" msgstr "" -#: ../libvips/mosaicing/global_balance.c:1060 -msgid "empty overlap!" -msgstr "" - #: ../libvips/mosaicing/global_balance.c:1783 msgid "gamma" msgstr "" @@ -6317,10 +6233,6 @@ msgstr "" msgid "- thumbnail generator" msgstr "" -#: ../tools/vipsthumbnail.c:406 -msgid "auto-rotate disabled: libvips built without exif support" -msgstr "" - #: ../libvips/resample/reduceh.cpp:457 msgid "reduce factors should be >= 1" msgstr "" diff --git a/po/malkovich.po b/po/malkovich.po index b3ac40294b..25dcebc88b 100644 --- a/po/malkovich.po +++ b/po/malkovich.po @@ -386,10 +386,6 @@ msgstr "" msgid "can only pyramid LABQ and non-complex images" msgstr "" -#: libsrc/conversion/im_vips2tiff.c:1372 -msgid "can't have 1-bit JPEG -- disabling JPEG" -msgstr "" - #: libsrc/conversion/im_vips2tiff.c:1529 #, fuzzy msgid "unknown coding type" diff --git a/tools/vips.c b/tools/vips.c index 5abc6193a1..d3af6c35e2 100644 --- a/tools/vips.c +++ b/tools/vips.c @@ -774,8 +774,8 @@ main(int argc, char **argv) } #endif /*ENABLE_DEPRECATED*/ #else /*!ENABLE_MODULES*/ - g_warning("%s", _("plugin load disabled: " - "libvips built without modules support")); + g_warning("plugin load disabled: " + "libvips built without modules support"); #endif /*ENABLE_MODULES*/ } diff --git a/tools/vipsthumbnail.c b/tools/vipsthumbnail.c index ce90bee00a..f94258ba62 100644 --- a/tools/vipsthumbnail.c +++ b/tools/vipsthumbnail.c @@ -546,9 +546,8 @@ main(int argc, char **argv) #ifndef HAVE_EXIF if (rotate_image) - g_warning("%s", - _("auto-rotate disabled: " - "libvips built without exif support")); + g_warning("auto-rotate disabled: " + "libvips built without exif support"); #endif /*!HAVE_EXIF*/ result = 0; From fe3d3a96e3b15e644c3c23f6f36de1814c5cc8e1 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Thu, 30 Jan 2025 17:10:25 +0000 Subject: [PATCH 054/174] i18n: refresh translations (#4370) * Apply clang-format to commit da5803e * i18n: refresh translations via vips8.17-update-po build target --- libvips/foreign/foreign.c | 4 +- libvips/foreign/magick.c | 4 +- libvips/foreign/ppmsave.c | 2 +- libvips/foreign/vips2tiff.c | 4 +- po/de.po | 10672 +++++++++++++++++++++++++--------- po/en_GB.po | 7973 ++++++++++++++----------- tools/vips.c | 2 +- tools/vipsthumbnail.c | 2 +- 8 files changed, 12650 insertions(+), 6013 deletions(-) diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 861e9ab55f..34cc1aecce 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1094,7 +1094,7 @@ vips_foreign_load_build(VipsObject *object) if ((flags & VIPS_FOREIGN_PARTIAL) && (flags & VIPS_FOREIGN_SEQUENTIAL)) { g_warning("VIPS_FOREIGN_PARTIAL and VIPS_FOREIGN_SEQUENTIAL " - "both set -- using SEQUENTIAL"); + "both set -- using SEQUENTIAL"); flags ^= VIPS_FOREIGN_PARTIAL; } @@ -1121,7 +1121,7 @@ vips_foreign_load_build(VipsObject *object) if (load->sequential) g_warning("ignoring deprecated \"sequential\" mode -- " - "please use \"access\" instead"); + "please use \"access\" instead"); g_object_set(object, "out", vips_image_new(), NULL); diff --git a/libvips/foreign/magick.c b/libvips/foreign/magick.c index 59f83ec734..81beac36d8 100644 --- a/libvips/foreign/magick.c +++ b/libvips/foreign/magick.c @@ -655,7 +655,7 @@ magick_optimize_image_layers(Image **images, ExceptionInfo *exception) return MagickTrue; #else /*!HAVE_OPTIMIZEPLUSIMAGELAYERS*/ g_warning("layer optimization is not supported by " - "your version of libMagick"); + "your version of libMagick"); return MagickTrue; #endif /*HAVE_OPTIMIZEPLUSIMAGELAYERS*/ @@ -671,7 +671,7 @@ magick_optimize_image_transparency(const Image *images, return exception->severity == UndefinedException; #else /*!HAVE_OPTIMIZEIMAGETRANSPARENCY*/ g_warning("transparency optimization is not supported by " - "your version of libMagick"); + "your version of libMagick"); return MagickTrue; #endif /*HAVE_OPTIMIZEIMAGETRANSPARENCY*/ diff --git a/libvips/foreign/ppmsave.c b/libvips/foreign/ppmsave.c index b8f8872611..d4b979177f 100644 --- a/libvips/foreign/ppmsave.c +++ b/libvips/foreign/ppmsave.c @@ -345,7 +345,7 @@ vips_foreign_save_ppm_build(VipsObject *object) (image->Bands != 1 || image->BandFmt != VIPS_FORMAT_UCHAR)) { g_warning("can only save 1 band uchar images as 1 bit -- " - "disabling 1 bit save"); + "disabling 1 bit save"); ppm->bitdepth = 0; } diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index d70291bdca..36d98d90b7 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -1492,7 +1492,7 @@ wtiff_new(VipsImage *input, VipsTarget *target, wtiff->ready->BandFmt == VIPS_FORMAT_UCHAR && wtiff->ready->Bands == 1)) { g_warning("can only set bitdepth for 1-band uchar and " - "3-band float lab -- disabling bitdepth"); + "3-band float lab -- disabling bitdepth"); wtiff->bitdepth = 0; } @@ -1509,7 +1509,7 @@ wtiff_new(VipsImage *input, VipsTarget *target, vips_band_format_iscomplex(wtiff->ready->BandFmt) || wtiff->ready->Bands > 2)) { g_warning("can only save non-complex greyscale images " - "as miniswhite -- disabling miniswhite"); + "as miniswhite -- disabling miniswhite"); wtiff->miniswhite = FALSE; } diff --git a/po/de.po b/po/de.po index b50b9d2344..abc4bcbb58 100644 --- a/po/de.po +++ b/po/de.po @@ -7,9 +7,8 @@ # msgid "" msgstr "" -"Project-Id-Version: libvips-doc 7.36.5-1\n" -"Report-Msgid-Bugs-To: VIPSIP@JISCMAIL.AC.UK\n" -"POT-Creation-Date: 2012-03-08 21:02+0000\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-01-30 14:51+0000\n" "PO-Revision-Date: 2014-03-12 21:58+0100\n" "Last-Translator: Chris Leick \n" "Language-Team: Debian German \n" @@ -19,3443 +18,8796 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: libvips/arithmetic/abs.c:215 # http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=0650& # db=man&fname=/usr/share/catman/p_man/cat3/il_c/ilAbsImg.z +#: libvips/arithmetic/abs.c:200 msgid "absolute value of an image" msgstr "absoluter Wert eines Bildes" -#: libvips/arithmetic/statistic.c:147 -msgid "VIPS statistic operations" -msgstr "statistische VIPS-Transaktionen" +#: libvips/arithmetic/add.c:178 +msgid "add two images" +msgstr "zwei Bilder hinzufügen" -#: libvips/arithmetic/statistic.c:151 libvips/arithmetic/unary.c:87 -#: libvips/conversion/bandmean.c:197 libvips/conversion/cast.c:474 -#: libvips/conversion/tilecache.c:422 libvips/conversion/extract.c:194 -#: libvips/conversion/extract.c:353 libvips/conversion/embed.c:516 -#: libvips/conversion/rot.c:355 libvips/conversion/flip.c:240 -#: libvips/conversion/copy.c:318 libvips/conversion/recomb.c:200 -#: libvips/conversion/replicate.c:196 libvips/conversion/cache.c:106 -#: libvips/conversion/bandjoin.c:171 libvips/foreign/foreign.c:1379 -msgid "Input" -msgstr "Eingabe" +#: libvips/arithmetic/arithmetic.c:392 +#, c-format +msgid "not one band or %d bands" +msgstr "nicht ein Band oder %d Bänder" -#: libvips/arithmetic/statistic.c:152 libvips/conversion/cast.c:475 -#: libvips/conversion/tilecache.c:423 libvips/conversion/extract.c:195 -#: libvips/conversion/extract.c:354 libvips/conversion/embed.c:517 -#: libvips/conversion/rot.c:356 libvips/conversion/flip.c:241 -#: libvips/conversion/copy.c:319 libvips/conversion/replicate.c:197 -#: libvips/conversion/cache.c:107 -msgid "Input image" -msgstr "Eingabebild" +#: libvips/arithmetic/arithmetic.c:397 libvips/foreign/spngsave.c:423 +msgid "bad bands" +msgstr "falsche Bänder" -#: libvips/arithmetic/im_point_bilinear.c:74 -msgid "coords outside image" -msgstr "Koordinaten außerhalb des Bildes" +#: libvips/arithmetic/arithmetic.c:725 +msgid "arithmetic operations" +msgstr "arithmetische Transaktionen" -#. Name -#: libvips/arithmetic/arith_dispatch.c:298 -msgid "absolute value" -msgstr "absoluter Wert" +#: libvips/arithmetic/arithmetic.c:731 libvips/arithmetic/avg.c:235 +#: libvips/arithmetic/deviate.c:237 libvips/arithmetic/hist_find.c:431 +#: libvips/arithmetic/hist_find_indexed.c:475 +#: libvips/arithmetic/hist_find_ndim.c:313 libvips/arithmetic/hough.c:179 +#: libvips/arithmetic/max.c:452 libvips/arithmetic/measure.c:201 +#: libvips/arithmetic/min.c:452 libvips/arithmetic/stats.c:442 +#: libvips/colour/CMYK2XYZ.c:126 libvips/colour/colour.c:415 +#: libvips/colour/colourspace.c:563 libvips/colour/scRGB2BW.c:243 +#: libvips/colour/scRGB2sRGB.c:276 libvips/colour/scRGB2XYZ.c:197 +#: libvips/colour/sRGB2scRGB.c:294 libvips/colour/XYZ2CMYK.c:125 +#: libvips/colour/XYZ2scRGB.c:206 libvips/conversion/conversion.c:346 +#: libvips/conversion/switch.c:202 libvips/convolution/canny.c:448 +#: libvips/convolution/convolution.c:134 libvips/convolution/correlation.c:162 +#: libvips/convolution/edge.c:223 libvips/convolution/gaussblur.c:138 +#: libvips/convolution/sharpen.c:328 libvips/create/create.c:124 +#: libvips/foreign/foreign.c:1215 libvips/freqfilt/freqfilt.c:104 +#: libvips/histogram/case.c:252 libvips/histogram/hist_entropy.c:117 +#: libvips/histogram/hist_equal.c:120 libvips/histogram/hist_local.c:367 +#: libvips/histogram/hist_norm.c:147 libvips/histogram/histogram.c:232 +#: libvips/histogram/hist_plot.c:339 libvips/histogram/maplut.c:750 +#: libvips/histogram/stdif.c:300 libvips/iofuncs/system.c:284 +#: libvips/morphology/morph.c:959 libvips/morphology/rank.c:564 +#: libvips/mosaicing/global_balance.c:1930 libvips/mosaicing/match.c:208 +#: libvips/mosaicing/matrixinvert.c:449 libvips/mosaicing/merge.c:134 +#: libvips/mosaicing/mosaic1.c:510 libvips/mosaicing/mosaic.c:191 +#: libvips/mosaicing/remosaic.c:170 libvips/resample/resample.c:146 +#: libvips/resample/thumbnail.c:968 +msgid "Output" +msgstr "Ausgabe" -#. Name -#: libvips/arithmetic/arith_dispatch.c:317 libvips/arithmetic/add.c:186 -msgid "add two images" -msgstr "zwei Bilder hinzufügen" +#: libvips/arithmetic/arithmetic.c:732 libvips/arithmetic/hough.c:180 +#: libvips/colour/CMYK2XYZ.c:127 libvips/colour/colour.c:416 +#: libvips/colour/colourspace.c:564 libvips/colour/scRGB2BW.c:244 +#: libvips/colour/scRGB2sRGB.c:277 libvips/colour/scRGB2XYZ.c:198 +#: libvips/colour/sRGB2scRGB.c:295 libvips/colour/XYZ2CMYK.c:126 +#: libvips/colour/XYZ2scRGB.c:207 libvips/conversion/conversion.c:347 +#: libvips/conversion/switch.c:203 libvips/convolution/canny.c:449 +#: libvips/convolution/convolution.c:135 libvips/convolution/correlation.c:163 +#: libvips/convolution/edge.c:224 libvips/convolution/gaussblur.c:139 +#: libvips/convolution/sharpen.c:329 libvips/create/create.c:125 +#: libvips/foreign/foreign.c:1216 libvips/freqfilt/freqfilt.c:105 +#: libvips/histogram/case.c:253 libvips/histogram/hist_equal.c:121 +#: libvips/histogram/hist_local.c:368 libvips/histogram/hist_norm.c:148 +#: libvips/histogram/histogram.c:233 libvips/histogram/hist_plot.c:340 +#: libvips/histogram/maplut.c:751 libvips/histogram/stdif.c:301 +#: libvips/iofuncs/system.c:285 libvips/morphology/morph.c:960 +#: libvips/morphology/rank.c:565 libvips/mosaicing/global_balance.c:1931 +#: libvips/mosaicing/match.c:209 libvips/mosaicing/merge.c:135 +#: libvips/mosaicing/mosaic1.c:511 libvips/mosaicing/mosaic.c:192 +#: libvips/mosaicing/remosaic.c:171 libvips/resample/resample.c:147 +#: libvips/resample/thumbnail.c:969 +msgid "Output image" +msgstr "Ausgabebild" -#. Name -#: libvips/arithmetic/arith_dispatch.c:342 -msgid "average value of image" -msgstr "Durchschnittswert des Bildes" +#: libvips/arithmetic/avg.c:227 +msgid "find image average" +msgstr "Bildmittelwert finden" -#. Name -#: libvips/arithmetic/arith_dispatch.c:431 -msgid "standard deviation of image" -msgstr "Standardabweichung des Bildes" +#: libvips/arithmetic/avg.c:236 libvips/arithmetic/deviate.c:238 +#: libvips/arithmetic/max.c:453 libvips/arithmetic/min.c:453 +#: libvips/histogram/hist_entropy.c:118 +msgid "Output value" +msgstr "Ausgabewert" -# im_exptra() transforms element x of input to -# pow(e, x) in output. -#. Name -#: libvips/arithmetic/arith_dispatch.c:450 -msgid "10^pel of image" -msgstr "10^pel des Bildes" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:469 -msgid "e^pel of image" -msgstr "e^pel des Bildes" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:498 -msgid "x^pel of image" -msgstr "x^pel des Bildes" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:527 -msgid "[x,y,z]^pel of image" -msgstr "[x,y,z]^pel des Bildes" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:546 libvips/arithmetic/divide.c:225 -msgid "divide two images" -msgstr "zwei Bilder teilen" +#: libvips/arithmetic/binary.c:89 +msgid "binary operations" +msgstr "binäre Transaktionen" -#. Name -#: libvips/arithmetic/arith_dispatch.c:565 -msgid "photographic negative" -msgstr "Fotonegativ" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:596 -msgid "calculate a*in + b = outfile" -msgstr "Berechnen von a*in + b = Ausgabedatei" - -#: libvips/arithmetic/arith_dispatch.c:622 -msgid "vectors not equal length" -msgstr "Vektoren ungleicher Länge" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:633 -msgid "calculate a*in + b -> out, a and b vectors" -msgstr "Berechnen von a*in + b -> out, a und b Vektoren" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:652 -msgid "log10 of image" -msgstr "log10 des Bildes" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:671 -msgid "ln of image" -msgstr "ln des Bildes" +#: libvips/arithmetic/binary.c:96 libvips/arithmetic/find_trim.c:216 +#: libvips/arithmetic/measure.c:221 libvips/colour/colour.c:684 +#: libvips/conversion/extract.c:200 libvips/draw/draw_flood.c:593 +#: libvips/draw/draw_rect.c:173 libvips/draw/draw_smudge.c:215 +msgid "Left" +msgstr "links" -#. Name -#: libvips/arithmetic/arith_dispatch.c:690 -msgid "tan of image (angles in degrees)" -msgstr "Tangens des Bildes (Winkel in Grad)" +#: libvips/arithmetic/binary.c:97 +msgid "Left-hand image argument" +msgstr "linksseitiges Bildargument" -#. Name -#: libvips/arithmetic/arith_dispatch.c:709 -msgid "atan of image (result in degrees)" -msgstr "Arkustangens des Bildes (Ergebnis in Grad)" +#: libvips/arithmetic/binary.c:102 libvips/colour/colour.c:690 +msgid "Right" +msgstr "rechts" -#. Name -#: libvips/arithmetic/arith_dispatch.c:728 -msgid "cos of image (angles in degrees)" -msgstr "Kosinus des Bildes (Winkel in Grad)" +#: libvips/arithmetic/binary.c:103 +msgid "Right-hand image argument" +msgstr "rechtsseitiges Bildargument" -#. Name -#: libvips/arithmetic/arith_dispatch.c:747 -msgid "acos of image (result in degrees)" -msgstr "Arkuskosinus des Bildes (Ergebnis in Grad)" +#: libvips/arithmetic/boolean.c:269 +#, fuzzy +msgid "boolean operation on two images" +msgstr "eine Wahr-/Falsch-Transaktion für ein Bilderpaar" -# hinter diesem String folgt ein Flag. -#. Name -#: libvips/arithmetic/arith_dispatch.c:766 -msgid "round to smallest integer value not less than" -msgstr "auf kleinsten ganzzahligen Wert runden, nicht weniger als" +#: libvips/arithmetic/boolean.c:277 libvips/arithmetic/boolean.c:577 +#: libvips/arithmetic/complex.c:258 libvips/arithmetic/complex.c:538 +#: libvips/arithmetic/complex.c:771 libvips/arithmetic/math2.c:241 +#: libvips/arithmetic/math2.c:471 libvips/arithmetic/math.c:261 +#: libvips/arithmetic/relational.c:246 libvips/arithmetic/relational.c:611 +#: libvips/conversion/bandbool.c:238 tools/vips.c:627 +msgid "Operation" +msgstr "Transaktion" -# hinter diesem String folgt ein Flag. -#. Name -#: libvips/arithmetic/arith_dispatch.c:785 -msgid "round to largest integer value not greater than" -msgstr "auf größten ganzzahligen Wert runden, nicht größer als" +#: libvips/arithmetic/boolean.c:278 libvips/arithmetic/boolean.c:578 +#: libvips/conversion/bandbool.c:239 +#, fuzzy +msgid "Boolean to perform" +msgstr "Boolesch zur Durchführung" -# hinter diesem String folgt ein Flag. -#. Name -#: libvips/arithmetic/arith_dispatch.c:804 -msgid "round to nearest integer value" -msgstr "auf nächsten ganzzahligen Wert runden" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:823 -msgid "sin of image (angles in degrees)" -msgstr "Sinus des Bildes (Winkel in Grad)" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:842 -msgid "average image bands" -msgstr "durchschnittliche Bildbänder" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:861 -msgid "unit vector in direction of value" -msgstr "Einheitsvektor in Richtung des Wertes" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:880 -msgid "asin of image (result in degrees)" -msgstr "Arkussinus des Bildes (Ergebnis in Grad)" - -#. Name -#: libvips/arithmetic/arith_dispatch.c:905 -msgid "maximum value of image" -msgstr "Maximalwert des Bildes" +#: libvips/arithmetic/boolean.c:569 +msgid "boolean operations against a constant" +msgstr "boolesche Transaktionen mit einer Konstante" -#. Name -#: libvips/arithmetic/arith_dispatch.c:940 -msgid "position of maximum value of image" -msgstr "Position des Maximalwerts des Bildes" +# http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=0650& +# db=man&fname=/usr/share/catman/p_man/cat3/il_c/ilAbsImg.z +#: libvips/arithmetic/clamp.c:155 +#, fuzzy +msgid "clamp values of an image" +msgstr "absoluter Wert eines Bildes" -#: libvips/arithmetic/arith_dispatch.c:968 -msgid "position of maximum value of image, averaging in case of draw" -msgstr "" -"Position des Maximalwerts des Bildes, durchschnittlich im Fall des Zeichnens" +#: libvips/arithmetic/clamp.c:162 +#, fuzzy +msgid "Min" +msgstr "primär" -#: libvips/arithmetic/arith_dispatch.c:1012 -msgid "position and value of n maxima of image" -msgstr "Position und Wert von n Maxima des Bildes" +#: libvips/arithmetic/clamp.c:163 +#, fuzzy +msgid "Minimum value" +msgstr "Minimalwert des Bildes" -#: libvips/arithmetic/arith_dispatch.c:1046 -msgid "position and value of n minima of image" -msgstr "Position und Wert von n Minima des Bildes" +#: libvips/arithmetic/clamp.c:169 +msgid "Max" +msgstr "" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1094 -msgid "measure averages of a grid of patches" -msgstr "Durchschnittsmaße eine Gitters aus Flickstücken" +#: libvips/arithmetic/clamp.c:170 +#, fuzzy +msgid "Maximum value" +msgstr "Maximalwert des Bildes" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1119 -msgid "minimum value of image" -msgstr "Minimalwert des Bildes" +#: libvips/arithmetic/complex.c:251 +msgid "perform a complex operation on an image" +msgstr "eine komplexe Transaktion mit einem Bild durchführen" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1147 -msgid "position of minimum value of image" -msgstr "Position des Minimalwerts des Bildes" +#: libvips/arithmetic/complex.c:259 libvips/arithmetic/complex.c:772 +#, fuzzy +msgid "Complex to perform" +msgstr "komplex durchzuführen" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1166 -msgid "remainder after integer division" -msgstr "Rest nach Ganzzahldivision" +#: libvips/arithmetic/complex.c:531 +#, fuzzy +msgid "complex binary operations on two images" +msgstr "eine komplexe Transaktion mit einem Bild durchführen" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1195 -msgid "remainder after integer division by a constant" -msgstr "Rest nach Ganzzahldivision durch eine Konstante" +#: libvips/arithmetic/complex.c:539 +#, fuzzy +msgid "Binary complex operation to perform" +msgstr "durchzuführende Rundungstransakktion" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1224 -msgid "remainder after integer division by a vector of constants" -msgstr "Rest nach Ganzzahldivision durch einen Vektor von Konstanten" +#: libvips/arithmetic/complex.c:762 +msgid "get a component from a complex image" +msgstr "einen Bestandteil eines komplexen Bildes holen" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1244 libvips/arithmetic/multiply.c:172 -msgid "multiply two images" -msgstr "zwei Bilder multiplizieren" +#: libvips/arithmetic/complex.c:978 +msgid "form a complex image from two real images" +msgstr "ein komplexes Bild aus zwei echten Bildern erstellen" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1265 -msgid "pel^x of image" -msgstr "pel^x des Bildes" +#: libvips/arithmetic/deviate.c:229 +#, fuzzy +msgid "find image standard deviation" +msgstr "Standardabweichung des Bildes" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1286 -msgid "pel^[x,y,z] of image" -msgstr "pel^[x,y,z] des Bildes" +#: libvips/arithmetic/divide.c:210 +msgid "divide two images" +msgstr "zwei Bilder teilen" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1317 -msgid "many image statistics in one pass" -msgstr "viele Bildstatistiken in einem Durchgang" +#: libvips/arithmetic/find_trim.c:183 +msgid "search an image for non-edge areas" +msgstr "" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1336 libvips/arithmetic/subtract.c:161 -msgid "subtract two images" -msgstr "zwei Bilder subtrahieren" +#: libvips/arithmetic/find_trim.c:189 libvips/arithmetic/getpoint.c:153 +#: libvips/arithmetic/measure.c:195 libvips/arithmetic/nary.c:87 +#: libvips/arithmetic/statistic.c:167 libvips/arithmetic/unary.c:88 +#: libvips/colour/CMYK2XYZ.c:120 libvips/colour/colour.c:480 +#: libvips/colour/colour.c:573 libvips/colour/colourspace.c:557 +#: libvips/colour/scRGB2BW.c:237 libvips/colour/scRGB2sRGB.c:270 +#: libvips/colour/scRGB2XYZ.c:191 libvips/colour/sRGB2scRGB.c:288 +#: libvips/colour/XYZ2CMYK.c:119 libvips/colour/XYZ2scRGB.c:200 +#: libvips/conversion/addalpha.c:90 libvips/conversion/arrayjoin.c:394 +#: libvips/conversion/autorot.c:207 libvips/conversion/bandbool.c:232 +#: libvips/conversion/bandfold.c:161 libvips/conversion/bandjoin.c:201 +#: libvips/conversion/bandjoin.c:436 libvips/conversion/bandmean.c:212 +#: libvips/conversion/bandrank.c:254 libvips/conversion/bandunfold.c:164 +#: libvips/conversion/byteswap.c:238 libvips/conversion/cache.c:108 +#: libvips/conversion/cast.c:530 libvips/conversion/copy.c:271 +#: libvips/conversion/embed.c:568 libvips/conversion/extract.c:194 +#: libvips/conversion/extract.c:432 libvips/conversion/falsecolour.c:380 +#: libvips/conversion/flatten.c:419 libvips/conversion/flip.c:240 +#: libvips/conversion/gamma.c:142 libvips/conversion/grid.c:199 +#: libvips/conversion/msb.c:247 libvips/conversion/premultiply.c:261 +#: libvips/conversion/recomb.c:224 libvips/conversion/replicate.c:196 +#: libvips/conversion/rot45.c:268 libvips/conversion/rot.c:365 +#: libvips/conversion/scale.c:155 libvips/conversion/sequential.c:243 +#: libvips/conversion/smartcrop.c:433 libvips/conversion/subsample.c:267 +#: libvips/conversion/tilecache.c:398 libvips/conversion/transpose3d.c:167 +#: libvips/conversion/unpremultiply.c:323 libvips/conversion/wrap.c:119 +#: libvips/conversion/zoom.c:373 libvips/convolution/canny.c:442 +#: libvips/convolution/convolution.c:128 libvips/convolution/correlation.c:150 +#: libvips/convolution/edge.c:217 libvips/convolution/gaussblur.c:132 +#: libvips/convolution/sharpen.c:322 libvips/create/buildlut.c:263 +#: libvips/create/invertlut.c:288 libvips/foreign/foreign.c:1894 +#: libvips/freqfilt/freqfilt.c:98 libvips/histogram/hist_entropy.c:111 +#: libvips/histogram/hist_equal.c:114 libvips/histogram/hist_ismonotonic.c:118 +#: libvips/histogram/hist_local.c:361 libvips/histogram/hist_match.c:161 +#: libvips/histogram/hist_norm.c:141 libvips/histogram/hist_plot.c:333 +#: libvips/histogram/hist_unary.c:88 libvips/histogram/maplut.c:744 +#: libvips/histogram/percent.c:109 libvips/histogram/stdif.c:294 +#: libvips/iofuncs/ginputsource.c:274 libvips/iofuncs/sbuf.c:88 +#: libvips/iofuncs/system.c:277 libvips/morphology/morphology.c:121 +#: libvips/mosaicing/global_balance.c:1924 libvips/mosaicing/matrixinvert.c:443 +#: libvips/mosaicing/remosaic.c:164 libvips/resample/resample.c:140 +#: libvips/resample/thumbnail.c:1782 +msgid "Input" +msgstr "Eingabe" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1384 -msgid "pixelwise linear regression" -msgstr "bildpunktweise lineare Regression" +#: libvips/arithmetic/find_trim.c:190 +#, fuzzy +msgid "Image to find_trim" +msgstr "Bilddateiname" -#. Name -#: libvips/arithmetic/arith_dispatch.c:1403 -msgid "phase of cross power spectrum of two complex images" -msgstr "Phase des Kreuzleistungsspektrums zweier komplexer Bilder" +#: libvips/arithmetic/find_trim.c:195 libvips/histogram/percent.c:122 +msgid "Threshold" +msgstr "" -#: libvips/arithmetic/linear.c:249 -msgid "calculate (a * in + b)" -msgstr "(a * in + b) berechnen" +#: libvips/arithmetic/find_trim.c:196 +msgid "Object threshold" +msgstr "" -#: libvips/arithmetic/linear.c:257 -msgid "a" -msgstr "a" +#: libvips/arithmetic/find_trim.c:202 libvips/conversion/arrayjoin.c:415 +#: libvips/conversion/embed.c:595 libvips/conversion/flatten.c:425 +#: libvips/conversion/insert.c:499 libvips/conversion/join.c:270 +#: libvips/foreign/foreign.c:1908 libvips/foreign/pdfiumload.c:723 +#: libvips/foreign/popplerload.c:573 libvips/resample/affine.c:699 +#: libvips/resample/mapim.c:574 libvips/resample/similarity.c:133 +msgid "Background" +msgstr "Hintergrund" -#: libvips/arithmetic/linear.c:258 -msgid "Multiply by this" -msgstr "hiermit multiplizieren" +#: libvips/arithmetic/find_trim.c:203 libvips/conversion/embed.c:596 +#, fuzzy +msgid "Color for background pixels" +msgstr "Farbe für neue Bildpunkte" -#: libvips/arithmetic/linear.c:264 -msgid "b" -msgstr "b" +#: libvips/arithmetic/find_trim.c:209 +msgid "Line art mode" +msgstr "" -#: libvips/arithmetic/linear.c:265 -msgid "Add this" -msgstr "dies hinzufügen" +#: libvips/arithmetic/find_trim.c:210 +msgid "Enable line art mode" +msgstr "" -#: libvips/arithmetic/remainder.c:178 -msgid "remainder after integer division of two images" -msgstr "Rest nach Ganzzahldivision zweier Bilder" +#: libvips/arithmetic/find_trim.c:217 +#, fuzzy +msgid "Left edge of image" +msgstr "linker Rand des Teilbilds im Hauptbild" -#: libvips/arithmetic/remainder.c:327 -msgid "remainder after integer division of an image and a constant" -msgstr "Rest nach Ganzzahldivision eines Bildes und einer Konstante" +#: libvips/arithmetic/find_trim.c:223 libvips/arithmetic/measure.c:228 +#: libvips/conversion/extract.c:207 libvips/draw/draw_flood.c:600 +#: libvips/draw/draw_rect.c:180 libvips/draw/draw_smudge.c:222 +msgid "Top" +msgstr "oben" -#: libvips/arithmetic/im_maxpos_vec.c:121 -#: libvips/arithmetic/im_maxpos_vec.c:186 -msgid "scalar images only" -msgstr "nur skalare Bilder" +#: libvips/arithmetic/find_trim.c:224 libvips/arithmetic/measure.c:229 +#: libvips/conversion/extract.c:208 +msgid "Top edge of extract area" +msgstr "obere Kante eines extrahierten Bereichs" -#: libvips/arithmetic/im_maxpos_vec.c:126 -#: libvips/arithmetic/im_maxpos_vec.c:191 -msgid "single band images only" -msgstr "nur Einzelbandbilder" +#: libvips/arithmetic/find_trim.c:230 libvips/arithmetic/hough_line.c:147 +#: libvips/arithmetic/measure.c:235 libvips/conversion/copy.c:284 +#: libvips/conversion/embed.c:574 libvips/conversion/extract.c:214 +#: libvips/conversion/smartcrop.c:439 libvips/create/black.c:140 +#: libvips/create/fractsurf.c:104 libvips/create/gaussnoise.c:167 +#: libvips/create/logmat.c:208 libvips/create/perlin.c:294 +#: libvips/create/point.c:141 libvips/create/sdf.c:304 +#: libvips/create/text.c:567 libvips/create/worley.c:307 +#: libvips/create/xyz.c:191 libvips/draw/draw_flood.c:607 +#: libvips/draw/draw_rect.c:187 libvips/draw/draw_smudge.c:229 +#: libvips/foreign/rawload.c:146 libvips/histogram/hist_local.c:373 +#: libvips/histogram/stdif.c:308 libvips/iofuncs/image.c:1102 +#: libvips/morphology/rank.c:570 +msgid "Width" +msgstr "Breite" -#: libvips/arithmetic/im_maxpos_vec.c:131 -#: libvips/arithmetic/im_maxpos_vec.c:196 -msgid "uncoded images only" -msgstr "nur unkodierte Bilder" +#: libvips/arithmetic/find_trim.c:231 libvips/arithmetic/measure.c:236 +#: libvips/conversion/extract.c:215 libvips/conversion/smartcrop.c:440 +msgid "Width of extract area" +msgstr "Breite des extrahierten Bereichs" -#: libvips/arithmetic/im_maxpos_vec.c:136 -#: libvips/arithmetic/im_maxpos_vec.c:201 -msgid "invalid argument" -msgstr "ungültiges Argument" +#: libvips/arithmetic/find_trim.c:237 libvips/arithmetic/hough_line.c:154 +#: libvips/arithmetic/measure.c:242 libvips/conversion/copy.c:291 +#: libvips/conversion/embed.c:581 libvips/conversion/extract.c:221 +#: libvips/conversion/smartcrop.c:446 libvips/create/black.c:147 +#: libvips/create/fractsurf.c:111 libvips/create/gaussnoise.c:174 +#: libvips/create/perlin.c:301 libvips/create/point.c:148 +#: libvips/create/sdf.c:311 libvips/create/text.c:574 +#: libvips/create/worley.c:314 libvips/create/xyz.c:198 +#: libvips/draw/draw_flood.c:614 libvips/draw/draw_rect.c:194 +#: libvips/draw/draw_smudge.c:236 libvips/foreign/rawload.c:153 +#: libvips/histogram/hist_local.c:380 libvips/histogram/stdif.c:315 +#: libvips/iofuncs/image.c:1109 libvips/morphology/rank.c:577 +msgid "Height" +msgstr "Höhe" -#: libvips/arithmetic/min.c:317 -msgid "find image minimum" -msgstr "Minimum des Bildes finden" +#: libvips/arithmetic/find_trim.c:238 libvips/arithmetic/measure.c:243 +#: libvips/conversion/extract.c:222 libvips/conversion/smartcrop.c:447 +msgid "Height of extract area" +msgstr "Höhe des extrahierten Bereichs" -#: libvips/arithmetic/min.c:325 libvips/arithmetic/arithmetic.c:382 -#: libvips/arithmetic/stats.c:423 libvips/arithmetic/measure.c:202 -#: libvips/arithmetic/max.c:324 libvips/arithmetic/avg.c:218 -#: libvips/arithmetic/deviate.c:219 libvips/conversion/conversion.c:89 -#: libvips/foreign/foreign.c:897 -msgid "Output" -msgstr "Ausgabe" +#: libvips/arithmetic/getpoint.c:149 +#, fuzzy +msgid "read a point from an image" +msgstr "Band aus einem Bild extrahieren" -#: libvips/arithmetic/min.c:326 libvips/arithmetic/max.c:325 -#: libvips/arithmetic/avg.c:219 libvips/arithmetic/deviate.c:220 -msgid "Output value" +#: libvips/arithmetic/getpoint.c:154 libvips/arithmetic/statistic.c:168 +#: libvips/arithmetic/unary.c:89 libvips/colour/CMYK2XYZ.c:121 +#: libvips/colour/colour.c:481 libvips/colour/colour.c:574 +#: libvips/colour/colourspace.c:558 libvips/colour/scRGB2BW.c:238 +#: libvips/colour/scRGB2sRGB.c:271 libvips/colour/scRGB2XYZ.c:192 +#: libvips/colour/sRGB2scRGB.c:289 libvips/colour/XYZ2CMYK.c:120 +#: libvips/colour/XYZ2scRGB.c:201 libvips/conversion/addalpha.c:91 +#: libvips/conversion/autorot.c:208 libvips/conversion/bandfold.c:162 +#: libvips/conversion/bandjoin.c:437 libvips/conversion/bandunfold.c:165 +#: libvips/conversion/byteswap.c:239 libvips/conversion/cache.c:109 +#: libvips/conversion/cast.c:531 libvips/conversion/copy.c:272 +#: libvips/conversion/embed.c:569 libvips/conversion/extract.c:195 +#: libvips/conversion/extract.c:433 libvips/conversion/falsecolour.c:381 +#: libvips/conversion/flatten.c:420 libvips/conversion/flip.c:241 +#: libvips/conversion/gamma.c:143 libvips/conversion/grid.c:200 +#: libvips/conversion/msb.c:248 libvips/conversion/premultiply.c:262 +#: libvips/conversion/replicate.c:197 libvips/conversion/rot45.c:269 +#: libvips/conversion/rot.c:366 libvips/conversion/scale.c:156 +#: libvips/conversion/sequential.c:244 libvips/conversion/smartcrop.c:434 +#: libvips/conversion/subsample.c:268 libvips/conversion/tilecache.c:399 +#: libvips/conversion/transpose3d.c:168 libvips/conversion/unpremultiply.c:324 +#: libvips/conversion/wrap.c:120 libvips/conversion/zoom.c:374 +#: libvips/convolution/canny.c:443 libvips/convolution/edge.c:218 +#: libvips/convolution/gaussblur.c:133 libvips/convolution/sharpen.c:323 +#: libvips/freqfilt/freqfilt.c:99 libvips/histogram/hist_equal.c:115 +#: libvips/histogram/hist_local.c:362 libvips/histogram/hist_norm.c:142 +#: libvips/histogram/hist_plot.c:334 libvips/histogram/hist_unary.c:89 +#: libvips/histogram/maplut.c:745 libvips/histogram/percent.c:110 +#: libvips/histogram/stdif.c:295 libvips/mosaicing/global_balance.c:1925 +#: libvips/mosaicing/remosaic.c:165 +msgid "Input image" +msgstr "Eingabebild" + +#: libvips/arithmetic/getpoint.c:159 libvips/arithmetic/max.c:480 +#: libvips/arithmetic/min.c:480 +#, fuzzy +msgid "Output array" msgstr "Ausgabewert" -#: libvips/arithmetic/min.c:332 libvips/arithmetic/max.c:331 -#: libvips/conversion/embed.c:522 +#: libvips/arithmetic/getpoint.c:160 libvips/arithmetic/max.c:481 +#: libvips/arithmetic/min.c:481 +#, fuzzy +msgid "Array of output values" +msgstr "Feld von Eingabebildern" + +#: libvips/arithmetic/getpoint.c:166 libvips/arithmetic/max.c:459 +#: libvips/arithmetic/min.c:459 libvips/conversion/composite.cpp:1733 +#: libvips/conversion/embed.c:656 libvips/conversion/wrap.c:125 +#: libvips/draw/draw_flood.c:566 libvips/draw/draw_image.c:275 +#: libvips/draw/draw_mask.c:338 msgid "x" msgstr "x" -#: libvips/arithmetic/min.c:333 -msgid "Horizontal position of minimum" -msgstr "horizontale Position des Minimums" +#: libvips/arithmetic/getpoint.c:167 libvips/arithmetic/getpoint.c:174 +#, fuzzy +msgid "Point to read" +msgstr "keine Punkte zum Mitteln" -#: libvips/arithmetic/min.c:339 libvips/arithmetic/max.c:338 -#: libvips/conversion/embed.c:529 +#: libvips/arithmetic/getpoint.c:173 libvips/arithmetic/max.c:466 +#: libvips/arithmetic/min.c:466 libvips/conversion/composite.cpp:1740 +#: libvips/conversion/embed.c:663 libvips/conversion/wrap.c:132 +#: libvips/draw/draw_flood.c:573 libvips/draw/draw_image.c:282 +#: libvips/draw/draw_mask.c:345 msgid "y" msgstr "y" -#: libvips/arithmetic/min.c:340 -msgid "Vertical position of minimum" -msgstr "vertikale Position des Minimums" +#: libvips/arithmetic/getpoint.c:180 +#, fuzzy +msgid "unpack_complex" +msgstr "Maske zu komplex" -#: libvips/arithmetic/boolean.c:209 -msgid "a boolean operation on a pair of images" -msgstr "eine Wahr-/Falsch-Transaktion für ein Bilderpaar" +#: libvips/arithmetic/getpoint.c:181 +msgid "Complex pixels should be unpacked" +msgstr "" -#: libvips/arithmetic/boolean.c:217 libvips/arithmetic/boolean.c:519 -#: libvips/arithmetic/math2.c:204 libvips/arithmetic/math2.c:401 -#: libvips/arithmetic/math.c:205 libvips/arithmetic/relational.c:227 -#: libvips/arithmetic/relational.c:560 libvips/arithmetic/complex.c:222 -#: libvips/arithmetic/complex.c:476 -msgid "Operation" -msgstr "Transaktion" +#: libvips/arithmetic/hist_find.c:422 +#, fuzzy +msgid "find image histogram" +msgstr "Minimum des Bildes finden" -#: libvips/arithmetic/boolean.c:218 libvips/arithmetic/boolean.c:520 -msgid "boolean to perform" -msgstr "Boolesch zur Durchführung" +#: libvips/arithmetic/hist_find.c:432 +#: libvips/arithmetic/hist_find_indexed.c:476 +#: libvips/arithmetic/hist_find_ndim.c:314 +#, fuzzy +msgid "Output histogram" +msgstr "Ausgabebild" -#: libvips/arithmetic/boolean.c:511 -msgid "boolean operations against a constant" -msgstr "boolesche Transaktionen mit einer Konstante" +#: libvips/arithmetic/hist_find.c:437 libvips/conversion/extract.c:438 +#: libvips/conversion/msb.c:253 libvips/histogram/hist_equal.c:126 +#: libvips/histogram/maplut.c:762 +msgid "Band" +msgstr "Band" -#: libvips/arithmetic/arithmetic.c:164 -#, c-format -msgid "not one band or %d bands" -msgstr "nicht ein Band oder %d Bänder" +#: libvips/arithmetic/hist_find.c:438 +msgid "Find histogram of band" +msgstr "" -#: libvips/arithmetic/arithmetic.c:168 libvips/histograms_lut/im_identity.c:80 -#: libvips/histograms_lut/im_identity.c:143 -msgid "bad bands" -msgstr "falsche Bänder" +#: libvips/arithmetic/hist_find_indexed.c:461 +msgid "find indexed image histogram" +msgstr "" -#: libvips/arithmetic/arithmetic.c:324 libvips/conversion/bandary.c:131 -msgid "too many input images" -msgstr "zu viele Eingabebilder" +#: libvips/arithmetic/hist_find_indexed.c:469 libvips/conversion/bandrank.c:261 +#: libvips/histogram/case.c:239 libvips/morphology/rank.c:584 +#: libvips/resample/mapim.c:555 +msgid "Index" +msgstr "" -#: libvips/arithmetic/arithmetic.c:378 -msgid "arithmetic operations" -msgstr "arithmetische Transaktionen" +#: libvips/arithmetic/hist_find_indexed.c:470 libvips/histogram/case.c:240 +#, fuzzy +msgid "Index image" +msgstr "Eingabebild" -#: libvips/arithmetic/arithmetic.c:383 libvips/conversion/conversion.c:90 -#: libvips/foreign/foreign.c:898 -msgid "Output image" -msgstr "Ausgabebild" +#: libvips/arithmetic/hist_find_indexed.c:481 libvips/convolution/compass.c:177 +msgid "Combine" +msgstr "" -#: libvips/arithmetic/stats.c:415 libvips/arithmetic/avg.c:210 -#: libvips/arithmetic/deviate.c:211 -msgid "find image average" -msgstr "Bildmittelwert finden" +#: libvips/arithmetic/hist_find_indexed.c:482 +msgid "Combine bins like this" +msgstr "" -#: libvips/arithmetic/stats.c:424 libvips/arithmetic/measure.c:203 -msgid "Output array of statistics" -msgstr "Ausgabefeld von Statistiken" +#: libvips/arithmetic/hist_find_ndim.c:150 +#, fuzzy +msgid "image is not 1 - 3 bands" +msgstr "Bild muss ein oder %d Bänder haben" -#: libvips/arithmetic/math2.c:196 -msgid "pow( left, right)" -msgstr "pow( links, rechts)" +#: libvips/arithmetic/hist_find_ndim.c:159 +#, fuzzy, c-format +msgid "bins out of range [1,%d]" +msgstr " »bins« außerhalb des Bereichs [1,%d]" -#: libvips/arithmetic/math2.c:205 libvips/arithmetic/math2.c:402 -#: libvips/arithmetic/math.c:206 -msgid "math to perform" -msgstr "durchzuführende Berechnung" +#: libvips/arithmetic/hist_find_ndim.c:304 +#, fuzzy +msgid "find n-dimensional image histogram" +msgstr "%d-dimensionale Bilder nicht unterstützt" -#: libvips/arithmetic/math2.c:393 -msgid "pow( @in, @c )" -msgstr "pow( @in, @c )" +#: libvips/arithmetic/hist_find_ndim.c:319 +msgid "Bins" +msgstr "" -#: libvips/arithmetic/round.c:160 -msgid "perform a round function on an image" -msgstr "eine Rundungsfunktion für ein Bild ausführen" +#: libvips/arithmetic/hist_find_ndim.c:320 +#, fuzzy +msgid "Number of bins in each dimension" +msgstr "Anzahl der Bänder in einem Bild" -#: libvips/arithmetic/round.c:168 -msgid "Round operation" -msgstr "Rundungstransakktion" +#: libvips/arithmetic/hough.c:170 +msgid "find hough transform" +msgstr "" -#: libvips/arithmetic/round.c:169 -msgid "rounding operation to perform" -msgstr "durchzuführende Rundungstransakktion" +#: libvips/arithmetic/hough_circle.c:115 +msgid "parameters out of range" +msgstr "Parameter außerhalb des Bereichs" -#: libvips/arithmetic/measure.c:163 -#, c-format -msgid "patch %d x %d, band %d: avg = %g, sdev = %g" -msgstr "Flicken %d x %d, Band %d: Durchschn. = %g, sdev = %g" +#: libvips/arithmetic/hough_circle.c:226 +msgid "find hough circle transform" +msgstr "" -#: libvips/arithmetic/measure.c:192 -msgid "measure a set of patches on a colour chart" -msgstr "messen eines Satzes von Patches auf ein Farbdiagramm" +#: libvips/arithmetic/hough_circle.c:233 libvips/foreign/pdfiumload.c:716 +#: libvips/foreign/popplerload.c:566 libvips/foreign/svgload.c:724 +#: libvips/foreign/webpload.c:192 libvips/mosaicing/mosaic.c:274 +#: libvips/resample/similarity.c:200 +msgid "Scale" +msgstr "" -#: libvips/arithmetic/measure.c:196 -msgid "in" -msgstr "in" +#: libvips/arithmetic/hough_circle.c:234 +msgid "Scale down dimensions by this factor" +msgstr "" -#: libvips/arithmetic/measure.c:197 -msgid "Image to measure" -msgstr "zu vermessendes Bild" +#: libvips/arithmetic/hough_circle.c:240 +msgid "Min radius" +msgstr "" -#: libvips/arithmetic/measure.c:208 libvips/conversion/replicate.c:202 -msgid "Across" -msgstr "über" +#: libvips/arithmetic/hough_circle.c:241 +msgid "Smallest radius to search for" +msgstr "" -#: libvips/arithmetic/measure.c:209 -msgid "Number of patches across chart" -msgstr "Anzahl der Patches über ein Diagramm" +#: libvips/arithmetic/hough_circle.c:247 +#, fuzzy +msgid "Max radius" +msgstr "Kacheln maximal" -#: libvips/arithmetic/measure.c:215 libvips/conversion/replicate.c:209 -msgid "Down" -msgstr "hinunter" +#: libvips/arithmetic/hough_circle.c:248 +msgid "Largest radius to search for" +msgstr "" -#: libvips/arithmetic/measure.c:216 -msgid "Number of patches down chart" -msgstr "Anzahl der Patches ein Diagramm hinunter" +#: libvips/arithmetic/hough_line.c:140 +msgid "find hough line transform" +msgstr "" -#: libvips/arithmetic/measure.c:222 libvips/arithmetic/binary.c:95 -#: libvips/conversion/extract.c:200 -msgid "Left" -msgstr "links" +#: libvips/arithmetic/hough_line.c:148 +msgid "Horizontal size of parameter space" +msgstr "" -#: libvips/arithmetic/measure.c:223 libvips/conversion/extract.c:201 -msgid "Left edge of extract area" -msgstr "linke Kante eines extrahierten Bereichs" +#: libvips/arithmetic/hough_line.c:155 +msgid "Vertical size of parameter space" +msgstr "" -#: libvips/arithmetic/measure.c:229 libvips/conversion/extract.c:207 -msgid "Top" -msgstr "oben" +#: libvips/arithmetic/invert.c:178 +msgid "invert an image" +msgstr "ein Bild invertieren" -#: libvips/arithmetic/measure.c:230 libvips/conversion/extract.c:208 -msgid "Top edge of extract area" -msgstr "obere Kante eines extrahierten Bereichs" +#: libvips/arithmetic/linear.c:446 +msgid "calculate (a * in + b)" +msgstr "(a * in + b) berechnen" -#: libvips/arithmetic/measure.c:236 libvips/conversion/extract.c:214 -#: libvips/conversion/embed.c:536 libvips/conversion/copy.c:331 -#: libvips/conversion/black.c:128 libvips/foreign/rawload.c:122 -#: libvips/iofuncs/image.c:845 -msgid "Width" -msgstr "Breite" +#: libvips/arithmetic/linear.c:454 libvips/create/sdf.c:332 +msgid "a" +msgstr "a" -#: libvips/arithmetic/measure.c:237 libvips/conversion/extract.c:215 -msgid "Width of extract area" -msgstr "Breite des extrahierten Bereichs" +#: libvips/arithmetic/linear.c:455 +msgid "Multiply by this" +msgstr "hiermit multiplizieren" -#: libvips/arithmetic/measure.c:243 libvips/conversion/extract.c:221 -#: libvips/conversion/embed.c:543 libvips/conversion/copy.c:338 -#: libvips/conversion/black.c:135 libvips/foreign/rawload.c:129 -#: libvips/iofuncs/image.c:852 -msgid "Height" -msgstr "Höhe" +#: libvips/arithmetic/linear.c:461 libvips/create/sdf.c:339 +msgid "b" +msgstr "b" -#: libvips/arithmetic/measure.c:244 libvips/conversion/extract.c:222 -msgid "Height of extract area" -msgstr "Höhe des extrahierten Bereichs" +#: libvips/arithmetic/linear.c:462 +msgid "Add this" +msgstr "dies hinzufügen" -#: libvips/arithmetic/math.c:197 -msgid "perform a math function on an image" -msgstr "eine mathematische Funktion für ein Bild ausführen" +#: libvips/arithmetic/linear.c:468 +msgid "uchar" +msgstr "" -#: libvips/arithmetic/relational.c:219 -msgid "a relational operation on a pair of images" -msgstr "eine relationale Transaktion für ein Bilderpaar" +#: libvips/arithmetic/linear.c:469 +msgid "Output should be uchar" +msgstr "" -#: libvips/arithmetic/relational.c:228 libvips/arithmetic/relational.c:561 -msgid "relational to perform" -msgstr "relational durchzuführen" +#: libvips/arithmetic/math2.c:233 +#, fuzzy +msgid "binary math operations" +msgstr "binäre Transaktionen" -#: libvips/arithmetic/relational.c:552 -msgid "relational operations against a constant" -msgstr "relationale Transaktion für eine Konstante" +#: libvips/arithmetic/math2.c:242 libvips/arithmetic/math2.c:472 +#: libvips/arithmetic/math.c:262 +#, fuzzy +msgid "Math to perform" +msgstr "durchzuführende Berechnung" -#: libvips/arithmetic/unaryconst.c:201 -msgid "unary operations with a constant" +#: libvips/arithmetic/math2.c:463 +#, fuzzy +msgid "binary math operations with a constant" msgstr "unäre Transaktionen mit einer Konstante" -#: libvips/arithmetic/unaryconst.c:205 -msgid "c" -msgstr "c" - -#: libvips/arithmetic/unaryconst.c:206 -msgid "Array of constants" -msgstr "Feld aus Konstanten" +#: libvips/arithmetic/math.c:253 +#, fuzzy +msgid "apply a math operation to an image" +msgstr "eine komplexe Transaktion mit einem Bild durchführen" -#: libvips/arithmetic/unary.c:80 -msgid "unary operations" -msgstr "unäre Transaktionen" +#: libvips/arithmetic/max.c:444 +msgid "find image maximum" +msgstr "Maximum des Bildes finden" -#: libvips/arithmetic/unary.c:88 libvips/conversion/bandmean.c:198 -#: libvips/conversion/recomb.c:201 -msgid "Input image argument" -msgstr "Eingabebildargument" - -#: libvips/arithmetic/invert.c:152 -msgid "invert an image" -msgstr "ein Bild invertieren" - -#: libvips/arithmetic/max.c:316 -msgid "find image maximum" -msgstr "Maximum des Bildes finden" - -#: libvips/arithmetic/max.c:332 +#: libvips/arithmetic/max.c:460 msgid "Horizontal position of maximum" msgstr "horizontale Position des Maximums" -#: libvips/arithmetic/max.c:339 +#: libvips/arithmetic/max.c:467 msgid "Vertical position of maximum" msgstr "vertikale Position des Maximums" -#: libvips/arithmetic/complex.c:215 -msgid "perform a complex operation on an image" -msgstr "eine komplexe Transaktion mit einem Bild durchführen" +#: libvips/arithmetic/max.c:473 libvips/arithmetic/min.c:473 +#: libvips/create/identity.c:157 libvips/create/invertlut.c:294 +#: libvips/resample/thumbnail.c:988 +msgid "Size" +msgstr "" -#: libvips/arithmetic/complex.c:223 libvips/arithmetic/complex.c:477 -msgid "complex to perform" -msgstr "komplex durchzuführen" +#: libvips/arithmetic/max.c:474 +#, fuzzy +msgid "Number of maximum values to find" +msgstr "Position des Maximalwerts des Bildes" -#: libvips/arithmetic/complex.c:468 -msgid "get a component from a complex image" -msgstr "einen Bestandteil eines komplexen Bildes holen" +#: libvips/arithmetic/max.c:487 libvips/arithmetic/min.c:487 +msgid "x array" +msgstr "" -#: libvips/arithmetic/complex.c:666 -msgid "form a complex image from two real images" -msgstr "ein komplexes Bild aus zwei echten Bildern erstellen" +#: libvips/arithmetic/max.c:488 libvips/arithmetic/min.c:488 +#, fuzzy +msgid "Array of horizontal positions" +msgstr "Feld aus Konstanten" -#: libvips/arithmetic/binary.c:88 -msgid "binary operations" -msgstr "binäre Transaktionen" +#: libvips/arithmetic/max.c:494 libvips/arithmetic/min.c:494 +msgid "y array" +msgstr "" -#: libvips/arithmetic/binary.c:96 -msgid "Left-hand image argument" -msgstr "linksseitiges Bildargument" +#: libvips/arithmetic/max.c:495 libvips/arithmetic/min.c:495 +#, fuzzy +msgid "Array of vertical positions" +msgstr "Feld aus Konstanten" -#: libvips/arithmetic/binary.c:101 -msgid "Right" -msgstr "rechts" +#: libvips/arithmetic/maxpair.c:151 +#, fuzzy +msgid "maximum of a pair of images" +msgstr "ein Bilderpaar zusammenführen" -#: libvips/arithmetic/binary.c:102 -msgid "Right-hand image argument" -msgstr "rechtsseitiges Bildargument" +#: libvips/arithmetic/measure.c:164 +#, fuzzy, c-format +msgid "%s: patch %d x %d, band %d: avg = %g, sdev = %g" +msgstr "Flicken %d x %d, Band %d: Durchschn. = %g, sdev = %g" -#: libvips/arithmetic/sign.c:151 -msgid "unit vector of pixel" -msgstr "Einheitsvektor von Bildpunkten" +#: libvips/arithmetic/measure.c:191 +#, fuzzy +msgid "measure a set of patches on a color chart" +msgstr "messen eines Satzes von Patches auf ein Farbdiagramm" -#: libvips/colour/im_rad2float.c:186 -msgid "not a RAD image" -msgstr "kein RAD-Bild" +#: libvips/arithmetic/measure.c:196 +msgid "Image to measure" +msgstr "zu vermessendes Bild" -#: libvips/colour/im_icc_transform.c:202 libvips/colour/im_icc_transform.c:212 -#: libvips/colour/im_icc_transform.c:1000 -#: libvips/colour/im_icc_transform.c:1010 -#, c-format -msgid "unable to open profile \"%s\"" -msgstr "Profil »%s« kann nicht geöffnet werden" +#: libvips/arithmetic/measure.c:202 libvips/arithmetic/stats.c:443 +msgid "Output array of statistics" +msgstr "Ausgabefeld von Statistiken" -#: libvips/colour/im_icc_transform.c:223 -#: libvips/colour/im_icc_transform.c:1022 -msgid "unable to create profiles" -msgstr "es können keine Profile erstellt werden" +#: libvips/arithmetic/measure.c:207 libvips/conversion/arrayjoin.c:401 +#: libvips/conversion/grid.c:212 libvips/conversion/replicate.c:202 +msgid "Across" +msgstr "über" -#: libvips/colour/im_icc_transform.c:242 -#: libvips/colour/im_icc_transform.c:1042 -msgid "unable to read profile" -msgstr "Profil kann nicht gelesen werden" +#: libvips/arithmetic/measure.c:208 +msgid "Number of patches across chart" +msgstr "Anzahl der Patches über ein Diagramm" -#: libvips/colour/im_icc_transform.c:363 libvips/colour/im_icc_transform.c:372 -#: libvips/colour/im_icc_transform.c:737 -#: libvips/colour/im_icc_transform.c:1170 -#: libvips/colour/im_icc_transform.c:1179 -#: libvips/colour/im_icc_transform.c:1522 -#, c-format -msgid "" -"intent %d (%s) not supported by profile \"%s\"; falling back to default " -"intent (usually PERCEPTUAL)" -msgstr "" -"Ziel-%d (%s) nicht von Profil »%s« unterstützt; Rückfall auf Standardabsicht " -"(normalerweise WAHRNEHMUNG)" +#: libvips/arithmetic/measure.c:214 libvips/conversion/grid.c:219 +#: libvips/conversion/replicate.c:209 +msgid "Down" +msgstr "hinunter" -#: libvips/colour/im_icc_transform.c:382 -#: libvips/colour/im_icc_transform.c:1189 -msgid "CMYK input profile needs a 4 band input image" -msgstr "CMYK-Eingabeprofil benötigt ein Eingabebild mit vier Bändern" +#: libvips/arithmetic/measure.c:215 +msgid "Number of patches down chart" +msgstr "Anzahl der Patches ein Diagramm hinunter" -#: libvips/colour/im_icc_transform.c:392 -#: libvips/colour/im_icc_transform.c:1199 -msgid "RGB input profile needs a 3 band input image" -msgstr "RGB-Eingabeprofil benötigt ein Eingabebild mit drei Bändern" +#: libvips/arithmetic/measure.c:222 libvips/conversion/extract.c:201 +msgid "Left edge of extract area" +msgstr "linke Kante eines extrahierten Bereichs" -#: libvips/colour/im_icc_transform.c:401 libvips/colour/im_icc_transform.c:551 -#: libvips/colour/im_icc_transform.c:1208 -#: libvips/colour/im_icc_transform.c:1340 -#, c-format -msgid "unimplemented input color space 0x%x" -msgstr "nicht implementierter Eingabefarbraum 0x%x" +#: libvips/arithmetic/min.c:444 +msgid "find image minimum" +msgstr "Minimum des Bildes finden" -#: libvips/colour/im_icc_transform.c:428 libvips/colour/im_icc_transform.c:767 -#: libvips/colour/im_icc_transform.c:1235 -#: libvips/colour/im_icc_transform.c:1552 -#, c-format -msgid "unimplemented output color space 0x%x" -msgstr "nicht implementierter Ausgabefarbraum 0x%x" +#: libvips/arithmetic/min.c:460 +msgid "Horizontal position of minimum" +msgstr "horizontale Position des Minimums" -#: libvips/colour/im_icc_transform.c:444 libvips/colour/im_icc_transform.c:567 -#: libvips/colour/im_icc_transform.c:1251 -#: libvips/colour/im_icc_transform.c:1356 -msgid "uchar or ushort input only" -msgstr "nur »uchar« oder »ushort«-Eingabe" +#: libvips/arithmetic/min.c:467 +msgid "Vertical position of minimum" +msgstr "vertikale Position des Minimums" -#: libvips/colour/im_icc_transform.c:516 -#: libvips/colour/im_icc_transform.c:1305 -#, c-format -msgid "" -"intent %d (%s) not supported by profile; falling back to default intent " -"(usually PERCEPTUAL)" -msgstr "" -"Ziel-%d (%s) nicht vom Profil unterstützt; Rückfall auf Standardabsicht " -"(normalerweise WAHRNEHMUNG)" +#: libvips/arithmetic/min.c:474 +#, fuzzy +msgid "Number of minimum values to find" +msgstr "Position des Minimalwerts des Bildes" -#: libvips/colour/im_icc_transform.c:533 -#: libvips/colour/im_icc_transform.c:1322 -msgid "CMYK profile needs a 4 band input image" -msgstr "CMYK-Profil benötigt ein Eingabebild mit vier Bändern" +#: libvips/arithmetic/minpair.c:151 +#, fuzzy +msgid "minimum of a pair of images" +msgstr "ein Bilderpaar zusammenführen" -#: libvips/colour/im_icc_transform.c:543 -#: libvips/colour/im_icc_transform.c:1332 -msgid "RGB profile needs a 3 band input image" -msgstr "RGB-Profil benötigt ein Eingabebild mit drei Bändern" +#: libvips/arithmetic/multiply.c:195 +msgid "multiply two images" +msgstr "zwei Bilder multiplizieren" -#: libvips/colour/im_icc_transform.c:634 -#: libvips/colour/im_icc_transform.c:1427 -msgid "no embedded profile" -msgstr "kein eingebettetes Profil" +#: libvips/arithmetic/nary.c:80 +#, fuzzy +msgid "nary operations" +msgstr "unäre Transaktionen" -#: libvips/colour/im_icc_transform.c:726 -#: libvips/colour/im_icc_transform.c:1511 -msgid "unsupported bit depth" -msgstr "nicht unterstützte Bit-Tiefe" +#: libvips/arithmetic/nary.c:88 libvips/conversion/arrayjoin.c:395 +#: libvips/conversion/bandjoin.c:202 libvips/conversion/bandrank.c:255 +#: libvips/conversion/composite.cpp:1581 libvips/iofuncs/system.c:278 +msgid "Array of input images" +msgstr "Feld von Eingabebildern" -#: libvips/colour/im_icc_transform.c:815 -#: libvips/colour/im_icc_transform.c:1605 -msgid "unable to get media white point" -msgstr "weißer Medienpunkt kann nicht abgefragt werden" +#: libvips/arithmetic/profile.c:293 +#, fuzzy +msgid "find image profiles" +msgstr "Bildmittelwert finden" -#: libvips/colour/im_icc_transform.c:1672 -msgid "lcms library not linked to this VIPS" -msgstr "gegen die »lcms«-Bibliothek wird in diesem VIPS nicht verlinkt" +#: libvips/arithmetic/profile.c:301 libvips/arithmetic/project.c:332 +msgid "Columns" +msgstr "" -#: libvips/colour/im_icc_transform.c:1682 -#: libvips/colour/im_icc_transform.c:1691 -#: libvips/colour/im_icc_transform.c:1701 -#: libvips/colour/im_icc_transform.c:1710 -msgid "lmcs library not linked to this VIPS" -msgstr "gegen die »lmcs«-Bibliothek wird in diesem VIPS nicht verlinkt" +#: libvips/arithmetic/profile.c:302 +msgid "First non-zero pixel in column" +msgstr "" -#: libvips/colour/disp.c:397 -msgid "out of range [0,255]" -msgstr "außerhalb des Bereichs [0,255]" +#: libvips/arithmetic/profile.c:307 libvips/arithmetic/project.c:338 +msgid "Rows" +msgstr "" -#: libvips/colour/disp.c:423 -msgid "bad display type" -msgstr "falsche Anzeigetyp" +#: libvips/arithmetic/profile.c:308 +msgid "First non-zero pixel in row" +msgstr "" -#: libvips/colour/disp.c:537 -msgid "display unknown" -msgstr "Anzeige unbekannt" +#: libvips/arithmetic/project.c:324 +#, fuzzy +msgid "find image projections" +msgstr "Minimum des Bildes finden" -#: libvips/colour/im_disp2XYZ.c:86 -msgid "input not 3-band uncoded char" -msgstr "Eingabe ist kein unkodiertes Zeichen mit drei Bändern" +#: libvips/arithmetic/project.c:333 +msgid "Sums of columns" +msgstr "" -#: libvips/colour/im_XYZ2disp.c:139 -msgid "3-band uncoded float only" -msgstr "nur unkodierte Fließkommazahlen mit drei Bändern" +#: libvips/arithmetic/project.c:339 +msgid "Sums of rows" +msgstr "" -#: libvips/colour/im_lab_morph.c:75 -msgid "bad greyscale mask size" -msgstr "falsche Grauskala-Maskengröße" +#: libvips/arithmetic/relational.c:238 +#, fuzzy +msgid "relational operation on two images" +msgstr "eine relationale Transaktion für ein Bilderpaar" -#: libvips/colour/im_lab_morph.c:86 -#, c-format -msgid "bad greyscale mask value, row %d" -msgstr "falscher Grauskala-Maskenwert, Reihe %d" +#: libvips/arithmetic/relational.c:247 libvips/arithmetic/relational.c:612 +#, fuzzy +msgid "Relational to perform" +msgstr "relational durchzuführen" -#: libvips/conversion/im_gaussnoise.c:124 -msgid "bad parameter" -msgstr "falscher Parameter" +#: libvips/arithmetic/relational.c:603 +msgid "relational operations against a constant" +msgstr "relationale Transaktion für eine Konstante" -#: libvips/conversion/bandmean.c:191 -msgid "band-wise average" -msgstr "bandweiser Durchschnitt" +#: libvips/arithmetic/remainder.c:192 +msgid "remainder after integer division of two images" +msgstr "Rest nach Ganzzahldivision zweier Bilder" -#: libvips/conversion/cast.c:123 -#, c-format -msgid "%d underflows and %d overflows detected" -msgstr "%d Unter- und %d Überläufe entdeckt" +#: libvips/arithmetic/remainder.c:353 +msgid "remainder after integer division of an image and a constant" +msgstr "Rest nach Ganzzahldivision eines Bildes und einer Konstante" -#: libvips/conversion/cast.c:470 -msgid "cast an image" -msgstr "ein Bild umwandeln" +#: libvips/arithmetic/round.c:173 +msgid "perform a round function on an image" +msgstr "eine Rundungsfunktion für ein Bild ausführen" -#: libvips/conversion/cast.c:480 libvips/conversion/copy.c:352 -#: libvips/iofuncs/image.c:866 -msgid "Format" -msgstr "Format" +#: libvips/arithmetic/round.c:181 +msgid "Round operation" +msgstr "Rundungstransakktion" -#: libvips/conversion/cast.c:481 -msgid "Format to cast to" -msgstr "Format, in das umgewandelt werden soll" +#: libvips/arithmetic/round.c:182 +#, fuzzy +msgid "Rounding operation to perform" +msgstr "durchzuführende Rundungstransakktion" -#: libvips/conversion/ifthenelse.c:395 -msgid "ifthenelse an image" -msgstr "fallsdannsonst eines Bildes" +#: libvips/arithmetic/sign.c:174 +msgid "unit vector of pixel" +msgstr "Einheitsvektor von Bildpunkten" -#: libvips/conversion/ifthenelse.c:399 -msgid "Condition" -msgstr "Bedingung" +#: libvips/arithmetic/statistic.c:161 +msgid "VIPS statistic operations" +msgstr "statistische VIPS-Transaktionen" -#: libvips/conversion/ifthenelse.c:400 -msgid "Condition input image" -msgstr "Bedingung des Eingabebilds" +#: libvips/arithmetic/stats.c:434 +#, fuzzy +msgid "find many image stats" +msgstr "ein Bild umdrehen" -#: libvips/conversion/ifthenelse.c:405 -msgid "Then image" -msgstr "dann Bild" +#: libvips/arithmetic/subtract.c:174 +msgid "subtract two images" +msgstr "zwei Bilder subtrahieren" -#: libvips/conversion/ifthenelse.c:406 -msgid "Source for TRUE pixels" -msgstr "Quelle für TRUE-Bildpunkte" +#: libvips/arithmetic/sum.c:149 +#, fuzzy +msgid "sum an array of images" +msgstr "ein Bilderpaar zusammenführen" -#: libvips/conversion/ifthenelse.c:411 -msgid "Else image" -msgstr "sonst Bild" +#: libvips/arithmetic/unary.c:81 +msgid "unary operations" +msgstr "unäre Transaktionen" -#: libvips/conversion/ifthenelse.c:412 -msgid "Source for FALSE pixels" -msgstr "Quelle für FALSE-Bildpunkte" +#: libvips/arithmetic/unaryconst.c:138 +msgid "unary operations with a constant" +msgstr "unäre Transaktionen mit einer Konstante" -#: libvips/conversion/ifthenelse.c:417 -msgid "blend" -msgstr "Mischung" +#: libvips/arithmetic/unaryconst.c:142 +msgid "c" +msgstr "c" -#: libvips/conversion/ifthenelse.c:418 -msgid "Blend smoothly between then and else parts" -msgstr "nahtlos zwischen »dann«- und »sonst«-Teilen mischen" +#: libvips/arithmetic/unaryconst.c:143 +msgid "Array of constants" +msgstr "Feld aus Konstanten" -#: libvips/conversion/insert.c:349 -msgid "insert an image" -msgstr "ein Bild einfügen" +#: libvips/colour/CMYK2XYZ.c:114 libvips/colour/CMYK2XYZ.c:182 +msgid "transform CMYK to XYZ" +msgstr "" -#: libvips/conversion/insert.c:353 -msgid "Main" -msgstr "primär" +#: libvips/colour/colour.c:288 +msgid "too many input images" +msgstr "zu viele Eingabebilder" -#: libvips/conversion/insert.c:354 -msgid "Main input image" -msgstr "Haupteingabebild" +#: libvips/colour/colour.c:409 +#, fuzzy +msgid "color operations" +msgstr "Transaktionen" -#: libvips/conversion/insert.c:359 -msgid "Sub-image" -msgstr "Teilbild" +#: libvips/colour/colour.c:476 +msgid "color space transformations" +msgstr "" -#: libvips/conversion/insert.c:360 -msgid "Sub-image to insert into main image" -msgstr "Teilbild, das in das Hauptbild eingefügt werden soll" +#: libvips/colour/colour.c:569 +msgid "change color coding" +msgstr "" -#: libvips/conversion/insert.c:365 -msgid "X" -msgstr "X" +#: libvips/colour/colour.c:680 +msgid "calculate color difference" +msgstr "" -#: libvips/conversion/insert.c:366 -msgid "Left edge of sub in main" -msgstr "linker Rand des Teilbilds im Hauptbild" +#: libvips/colour/colour.c:685 +#, fuzzy +msgid "Left-hand input image" +msgstr "zweites Eingabebild" -#: libvips/conversion/insert.c:372 -msgid "Y" -msgstr "Y" +#: libvips/colour/colour.c:691 +#, fuzzy +msgid "Right-hand input image" +msgstr "Haupteingabebild" -#: libvips/conversion/insert.c:373 -msgid "Top edge of sub in main" -msgstr "oberer Rand des Teilbilds im Hauptbild" +#: libvips/colour/colourspace.c:145 +#, fuzzy +msgid "too few bands for operation" +msgstr "Rundungstransakktion" -#: libvips/conversion/insert.c:379 libvips/conversion/join.c:233 -msgid "Expand" -msgstr "expandieren" +#: libvips/colour/colourspace.c:519 +#, fuzzy, c-format +msgid "no known route from '%s' to '%s'" +msgstr "unbekanntes Argument »%s«" -#: libvips/conversion/insert.c:380 libvips/conversion/join.c:234 -msgid "Expand output to hold all of both inputs" -msgstr "Ausgabe so expandieren, dass sie beide Eingaben vollständig enthält" +#: libvips/colour/colourspace.c:551 +msgid "convert to a new colorspace" +msgstr "" -#: libvips/conversion/insert.c:386 libvips/conversion/join.c:247 -msgid "Background" -msgstr "Hintergrund" +#: libvips/colour/colourspace.c:569 +msgid "Space" +msgstr "" -#: libvips/conversion/insert.c:387 libvips/conversion/join.c:248 -msgid "Colour for new pixels" -msgstr "Farbe für neue Bildpunkte" +#: libvips/colour/colourspace.c:570 +msgid "Destination color space" +msgstr "" -#: libvips/conversion/tilecache.c:418 libvips/conversion/cache.c:102 -msgid "cache an image" -msgstr "ein Bild zwischenspeichern" +#: libvips/colour/colourspace.c:576 +msgid "Source space" +msgstr "" -#: libvips/conversion/tilecache.c:428 libvips/conversion/cache.c:112 -#: libvips/foreign/tiffsave.c:213 -msgid "Tile width" -msgstr "Kachelbreite" +#: libvips/colour/colourspace.c:577 +#, fuzzy +msgid "Source color space" +msgstr "nicht unterstützter Farbraum %d" -#: libvips/conversion/tilecache.c:429 libvips/conversion/cache.c:113 -#: libvips/foreign/tiffsave.c:214 -msgid "Tile width in pixels" -msgstr "Kachelbreite in Bildpunkten" +#: libvips/colour/dE00.c:236 +msgid "calculate dE00" +msgstr "" -#: libvips/conversion/tilecache.c:435 libvips/conversion/cache.c:119 -#: libvips/foreign/tiffsave.c:220 -msgid "Tile height" -msgstr "Kachelhöhe" +#: libvips/colour/dE76.c:113 +msgid "calculate dE76" +msgstr "" -#: libvips/conversion/tilecache.c:436 libvips/conversion/cache.c:120 -#: libvips/foreign/tiffsave.c:221 -msgid "Tile height in pixels" -msgstr "Kachelhöhe in Bildpunkten" +#: libvips/colour/dECMC.c:61 +msgid "calculate dECMC" +msgstr "" -#: libvips/conversion/tilecache.c:442 libvips/conversion/cache.c:126 -msgid "Max tiles" -msgstr "Kacheln maximal" +#: libvips/colour/float2rad.c:206 +msgid "transform float RGB to Radiance coding" +msgstr "" -#: libvips/conversion/tilecache.c:443 libvips/conversion/cache.c:127 -msgid "Maximum number of tiles to cache" -msgstr "maximale Anzahl von Kacheln, die zwischengespeichert werden soll" +#: libvips/colour/HSV2sRGB.c:112 +msgid "transform HSV to sRGB" +msgstr "" -#: libvips/conversion/tilecache.c:449 -msgid "Strategy" -msgstr "Strategie" +#: libvips/colour/icc_transform.c:272 libvips/colour/scRGB2BW.c:190 +#: libvips/colour/scRGB2sRGB.c:224 +#, fuzzy +msgid "depth must be 8 or 16" +msgstr "»mwidth« muss -1 oder >= 0 sein" -#: libvips/conversion/tilecache.c:450 -msgid "Expected access pattern" -msgstr "erwartetes Zugriffsmuster" +#: libvips/colour/icc_transform.c:284 +#, c-format +msgid "unimplemented input color space 0x%x" +msgstr "nicht implementierter Eingabefarbraum 0x%x" -#: libvips/conversion/im_text.c:132 -msgid "no text to render" -msgstr "kein Text zu rendern" +#: libvips/colour/icc_transform.c:360 +#, c-format +msgid "unimplemented output color space 0x%x" +msgstr "nicht implementierter Ausgabefarbraum 0x%x" -#: libvips/conversion/im_text.c:219 -msgid "invalid markup in text" -msgstr "ungültige Auszeichnung im Text" +#: libvips/colour/icc_transform.c:437 +#, fuzzy +msgid "no device profile" +msgstr "kein eingebettetes Profil" -#: libvips/conversion/im_text.c:252 -msgid "pangoft2 support disabled" -msgstr "Pangoft2-Unterstützung deaktiviert" +#: libvips/colour/icc_transform.c:612 libvips/colour/icc_transform.c:635 +#: libvips/colour/icc_transform.c:658 libvips/iofuncs/operation.c:442 +msgid "input" +msgstr "Eingabe" -#: libvips/conversion/im_zoom.c:331 -msgid "zoom factors should be >= 0" -msgstr "Zoomfaktoren sollten >=0 sein" +#: libvips/colour/icc_transform.c:612 libvips/colour/icc_transform.c:635 +#: libvips/colour/icc_transform.c:658 libvips/iofuncs/operation.c:443 +msgid "output" +msgstr "Ausgabe" -#. Make sure we won't get integer overflow. -#. -#: libvips/conversion/im_zoom.c:338 -msgid "zoom factors too large" -msgstr "Zoomfaktoren zu groß" +#: libvips/colour/icc_transform.c:631 +#, c-format +msgid "" +"fallback to suggested %s intent, as profile does not support %s %s intent" +msgstr "" -#: libvips/conversion/conver_dispatch.c:918 -#: libvips/inplace/inplace_dispatch.c:171 -msgid "vectors not same length" -msgstr "Vektoren ungleicher Länge" +#: libvips/colour/icc_transform.c:656 +#, c-format +msgid "profile does not support %s %s intent" +msgstr "" -#: libvips/conversion/extract.c:147 -msgid "bad extract area" -msgstr "falscher extrahierter Bereich" +#: libvips/colour/icc_transform.c:757 +msgid "unable to load or find any compatible input profile" +msgstr "" -#: libvips/conversion/extract.c:190 -msgid "extract an area from an image" -msgstr "einen Bereich eines Bildes extrahieren" +#: libvips/colour/icc_transform.c:775 +msgid "transform using ICC profiles" +msgstr "" -#: libvips/conversion/extract.c:318 -msgid "bad extract band" -msgstr "schlecht extrahiertes Band" +#: libvips/colour/icc_transform.c:779 libvips/resample/thumbnail.c:1030 +msgid "Intent" +msgstr "" -#: libvips/conversion/extract.c:347 -msgid "extract band from an image" -msgstr "Band aus einem Bild extrahieren" +#: libvips/colour/icc_transform.c:780 libvips/resample/thumbnail.c:1031 +msgid "Rendering intent" +msgstr "" -#: libvips/conversion/extract.c:359 -msgid "Band" -msgstr "Band" +#: libvips/colour/icc_transform.c:786 +msgid "PCS" +msgstr "" -#: libvips/conversion/extract.c:360 -msgid "Band to extract" -msgstr "zu extrahierendes Band" +#: libvips/colour/icc_transform.c:787 +msgid "Set Profile Connection Space" +msgstr "" -#: libvips/conversion/extract.c:366 -msgid "n" -msgstr "n" +#: libvips/colour/icc_transform.c:793 +msgid "Black point compensation" +msgstr "" -#: libvips/conversion/extract.c:367 -msgid "Number of bands to extract" -msgstr "Anzahl zu extrahierender Bänder" +#: libvips/colour/icc_transform.c:794 +msgid "Enable black point compensation" +msgstr "" -#: libvips/conversion/embed.c:430 libvips/iofuncs/image.c:1777 -msgid "bad dimensions" -msgstr "falsche Abmessungen" +#: libvips/colour/icc_transform.c:969 +msgid "import from device with ICC profile" +msgstr "" -#: libvips/conversion/embed.c:512 -msgid "embed an image in a larger image" -msgstr "ein Bild in ein größeres Bild einbetten" +#: libvips/colour/icc_transform.c:975 libvips/colour/icc_transform.c:1258 +msgid "Embedded" +msgstr "" -#: libvips/conversion/embed.c:523 -msgid "Left edge of input in output" -msgstr "linker Rand der Eingabe in der Ausgabe" +#: libvips/colour/icc_transform.c:976 libvips/colour/icc_transform.c:1259 +msgid "Use embedded input profile, if available" +msgstr "" -#: libvips/conversion/embed.c:530 -msgid "Top edge of input in output" -msgstr "oberer Rand der Eingabe in der Ausgabe" +#: libvips/colour/icc_transform.c:982 libvips/colour/icc_transform.c:1265 +#, fuzzy +msgid "Input profile" +msgstr "Profil" -#: libvips/conversion/embed.c:537 libvips/conversion/copy.c:332 -#: libvips/conversion/black.c:129 libvips/foreign/rawload.c:123 -#: libvips/iofuncs/image.c:846 -msgid "Image width in pixels" -msgstr "Bildbreite in Bildpunkten" +#: libvips/colour/icc_transform.c:983 libvips/colour/icc_transform.c:1266 +#, fuzzy +msgid "Filename to load input profile from" +msgstr "Name der Datei, aus der geladen werden soll" -#: libvips/conversion/embed.c:544 libvips/conversion/copy.c:339 -#: libvips/conversion/black.c:136 libvips/foreign/rawload.c:130 -#: libvips/iofuncs/image.c:853 -msgid "Image height in pixels" -msgstr "Bildhöhe in Bildpunkten" +#: libvips/colour/icc_transform.c:1046 libvips/colour/icc_transform.c:1212 +#, fuzzy +msgid "no output profile" +msgstr "kein eingebettetes Profil" -#: libvips/conversion/embed.c:550 -msgid "Extend" -msgstr "vergrößern" +#: libvips/colour/icc_transform.c:1141 +msgid "output to device with ICC profile" +msgstr "" -#: libvips/conversion/embed.c:551 -msgid "How to generate the extra pixels" -msgstr "Wie werden die zusätzlichen Bildpunkte erzeugt?" +#: libvips/colour/icc_transform.c:1147 libvips/colour/icc_transform.c:1251 +#, fuzzy +msgid "Output profile" +msgstr "Ausgabewert" -#: libvips/conversion/im_grid.c:164 -#: libvips/convolution/im_contrast_surface.c:140 libvips/iofuncs/image.c:710 -#: libvips/iofuncs/sinkscreen.c:1082 libvips/morphology/im_rank.c:342 -msgid "bad parameters" -msgstr "falsche Parameter" +#: libvips/colour/icc_transform.c:1148 libvips/colour/icc_transform.c:1252 +#, fuzzy +msgid "Filename to load output profile from" +msgstr "Name der Datei, aus der geladen werden soll" -#: libvips/conversion/im_grid.c:169 -msgid "bad grid geometry" -msgstr "falsche Gittergeometrie" +#: libvips/colour/icc_transform.c:1154 libvips/colour/icc_transform.c:1272 +#: libvips/colour/scRGB2BW.c:249 libvips/colour/scRGB2sRGB.c:282 +#: libvips/foreign/dzsave.c:2364 libvips/foreign/tiffsave.c:378 +msgid "Depth" +msgstr "" -#: libvips/conversion/join.c:210 -msgid "join a pair of images" -msgstr "ein Bilderpaar zusammenführen" +#: libvips/colour/icc_transform.c:1155 libvips/colour/icc_transform.c:1273 +#: libvips/colour/scRGB2BW.c:250 libvips/colour/scRGB2sRGB.c:283 +msgid "Output device space depth in bits" +msgstr "" -#: libvips/conversion/join.c:214 -msgid "in1" -msgstr "in1" +#: libvips/colour/icc_transform.c:1245 +msgid "transform between devices with ICC profiles" +msgstr "" -#: libvips/conversion/join.c:215 -msgid "First input image" -msgstr "erstes Eingabebild" +#: libvips/colour/icc_transform.c:1321 +msgid "unable to get media white point" +msgstr "weißer Medienpunkt kann nicht abgefragt werden" -#: libvips/conversion/join.c:220 -msgid "in2" -msgstr "in2" +#: libvips/colour/icc_transform.c:1416 +#, fuzzy +msgid "libvips configured without lcms support" +msgstr "VIPS wurde ohne FFT-Unterstützung konfiguriert" -#: libvips/conversion/join.c:221 -msgid "Second input image" -msgstr "zweites Eingabebild" +#: libvips/colour/Lab2LabQ.c:137 +msgid "transform float Lab to LabQ coding" +msgstr "" -#: libvips/conversion/join.c:226 -msgid "direction" -msgstr "Richtung" +#: libvips/colour/Lab2LabS.c:82 +msgid "transform float Lab to signed short" +msgstr "" -#: libvips/conversion/join.c:227 -msgid "Join left-right or up-down" -msgstr "von links nach rechts oder von oben nach unten zusammenführen" +#: libvips/colour/Lab2LCh.c:132 +msgid "transform Lab to LCh" +msgstr "" -#: libvips/conversion/join.c:240 -msgid "Shim" -msgstr "Scheibe" +#: libvips/colour/Lab2XYZ.c:177 +msgid "transform CIELAB to XYZ" +msgstr "" -#: libvips/conversion/join.c:241 -msgid "Pixels between images" -msgstr "Bildpunkte zwischen Bildern" +#: libvips/colour/Lab2XYZ.c:183 libvips/colour/XYZ2Lab.c:236 +msgid "Temperature" +msgstr "" -#: libvips/conversion/join.c:254 -msgid "Align" -msgstr "ausrichten" +#: libvips/colour/Lab2XYZ.c:184 +msgid "Color temperature" +msgstr "" -#: libvips/conversion/join.c:255 -msgid "Align on the low, centre or high coordinate edge" -msgstr "am Rand der unteren, mittleren oder höchsten Koordinate ausrichten" +#: libvips/colour/LabQ2Lab.c:125 +msgid "unpack a LabQ image to float Lab" +msgstr "" -#: libvips/conversion/rot.c:351 -msgid "rotate an image" -msgstr "ein Bild drehen" +#: libvips/colour/LabQ2LabS.c:104 +msgid "unpack a LabQ image to short Lab" +msgstr "" -#: libvips/conversion/rot.c:361 -msgid "Angle" -msgstr "Winkel" +#: libvips/colour/LabQ2sRGB.c:549 +#, fuzzy +msgid "convert a LabQ image to sRGB" +msgstr "ein Bild invertieren" -#: libvips/conversion/rot.c:362 -msgid "Angle to rotate image" -msgstr "Winkel zum Drehen eines Bildes" +#: libvips/colour/LabS2Lab.c:78 +msgid "transform signed short Lab to float" +msgstr "" -#: libvips/conversion/flip.c:236 -msgid "flip an image" -msgstr "ein Bild umdrehen" +#: libvips/colour/LabS2LabQ.c:127 +msgid "transform short Lab to LabQ coding" +msgstr "" -#: libvips/conversion/flip.c:246 -msgid "Direction" -msgstr "Richtung" +#: libvips/colour/LCh2Lab.c:111 +msgid "transform LCh to Lab" +msgstr "" -#: libvips/conversion/flip.c:247 -msgid "Direction to flip image" -msgstr "Richtung, nach der das Bild umgedreht werden soll" +#: libvips/colour/LCh2UCS.c:206 libvips/colour/UCS2LCh.c:273 +msgid "transform LCh to CMC" +msgstr "" -#: libvips/conversion/copy.c:314 -msgid "copy an image" -msgstr "ein Bild kopieren" +#: libvips/colour/profile_load.c:123 +#, fuzzy, c-format +msgid "unable to load profile \"%s\"" +msgstr "Profil »%s« kann nicht geöffnet werden" -#: libvips/conversion/copy.c:324 -msgid "Swap" -msgstr "austauschen" +# Portable Pixmap +#: libvips/colour/profile_load.c:147 +#, fuzzy +msgid "load named ICC profile" +msgstr "PPM aus Datei laden" -#: libvips/conversion/copy.c:325 -msgid "Swap bytes in image between little and big-endian" -msgstr "Byte im Bild zwischen Little- und Big-Endian austauschen" +#: libvips/colour/profile_load.c:151 +msgid "Name" +msgstr "" -#: libvips/conversion/copy.c:345 libvips/conversion/black.c:142 -#: libvips/foreign/rawload.c:136 libvips/iofuncs/image.c:859 -msgid "Bands" -msgstr "Bänder" +#: libvips/colour/profile_load.c:152 +#, fuzzy +msgid "Profile name" +msgstr "Dateiname" -#: libvips/conversion/copy.c:346 libvips/conversion/black.c:143 -#: libvips/foreign/rawload.c:137 libvips/iofuncs/image.c:860 -msgid "Number of bands in image" -msgstr "Anzahl der Bänder in einem Bild" +#: libvips/colour/profile_load.c:158 libvips/foreign/foreign.c:1922 +#, fuzzy +msgid "Profile" +msgstr "Profil" -#: libvips/conversion/copy.c:353 libvips/iofuncs/image.c:867 -msgid "Pixel format in image" -msgstr "Bildpunktformat im Bild" +#: libvips/colour/profile_load.c:159 +#, fuzzy +msgid "Loaded profile" +msgstr "kein eingebettetes Profil" -#: libvips/conversion/copy.c:359 libvips/iofuncs/image.c:873 -msgid "Coding" -msgstr "Kodierung" +#: libvips/colour/rad2float.c:184 +#, fuzzy +msgid "unpack Radiance coding to float RGB" +msgstr "Nur Radiance-Kodierung" -#: libvips/conversion/copy.c:360 libvips/iofuncs/image.c:874 -msgid "Pixel coding" -msgstr "Bildpunktkodierung" +#: libvips/colour/scRGB2BW.c:231 +msgid "convert scRGB to BW" +msgstr "" -#: libvips/conversion/copy.c:366 libvips/iofuncs/image.c:880 -msgid "Interpretation" -msgstr "Interpretation" +#: libvips/colour/scRGB2sRGB.c:264 +#, fuzzy +msgid "convert an scRGB image to sRGB" +msgstr "ein Bild invertieren" -#: libvips/conversion/copy.c:367 libvips/iofuncs/image.c:881 -msgid "Pixel interpretation" -msgstr "Bildpunktinterpretation" +#: libvips/colour/scRGB2XYZ.c:185 +msgid "transform scRGB to XYZ" +msgstr "" -#: libvips/conversion/copy.c:373 libvips/foreign/tiffsave.c:249 -#: libvips/iofuncs/image.c:887 -msgid "Xres" -msgstr "Xres" +#: libvips/colour/sRGB2HSV.c:133 +msgid "transform sRGB to HSV" +msgstr "" -#: libvips/conversion/copy.c:374 libvips/foreign/tiffsave.c:250 -#: libvips/iofuncs/image.c:888 -msgid "Horizontal resolution in pixels/mm" -msgstr "horizontale Auflösung in Bildpunkten/mm" +#: libvips/colour/sRGB2scRGB.c:282 +#, fuzzy +msgid "convert an sRGB image to scRGB" +msgstr "ein Bild invertieren" -#: libvips/conversion/copy.c:380 libvips/foreign/tiffsave.c:256 -#: libvips/iofuncs/image.c:894 -msgid "Yres" -msgstr "Yres" +#: libvips/colour/XYZ2CMYK.c:113 libvips/colour/XYZ2CMYK.c:193 +msgid "transform XYZ to CMYK" +msgstr "" -#: libvips/conversion/copy.c:381 libvips/foreign/tiffsave.c:257 -#: libvips/iofuncs/image.c:895 -msgid "Vertical resolution in pixels/mm" -msgstr "vertikale Auflösung in Bildpunkten/mm" +#: libvips/colour/XYZ2Lab.c:230 +msgid "transform XYZ to Lab" +msgstr "" -#: libvips/conversion/copy.c:387 libvips/iofuncs/image.c:901 -msgid "Xoffset" -msgstr "Xoffset" +#: libvips/colour/XYZ2Lab.c:237 +msgid "Colour temperature" +msgstr "" -#: libvips/conversion/copy.c:388 libvips/iofuncs/image.c:902 -msgid "Horizontal offset of origin" -msgstr "horizontaler Versatz vom Ursprung" +#: libvips/colour/XYZ2scRGB.c:194 +msgid "transform XYZ to scRGB" +msgstr "" -#: libvips/conversion/copy.c:394 libvips/iofuncs/image.c:908 -msgid "Yoffset" -msgstr "Yoffset" +#: libvips/colour/XYZ2Yxy.c:98 +msgid "transform XYZ to Yxy" +msgstr "" -#: libvips/conversion/copy.c:395 libvips/iofuncs/image.c:909 -msgid "Vertical offset of origin" -msgstr "vertikaler Versatz vom Ursprung" +#: libvips/colour/Yxy2XYZ.c:103 +msgid "transform Yxy to XYZ" +msgstr "" -#: libvips/conversion/bandary.c:127 -msgid "no input images" -msgstr "keine Eingabebilder" +#: libvips/conversion/addalpha.c:84 +msgid "append an alpha channel" +msgstr "" -#: libvips/conversion/bandary.c:173 -msgid "operations on image bands" -msgstr "Transaktionen für Bänder von Bildern" +#: libvips/conversion/arrayjoin.c:388 +#, fuzzy +msgid "join an array of images" +msgstr "ein Bilderpaar zusammenführen" -#: libvips/conversion/conversion.c:85 -msgid "conversion operations" -msgstr "Umwandlungstransaktionen" +#: libvips/conversion/arrayjoin.c:402 +#, fuzzy +msgid "Number of images across grid" +msgstr "Anzahl der Patches über ein Diagramm" -#: libvips/conversion/recomb.c:160 -msgid "bands in must equal matrix width" -msgstr "»in«-Bänder müssen die gleiche Breite wie die Matrix haben" +#: libvips/conversion/arrayjoin.c:408 libvips/conversion/join.c:263 +msgid "Shim" +msgstr "Scheibe" -#: libvips/conversion/recomb.c:196 -msgid "linear recombination with matrix" -msgstr "lineare Neukombinierung mit der Matrix" +#: libvips/conversion/arrayjoin.c:409 libvips/conversion/join.c:264 +msgid "Pixels between images" +msgstr "Bildpunkte zwischen Bildern" -#: libvips/conversion/recomb.c:206 -msgid "M" -msgstr "M" +#: libvips/conversion/arrayjoin.c:416 libvips/conversion/join.c:271 +msgid "Colour for new pixels" +msgstr "Farbe für neue Bildpunkte" -#: libvips/conversion/recomb.c:207 -msgid "matrix of coefficients" -msgstr "Matrix der Koeffizienten" +#: libvips/conversion/arrayjoin.c:422 +#, fuzzy +msgid "Horizontal align" +msgstr "horizontaler Versatz vom Ursprung" -#: libvips/conversion/replicate.c:192 -msgid "replicate an image" -msgstr "ein Bild nachmachen" +#: libvips/conversion/arrayjoin.c:423 +#, fuzzy +msgid "Align on the left, centre or right" +msgstr "am Rand der unteren, mittleren oder höchsten Koordinate ausrichten" -#: libvips/conversion/replicate.c:203 -msgid "Repeat this many times horizontally" -msgstr "horizontal so oft wiederholen" +#: libvips/conversion/arrayjoin.c:429 +#, fuzzy +msgid "Vertical align" +msgstr "vertikaler Versatz vom Ursprung" -#: libvips/conversion/replicate.c:210 -msgid "Repeat this many times vertically" -msgstr "vertikal so oft wiederholen" +#: libvips/conversion/arrayjoin.c:430 +#, fuzzy +msgid "Align on the top, centre or bottom" +msgstr "am Rand der unteren, mittleren oder höchsten Koordinate ausrichten" -#: libvips/conversion/black.c:124 -msgid "make a black image" -msgstr "ein schwarzes Bild erstellen" +#: libvips/conversion/arrayjoin.c:436 +#, fuzzy +msgid "Horizontal spacing" +msgstr "horizontaler Versatz vom Ursprung" -#: libvips/conversion/im_msb.c:134 libvips/conversion/im_msb.c:213 -msgid "unknown coding" -msgstr "unbekannte Kodierung" +#: libvips/conversion/arrayjoin.c:437 +#, fuzzy +msgid "Horizontal spacing between images" +msgstr "Bildpunkte zwischen Bildern" -#: libvips/conversion/im_msb.c:169 libvips/resample/im_rightshift_size.c:116 -msgid "bad arguments" -msgstr "falsche Argumente" +#: libvips/conversion/arrayjoin.c:443 +msgid "Vertical spacing" +msgstr "" -#: libvips/conversion/im_msb.c:183 libvips/conversion/im_msb.c:200 -msgid "image does not have that many bands" -msgstr "Bild hat nicht so viele Bänder" +#: libvips/conversion/arrayjoin.c:444 +#, fuzzy +msgid "Vertical spacing between images" +msgstr "Bildpunkte zwischen Bildern" -#: libvips/conversion/im_system_image.c:76 -#, c-format -msgid "command failed: \"%s\"" -msgstr "Befehl fehlgeschlagen: »%s«" +#: libvips/conversion/autorot.c:203 +msgid "autorotate image by exif tag" +msgstr "" -#: libvips/conversion/im_subsample.c:202 -msgid "factors should both be >= 1" -msgstr "beide Faktoren sollten >=1 sein" +#: libvips/conversion/autorot.c:213 libvips/conversion/rot45.c:274 +#: libvips/conversion/rot.c:371 libvips/convolution/compass.c:170 +#: libvips/foreign/dzsave.c:2378 libvips/mosaicing/mosaic.c:281 +#: libvips/resample/similarity.c:207 libvips/resample/similarity.c:276 +msgid "Angle" +msgstr "Winkel" -#: libvips/conversion/im_subsample.c:221 libvips/resample/im_shrink.c:286 -msgid "image has shrunk to nothing" -msgstr "Bild ist zu nichts geschrumpft" +#: libvips/conversion/autorot.c:214 +msgid "Angle image was rotated by" +msgstr "" -#: libvips/conversion/bandjoin.c:165 -msgid "bandwise join a set of images" -msgstr "einen Satz Bilder bandweise zusammenführen" +#: libvips/conversion/autorot.c:220 +msgid "Flip" +msgstr "" -#: libvips/conversion/bandjoin.c:172 -msgid "Array of input images" -msgstr "Feld von Eingabebildern" +#: libvips/conversion/autorot.c:221 +msgid "Whether the image was flipped or not" +msgstr "" -#: libvips/convolution/im_contrast_surface.c:147 -msgid "parameters would result in zero size output image" -msgstr "Parameter würden zu einem Ausgabebild der Größe Null führen" +#: libvips/conversion/bandary.c:211 libvips/conversion/bandary.c:280 +#: libvips/conversion/composite.cpp:1299 +msgid "no input images" +msgstr "keine Eingabebilder" -#: libvips/convolution/im_aconvsep.c:130 libvips/convolution/im_aconv.c:223 -#: libvips/convolution/im_aconv.c:229 libvips/convolution/im_aconv.c:750 -msgid "mask too complex" -msgstr "Maske zu komplex" +#: libvips/conversion/bandary.c:257 +msgid "operations on image bands" +msgstr "Transaktionen für Bänder von Bildern" -#: libvips/convolution/im_aconvsep.c:798 libvips/convolution/im_conv.c:1038 -#: libvips/convolution/im_conv_f.c:340 libvips/convolution/im_aconv.c:980 -#: libvips/convolution/im_aconv.c:1201 libvips/morphology/morphology.c:721 -msgid "image too small for mask" -msgstr "Bild zu klein für Maske" +#: libvips/conversion/bandbool.c:75 +#, fuzzy, c-format +msgid "operator %s not supported across image bands" +msgstr "Transaktionen für Bänder von Bildern" -#: libvips/convolution/im_conv.c:215 -#, c-format -msgid "%d overflows and %d underflows detected" -msgstr "%d Über- und %d Unterläufe entdeckt" +#: libvips/conversion/bandbool.c:225 +#, fuzzy +msgid "boolean operation across image bands" +msgstr "Transaktionen für Bänder von Bildern" -#: libvips/convolution/im_conv.c:1125 libvips/convolution/im_conv_f.c:403 -msgid "expect 1xN or Nx1 input mask" -msgstr "1xN- oder Nx1-Eingabemaske wird erwartet" +#: libvips/conversion/bandbool.c:233 libvips/conversion/bandmean.c:213 +#: libvips/conversion/recomb.c:225 libvips/convolution/convolution.c:129 +#: libvips/convolution/correlation.c:151 libvips/morphology/morphology.c:122 +#: libvips/resample/resample.c:141 libvips/resample/thumbnail.c:1783 +msgid "Input image argument" +msgstr "Eingabebildargument" -# ref und in sind Objekte -#: libvips/convolution/im_fastcor.c:134 libvips/convolution/im_spcor.c:247 -msgid "ref not smaller than or equal to in" -msgstr "»ref« nicht kleiner oder gleich »in«" +#: libvips/conversion/bandfold.c:123 +msgid "@factor must be a factor of image width" +msgstr "" -#: libvips/convolution/im_sharpen.c:325 libvips/histograms_lut/im_stdif.c:196 -msgid "parameters out of range" -msgstr "Parameter außerhalb des Bereichs" +#: libvips/conversion/bandfold.c:155 +msgid "fold up x axis into bands" +msgstr "" -#: libvips/foreign/rawload.c:107 -msgid "load raw data from a file" -msgstr "Rohdaten aus einer Datei laden" +#: libvips/conversion/bandfold.c:167 libvips/conversion/bandunfold.c:170 +#: libvips/create/eye.c:108 +#, fuzzy +msgid "Factor" +msgstr "Q-Faktor" -#: libvips/foreign/rawload.c:115 libvips/foreign/fitssave.c:128 -#: libvips/foreign/ppmload.c:126 libvips/foreign/radload.c:126 -#: libvips/foreign/openslideload.c:176 libvips/foreign/tiffload.c:142 -#: libvips/foreign/fitsload.c:116 libvips/foreign/vipssave.c:125 -#: libvips/foreign/radsave.c:119 libvips/foreign/openexrload.c:137 -#: libvips/foreign/analyzeload.c:126 libvips/foreign/pngload.c:136 -#: libvips/foreign/tiffsave.c:169 libvips/foreign/vipsload.c:133 -#: libvips/foreign/magickload.c:146 libvips/foreign/matload.c:128 -#: libvips/foreign/jpegload.c:245 libvips/foreign/jpegsave.c:193 -#: libvips/foreign/rawsave.c:166 libvips/foreign/ppmsave.c:118 -#: libvips/foreign/csvsave.c:121 libvips/foreign/csvload.c:132 -#: libvips/foreign/pngsave.c:166 libvips/iofuncs/image.c:915 -msgid "Filename" -msgstr "Dateiname" +#: libvips/conversion/bandfold.c:168 +msgid "Fold by this factor" +msgstr "" -#: libvips/foreign/rawload.c:116 libvips/foreign/ppmload.c:127 -#: libvips/foreign/radload.c:127 libvips/foreign/openslideload.c:177 -#: libvips/foreign/tiffload.c:143 libvips/foreign/fitsload.c:117 -#: libvips/foreign/openexrload.c:138 libvips/foreign/analyzeload.c:127 -#: libvips/foreign/pngload.c:137 libvips/foreign/vipsload.c:134 -#: libvips/foreign/magickload.c:147 libvips/foreign/matload.c:129 -#: libvips/foreign/jpegload.c:246 libvips/foreign/csvload.c:133 -msgid "Filename to load from" -msgstr "Name der Datei, aus der geladen werden soll" +#: libvips/conversion/bandjoin.c:195 +msgid "bandwise join a set of images" +msgstr "einen Satz Bilder bandweise zusammenführen" -#: libvips/foreign/rawload.c:143 libvips/iofuncs/image.c:943 -msgid "Size of header" -msgstr "Größe der Kopfdaten" +#: libvips/conversion/bandjoin.c:430 +#, fuzzy +msgid "append a constant band to an image" +msgstr "Band aus einem Bild extrahieren" -#: libvips/foreign/rawload.c:144 libvips/iofuncs/image.c:944 -msgid "Offset in bytes from start of file" -msgstr "Versatz in Byte vom Anfang der Datei" +#: libvips/conversion/bandjoin.c:442 +msgid "Constants" +msgstr "" -#: libvips/foreign/fitssave.c:119 -# http://de.wikipedia.org/wiki/Flexible_Image_Transport_System -msgid "save image to fits file" -msgstr "Bild in FITS-Datei speichern" +#: libvips/conversion/bandjoin.c:443 +#, fuzzy +msgid "Array of constants to add" +msgstr "Feld aus Konstanten" -#: libvips/foreign/fitssave.c:129 libvips/foreign/vipssave.c:126 -#: libvips/foreign/radsave.c:120 libvips/foreign/tiffsave.c:170 -#: libvips/foreign/jpegsave.c:194 libvips/foreign/rawsave.c:167 -#: libvips/foreign/ppmsave.c:119 libvips/foreign/csvsave.c:122 -#: libvips/foreign/pngsave.c:167 -msgid "Filename to save to" -msgstr "Name der Datei in die gespeichert werden soll" +#: libvips/conversion/bandmean.c:206 +msgid "band-wise average" +msgstr "bandweiser Durchschnitt" -#: libvips/foreign/ppmload.c:114 -# Portable Pixmap -msgid "load ppm from file" -msgstr "PPM aus Datei laden" +#: libvips/conversion/bandrank.c:248 +#, fuzzy +msgid "band-wise rank of a set of images" +msgstr "einen Satz Bilder bandweise zusammenführen" -#: libvips/foreign/radload.c:114 -msgid "load a Radiance image from a file" -msgstr "ein Radiance-Bild aus einer Datei laden" +#: libvips/conversion/bandrank.c:262 +msgid "Select this band element from sorted list" +msgstr "" -#: libvips/foreign/openslideload.c:159 -msgid "load file with OpenSlide" -msgstr "Datei mit OpenSlide laden" +#: libvips/conversion/bandunfold.c:126 +msgid "@factor must be a factor of image bands" +msgstr "" -#: libvips/foreign/openslideload.c:183 -msgid "Level" -msgstr "Ebene" +#: libvips/conversion/bandunfold.c:158 +msgid "unfold image bands into x axis" +msgstr "" -#: libvips/foreign/openslideload.c:184 -msgid "Load this level from the file" -msgstr "diese Ebene aus der Datei laden" +#: libvips/conversion/bandunfold.c:171 +msgid "Unfold by this factor" +msgstr "" + +#: libvips/conversion/byteswap.c:232 +#, fuzzy +msgid "byteswap an image" +msgstr "ein Bild drehen" + +#: libvips/conversion/cache.c:98 libvips/conversion/tilecache.c:392 +msgid "cache an image" +msgstr "ein Bild zwischenspeichern" + +#: libvips/conversion/cache.c:114 libvips/conversion/tilecache.c:800 +#: libvips/foreign/dzsave.c:2451 libvips/foreign/jp2ksave.c:971 +#: libvips/foreign/tiffsave.c:287 +msgid "Tile width" +msgstr "Kachelbreite" + +#: libvips/conversion/cache.c:115 libvips/conversion/tilecache.c:801 +#: libvips/foreign/dzsave.c:2452 libvips/foreign/jp2ksave.c:972 +#: libvips/foreign/tiffsave.c:288 +msgid "Tile width in pixels" +msgstr "Kachelbreite in Bildpunkten" + +#: libvips/conversion/cache.c:121 libvips/conversion/grid.c:205 +#: libvips/conversion/sequential.c:249 libvips/conversion/tilecache.c:404 +#: libvips/foreign/dzsave.c:2458 libvips/foreign/jp2ksave.c:978 +#: libvips/foreign/tiffsave.c:294 +msgid "Tile height" +msgstr "Kachelhöhe" + +#: libvips/conversion/cache.c:122 libvips/conversion/sequential.c:250 +#: libvips/conversion/tilecache.c:405 libvips/foreign/dzsave.c:2459 +#: libvips/foreign/jp2ksave.c:979 libvips/foreign/tiffsave.c:295 +msgid "Tile height in pixels" +msgstr "Kachelhöhe in Bildpunkten" + +#: libvips/conversion/cache.c:128 libvips/conversion/tilecache.c:807 +msgid "Max tiles" +msgstr "Kacheln maximal" + +#: libvips/conversion/cache.c:129 libvips/conversion/tilecache.c:808 +msgid "Maximum number of tiles to cache" +msgstr "maximale Anzahl von Kacheln, die zwischengespeichert werden soll" + +#: libvips/conversion/cast.c:524 +msgid "cast an image" +msgstr "ein Bild umwandeln" + +#: libvips/conversion/cast.c:536 libvips/conversion/copy.c:305 +#: libvips/foreign/ppmsave.c:506 libvips/foreign/rawload.c:174 +#: libvips/foreign/vips2magick.c:482 libvips/iofuncs/image.c:1123 +msgid "Format" +msgstr "Format" + +#: libvips/conversion/cast.c:537 +msgid "Format to cast to" +msgstr "Format, in das umgewandelt werden soll" + +#: libvips/conversion/cast.c:543 +msgid "Shift" +msgstr "" + +#: libvips/conversion/cast.c:544 +msgid "Shift integer values up and down" +msgstr "" + +#: libvips/conversion/composite.cpp:1304 +#, fuzzy, c-format +msgid "must be 1 or %d blend modes" +msgstr "Bild muss ein oder %d Bänder haben" + +#: libvips/conversion/composite.cpp:1314 +#, c-format +msgid "blend mode index %d (%d) invalid" +msgstr "" + +#: libvips/conversion/composite.cpp:1413 +#, fuzzy +msgid "images do not have same numbers of bands" +msgstr "Bilder müssen die gleiche Anzahl Bänder haben" + +#: libvips/conversion/composite.cpp:1420 +#, fuzzy +msgid "too many input bands" +msgstr "zu viele Eingabebilder" + +#: libvips/conversion/composite.cpp:1430 +#, fuzzy +msgid "unsupported compositing space" +msgstr "nicht unterstützter Farbraum %d" + +#: libvips/conversion/composite.cpp:1478 +#, fuzzy +msgid "blend images together" +msgstr "falscher Bildtyp" + +#: libvips/conversion/composite.cpp:1484 +msgid "Compositing space" +msgstr "" + +#: libvips/conversion/composite.cpp:1485 +msgid "Composite images in this colour space" +msgstr "" + +#: libvips/conversion/composite.cpp:1491 libvips/conversion/smartcrop.c:474 +#: libvips/resample/affine.c:706 libvips/resample/mapim.c:581 +msgid "Premultiplied" +msgstr "" + +#: libvips/conversion/composite.cpp:1492 libvips/resample/affine.c:707 +#: libvips/resample/mapim.c:582 +msgid "Images have premultiplied alpha" +msgstr "" + +#: libvips/conversion/composite.cpp:1540 +#, c-format +msgid "must be %d x coordinates" +msgstr "" + +#: libvips/conversion/composite.cpp:1548 +#, c-format +msgid "must be %d y coordinates" +msgstr "" + +#: libvips/conversion/composite.cpp:1574 +msgid "blend an array of images with an array of blend modes" +msgstr "" + +#: libvips/conversion/composite.cpp:1580 +#, fuzzy +msgid "Inputs" +msgstr "Eingabe" + +#: libvips/conversion/composite.cpp:1587 +#, fuzzy +msgid "Blend modes" +msgstr "Öffnen-Modus" + +#: libvips/conversion/composite.cpp:1588 +msgid "Array of VipsBlendMode to join with" +msgstr "" + +#: libvips/conversion/composite.cpp:1594 +msgid "x coordinates" +msgstr "" + +#: libvips/conversion/composite.cpp:1595 +#, fuzzy +msgid "Array of x coordinates to join at" +msgstr "Feld aus Konstanten" + +#: libvips/conversion/composite.cpp:1601 +msgid "y coordinates" +msgstr "" + +#: libvips/conversion/composite.cpp:1602 +#, fuzzy +msgid "Array of y coordinates to join at" +msgstr "Feld aus Konstanten" + +#: libvips/conversion/composite.cpp:1708 +msgid "blend a pair of images with a blend mode" +msgstr "" + +#: libvips/conversion/composite.cpp:1714 +msgid "Base" +msgstr "" + +#: libvips/conversion/composite.cpp:1715 +#, fuzzy +msgid "Base image" +msgstr "sonst Bild" + +#: libvips/conversion/composite.cpp:1720 +msgid "Overlay" +msgstr "" + +#: libvips/conversion/composite.cpp:1721 +#, fuzzy +msgid "Overlay image" +msgstr "Zeilensprungbild" + +#: libvips/conversion/composite.cpp:1726 +#, fuzzy +msgid "Blend mode" +msgstr "Öffnen-Modus" + +#: libvips/conversion/composite.cpp:1727 +msgid "VipsBlendMode to join with" +msgstr "" + +#: libvips/conversion/composite.cpp:1734 +msgid "x position of overlay" +msgstr "" + +#: libvips/conversion/composite.cpp:1741 +msgid "y position of overlay" +msgstr "" + +#: libvips/conversion/conversion.c:342 +msgid "conversion operations" +msgstr "Umwandlungstransaktionen" + +#: libvips/conversion/copy.c:235 +#, fuzzy +msgid "must not change pel size" +msgstr "Bilder passen in der Bildpunktgröße nicht zusammen" + +#: libvips/conversion/copy.c:260 +msgid "copy an image" +msgstr "ein Bild kopieren" + +#: libvips/conversion/copy.c:277 +msgid "Swap" +msgstr "austauschen" + +#: libvips/conversion/copy.c:278 +msgid "Swap bytes in image between little and big-endian" +msgstr "Byte im Bild zwischen Little- und Big-Endian austauschen" + +#: libvips/conversion/copy.c:285 libvips/conversion/embed.c:575 +#: libvips/create/black.c:141 libvips/create/fractsurf.c:105 +#: libvips/create/gaussnoise.c:168 libvips/create/perlin.c:295 +#: libvips/create/point.c:142 libvips/create/sdf.c:305 +#: libvips/create/worley.c:308 libvips/create/xyz.c:192 +#: libvips/foreign/rawload.c:147 libvips/iofuncs/image.c:1103 +msgid "Image width in pixels" +msgstr "Bildbreite in Bildpunkten" + +#: libvips/conversion/copy.c:292 libvips/conversion/embed.c:582 +#: libvips/create/black.c:148 libvips/create/fractsurf.c:112 +#: libvips/create/gaussnoise.c:175 libvips/create/perlin.c:302 +#: libvips/create/point.c:149 libvips/create/sdf.c:312 +#: libvips/create/worley.c:315 libvips/create/xyz.c:199 +#: libvips/foreign/rawload.c:154 libvips/iofuncs/image.c:1110 +msgid "Image height in pixels" +msgstr "Bildhöhe in Bildpunkten" + +#: libvips/conversion/copy.c:298 libvips/create/black.c:154 +#: libvips/create/identity.c:143 libvips/foreign/rawload.c:160 +#: libvips/iofuncs/image.c:1116 +msgid "Bands" +msgstr "Bänder" + +#: libvips/conversion/copy.c:299 libvips/create/black.c:155 +#: libvips/foreign/rawload.c:161 libvips/iofuncs/image.c:1117 +msgid "Number of bands in image" +msgstr "Anzahl der Bänder in einem Bild" + +#: libvips/conversion/copy.c:306 libvips/foreign/rawload.c:175 +#: libvips/iofuncs/image.c:1124 +msgid "Pixel format in image" +msgstr "Bildpunktformat im Bild" + +#: libvips/conversion/copy.c:312 libvips/iofuncs/image.c:1130 +msgid "Coding" +msgstr "Kodierung" + +#: libvips/conversion/copy.c:313 libvips/iofuncs/image.c:1131 +msgid "Pixel coding" +msgstr "Bildpunktkodierung" + +#: libvips/conversion/copy.c:319 libvips/foreign/rawload.c:181 +#: libvips/iofuncs/image.c:1137 +msgid "Interpretation" +msgstr "Interpretation" + +#: libvips/conversion/copy.c:320 libvips/foreign/rawload.c:182 +#: libvips/iofuncs/image.c:1138 +msgid "Pixel interpretation" +msgstr "Bildpunktinterpretation" + +#: libvips/conversion/copy.c:326 libvips/foreign/tiffsave.c:329 +#: libvips/iofuncs/image.c:1144 +msgid "Xres" +msgstr "Xres" + +#: libvips/conversion/copy.c:327 libvips/foreign/tiffsave.c:330 +#: libvips/iofuncs/image.c:1145 +msgid "Horizontal resolution in pixels/mm" +msgstr "horizontale Auflösung in Bildpunkten/mm" + +#: libvips/conversion/copy.c:333 libvips/foreign/tiffsave.c:336 +#: libvips/iofuncs/image.c:1151 +msgid "Yres" +msgstr "Yres" + +#: libvips/conversion/copy.c:334 libvips/foreign/tiffsave.c:337 +#: libvips/iofuncs/image.c:1152 +msgid "Vertical resolution in pixels/mm" +msgstr "vertikale Auflösung in Bildpunkten/mm" + +#: libvips/conversion/copy.c:340 libvips/iofuncs/image.c:1158 +msgid "Xoffset" +msgstr "Xoffset" + +#: libvips/conversion/copy.c:341 libvips/iofuncs/image.c:1159 +msgid "Horizontal offset of origin" +msgstr "horizontaler Versatz vom Ursprung" + +#: libvips/conversion/copy.c:347 libvips/iofuncs/image.c:1165 +msgid "Yoffset" +msgstr "Yoffset" + +#: libvips/conversion/copy.c:348 libvips/iofuncs/image.c:1166 +msgid "Vertical offset of origin" +msgstr "vertikaler Versatz vom Ursprung" + +#: libvips/conversion/embed.c:479 libvips/foreign/heifload.c:571 +#: libvips/foreign/svgload.c:502 libvips/iofuncs/image.c:3143 +msgid "bad dimensions" +msgstr "falsche Abmessungen" + +#: libvips/conversion/embed.c:561 libvips/conversion/embed.c:652 +msgid "embed an image in a larger image" +msgstr "ein Bild in ein größeres Bild einbetten" + +#: libvips/conversion/embed.c:588 libvips/resample/affine.c:692 +#: libvips/resample/mapim.c:567 +msgid "Extend" +msgstr "vergrößern" + +#: libvips/conversion/embed.c:589 libvips/resample/affine.c:693 +#: libvips/resample/mapim.c:568 +msgid "How to generate the extra pixels" +msgstr "Wie werden die zusätzlichen Bildpunkte erzeugt?" + +#: libvips/conversion/embed.c:657 libvips/conversion/wrap.c:126 +msgid "Left edge of input in output" +msgstr "linker Rand der Eingabe in der Ausgabe" + +#: libvips/conversion/embed.c:664 libvips/conversion/wrap.c:133 +msgid "Top edge of input in output" +msgstr "oberer Rand der Eingabe in der Ausgabe" + +#: libvips/conversion/embed.c:806 +#, fuzzy +msgid "place an image within a larger image with a certain gravity" +msgstr "ein Bild in ein größeres Bild einbetten" + +#: libvips/conversion/embed.c:811 libvips/conversion/flip.c:246 +#: libvips/conversion/join.c:249 libvips/morphology/countlines.c:146 +#: libvips/mosaicing/merge.c:140 libvips/mosaicing/mosaic1.c:516 +#: libvips/mosaicing/mosaic.c:197 +msgid "Direction" +msgstr "Richtung" + +#: libvips/conversion/embed.c:812 +msgid "Direction to place image within width/height" +msgstr "" + +#: libvips/conversion/extract.c:150 libvips/conversion/smartcrop.c:341 +msgid "bad extract area" +msgstr "falscher extrahierter Bereich" + +#: libvips/conversion/extract.c:188 libvips/conversion/smartcrop.c:429 +msgid "extract an area from an image" +msgstr "einen Bereich eines Bildes extrahieren" + +#: libvips/conversion/extract.c:398 +msgid "bad extract band" +msgstr "schlecht extrahiertes Band" + +#: libvips/conversion/extract.c:426 +msgid "extract band from an image" +msgstr "Band aus einem Bild extrahieren" + +#: libvips/conversion/extract.c:439 +msgid "Band to extract" +msgstr "zu extrahierendes Band" + +#: libvips/conversion/extract.c:445 libvips/foreign/heifload.c:1090 +#: libvips/foreign/jxlload.c:1139 libvips/foreign/magick6load.c:148 +#: libvips/foreign/magick7load.c:389 libvips/foreign/nsgifload.c:627 +#: libvips/foreign/pdfiumload.c:702 libvips/foreign/popplerload.c:552 +#: libvips/foreign/tiffload.c:203 libvips/foreign/webpload.c:185 +msgid "n" +msgstr "n" + +#: libvips/conversion/extract.c:446 +msgid "Number of bands to extract" +msgstr "Anzahl zu extrahierender Bänder" + +#: libvips/conversion/falsecolour.c:374 +#, fuzzy +msgid "false-color an image" +msgstr "ein Bild einfügen" + +# http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=0650& +# db=man&fname=/usr/share/catman/p_man/cat3/il_c/ilAbsImg.z +#: libvips/conversion/flatten.c:413 +#, fuzzy +msgid "flatten alpha out of an image" +msgstr "absoluter Wert eines Bildes" + +#: libvips/conversion/flatten.c:426 libvips/foreign/foreign.c:1909 +#: libvips/resample/affine.c:700 libvips/resample/mapim.c:575 +#: libvips/resample/similarity.c:134 +#, fuzzy +msgid "Background value" +msgstr "Hintergrund" + +#: libvips/conversion/flatten.c:432 libvips/conversion/premultiply.c:267 +#: libvips/conversion/unpremultiply.c:329 +msgid "Maximum alpha" +msgstr "" + +#: libvips/conversion/flatten.c:433 libvips/conversion/premultiply.c:268 +#: libvips/conversion/unpremultiply.c:330 +#, fuzzy +msgid "Maximum value of alpha channel" +msgstr "Maximalwert des Bildes" + +#: libvips/conversion/flip.c:236 +msgid "flip an image" +msgstr "ein Bild umdrehen" + +#: libvips/conversion/flip.c:247 +msgid "Direction to flip image" +msgstr "Richtung, nach der das Bild umgedreht werden soll" + +#: libvips/conversion/gamma.c:136 +#, fuzzy +msgid "gamma an image" +msgstr "ein Bild umwandeln" + +#: libvips/conversion/gamma.c:148 libvips/conversion/scale.c:168 +msgid "Exponent" +msgstr "" + +#: libvips/conversion/gamma.c:149 +#, fuzzy +msgid "Gamma factor" +msgstr "Q-Faktor" + +#: libvips/conversion/grid.c:165 +msgid "bad grid geometry" +msgstr "falsche Gittergeometrie" + +#: libvips/conversion/grid.c:195 +#, fuzzy +msgid "grid an image" +msgstr "ein Bild umdrehen" + +#: libvips/conversion/grid.c:206 +msgid "Chop into tiles this high" +msgstr "" + +#: libvips/conversion/grid.c:213 +#, fuzzy +msgid "Number of tiles across" +msgstr "Anzahl der Patches über ein Diagramm" + +#: libvips/conversion/grid.c:220 +#, fuzzy +msgid "Number of tiles down" +msgstr "Anzahl der Patches ein Diagramm hinunter" + +#: libvips/conversion/ifthenelse.c:525 +msgid "ifthenelse an image" +msgstr "fallsdannsonst eines Bildes" + +#: libvips/conversion/ifthenelse.c:529 +msgid "Condition" +msgstr "Bedingung" + +#: libvips/conversion/ifthenelse.c:530 +msgid "Condition input image" +msgstr "Bedingung des Eingabebilds" + +#: libvips/conversion/ifthenelse.c:535 +msgid "Then image" +msgstr "dann Bild" + +#: libvips/conversion/ifthenelse.c:536 +msgid "Source for TRUE pixels" +msgstr "Quelle für TRUE-Bildpunkte" + +#: libvips/conversion/ifthenelse.c:541 +msgid "Else image" +msgstr "sonst Bild" + +#: libvips/conversion/ifthenelse.c:542 +msgid "Source for FALSE pixels" +msgstr "Quelle für FALSE-Bildpunkte" + +#: libvips/conversion/ifthenelse.c:547 +#, fuzzy +msgid "Blend" +msgstr "Mischung" + +#: libvips/conversion/ifthenelse.c:548 +msgid "Blend smoothly between then and else parts" +msgstr "nahtlos zwischen »dann«- und »sonst«-Teilen mischen" + +#: libvips/conversion/insert.c:460 +msgid "insert image @sub into @main at @x, @y" +msgstr "" + +#: libvips/conversion/insert.c:466 +msgid "Main" +msgstr "primär" + +#: libvips/conversion/insert.c:467 +msgid "Main input image" +msgstr "Haupteingabebild" + +#: libvips/conversion/insert.c:472 libvips/draw/draw_image.c:269 +msgid "Sub-image" +msgstr "Teilbild" + +#: libvips/conversion/insert.c:473 libvips/draw/draw_image.c:270 +msgid "Sub-image to insert into main image" +msgstr "Teilbild, das in das Hauptbild eingefügt werden soll" + +#: libvips/conversion/insert.c:478 +msgid "X" +msgstr "X" + +#: libvips/conversion/insert.c:479 +msgid "Left edge of sub in main" +msgstr "linker Rand des Teilbilds im Hauptbild" + +#: libvips/conversion/insert.c:485 +msgid "Y" +msgstr "Y" + +#: libvips/conversion/insert.c:486 +msgid "Top edge of sub in main" +msgstr "oberer Rand des Teilbilds im Hauptbild" + +#: libvips/conversion/insert.c:492 libvips/conversion/join.c:256 +msgid "Expand" +msgstr "expandieren" + +#: libvips/conversion/insert.c:493 libvips/conversion/join.c:257 +msgid "Expand output to hold all of both inputs" +msgstr "Ausgabe so expandieren, dass sie beide Eingaben vollständig enthält" + +#: libvips/conversion/insert.c:500 +#, fuzzy +msgid "Color for new pixels" +msgstr "Farbe für neue Bildpunkte" + +#: libvips/conversion/join.c:231 +msgid "join a pair of images" +msgstr "ein Bilderpaar zusammenführen" + +#: libvips/conversion/join.c:237 +msgid "in1" +msgstr "in1" + +#: libvips/conversion/join.c:238 +msgid "First input image" +msgstr "erstes Eingabebild" + +#: libvips/conversion/join.c:243 libvips/freqfilt/phasecor.c:111 +msgid "in2" +msgstr "in2" + +#: libvips/conversion/join.c:244 libvips/freqfilt/phasecor.c:112 +msgid "Second input image" +msgstr "zweites Eingabebild" + +#: libvips/conversion/join.c:250 +msgid "Join left-right or up-down" +msgstr "von links nach rechts oder von oben nach unten zusammenführen" + +#: libvips/conversion/join.c:277 libvips/create/text.c:581 +msgid "Align" +msgstr "ausrichten" + +#: libvips/conversion/join.c:278 +msgid "Align on the low, centre or high coordinate edge" +msgstr "am Rand der unteren, mittleren oder höchsten Koordinate ausrichten" + +#: libvips/conversion/msb.c:168 +#, fuzzy +msgid "bad band" +msgstr "falsche Bänder" + +#: libvips/conversion/msb.c:241 +msgid "pick most-significant byte from an image" +msgstr "" + +#: libvips/conversion/msb.c:254 +#, fuzzy +msgid "Band to msb" +msgstr "Bänder auf N setzen" + +#: libvips/conversion/premultiply.c:255 +#, fuzzy +msgid "premultiply image alpha" +msgstr "zwei Bilder multiplizieren" + +#: libvips/conversion/recomb.c:183 +msgid "bands in must equal matrix width" +msgstr "»in«-Bänder müssen die gleiche Breite wie die Matrix haben" + +#: libvips/conversion/recomb.c:218 +msgid "linear recombination with matrix" +msgstr "lineare Neukombinierung mit der Matrix" + +#: libvips/conversion/recomb.c:230 +msgid "M" +msgstr "M" + +#: libvips/conversion/recomb.c:231 +#, fuzzy +msgid "Matrix of coefficients" +msgstr "Matrix der Koeffizienten" + +#: libvips/conversion/replicate.c:192 +msgid "replicate an image" +msgstr "ein Bild nachmachen" + +#: libvips/conversion/replicate.c:203 +msgid "Repeat this many times horizontally" +msgstr "horizontal so oft wiederholen" + +#: libvips/conversion/replicate.c:210 +msgid "Repeat this many times vertically" +msgstr "vertikal so oft wiederholen" + +#: libvips/conversion/rot45.c:264 libvips/conversion/rot.c:361 +msgid "rotate an image" +msgstr "ein Bild drehen" + +#: libvips/conversion/rot45.c:275 libvips/conversion/rot.c:372 +msgid "Angle to rotate image" +msgstr "Winkel zum Drehen eines Bildes" + +#: libvips/conversion/scale.c:151 +#, fuzzy +msgid "scale an image to uchar" +msgstr "ein Bild zwischenspeichern" + +#: libvips/conversion/scale.c:161 libvips/iofuncs/system.c:311 +msgid "Log" +msgstr "" + +#: libvips/conversion/scale.c:162 +msgid "Log scale" +msgstr "" + +#: libvips/conversion/scale.c:169 +msgid "Exponent for log scale" +msgstr "" + +#: libvips/conversion/sequential.c:239 +msgid "check sequential access" +msgstr "" + +#: libvips/conversion/sequential.c:256 +msgid "Strategy" +msgstr "Strategie" + +#: libvips/conversion/sequential.c:257 libvips/conversion/tilecache.c:412 +msgid "Expected access pattern" +msgstr "erwartetes Zugriffsmuster" + +#: libvips/conversion/sequential.c:263 +msgid "Trace" +msgstr "" + +#: libvips/conversion/sequential.c:264 +msgid "Trace pixel requests" +msgstr "" + +#: libvips/conversion/smartcrop.c:453 +#, fuzzy +msgid "Interesting" +msgstr "Interpretation" + +#: libvips/conversion/smartcrop.c:454 +msgid "How to measure interestingness" +msgstr "" + +#: libvips/conversion/smartcrop.c:460 +msgid "Attention x" +msgstr "" + +#: libvips/conversion/smartcrop.c:461 +#, fuzzy +msgid "Horizontal position of attention centre" +msgstr "horizontale Position des Minimums" + +#: libvips/conversion/smartcrop.c:467 +msgid "Attention y" +msgstr "" + +#: libvips/conversion/smartcrop.c:468 +#, fuzzy +msgid "Vertical position of attention centre" +msgstr "vertikale Position des Minimums" + +#: libvips/conversion/smartcrop.c:475 +msgid "Input image already has premultiplied alpha" +msgstr "" + +#: libvips/conversion/subsample.c:228 libvips/resample/reduceh.cpp:546 +#: libvips/resample/reducev.cpp:1001 libvips/resample/shrinkh.c:316 +#: libvips/resample/shrinkv.c:364 +msgid "image has shrunk to nothing" +msgstr "Bild ist zu nichts geschrumpft" + +#: libvips/conversion/subsample.c:259 +#, fuzzy +msgid "subsample an image" +msgstr "ein Bild zwischenspeichern" + +#: libvips/conversion/subsample.c:273 libvips/conversion/zoom.c:379 +msgid "Xfac" +msgstr "" + +#: libvips/conversion/subsample.c:274 +#, fuzzy +msgid "Horizontal subsample factor" +msgstr "horizontaler Versatz vom Ursprung" + +#: libvips/conversion/subsample.c:280 libvips/conversion/zoom.c:386 +msgid "Yfac" +msgstr "" + +#: libvips/conversion/subsample.c:281 +#, fuzzy +msgid "Vertical subsample factor" +msgstr "vertikaler Versatz vom Ursprung" + +#: libvips/conversion/subsample.c:287 +msgid "Point" +msgstr "" + +#: libvips/conversion/subsample.c:288 +msgid "Point sample" +msgstr "" + +#: libvips/conversion/switch.c:129 +#, fuzzy +msgid "bad number of tests" +msgstr "falsche Achsenanzahl %d" + +#: libvips/conversion/switch.c:161 +#, fuzzy +msgid "test images not 1-band" +msgstr "Bild muss ein Band haben" + +#: libvips/conversion/switch.c:189 +msgid "find the index of the first non-zero pixel in tests" +msgstr "" + +#: libvips/conversion/switch.c:195 +msgid "Tests" +msgstr "" + +#: libvips/conversion/switch.c:196 +#, fuzzy +msgid "Table of images to test" +msgstr "Bild in TIFF-Datei speichern" + +#: libvips/conversion/tilecache.c:411 libvips/foreign/foreign.c:1235 +msgid "Access" +msgstr "" + +#: libvips/conversion/tilecache.c:418 +msgid "Threaded" +msgstr "" + +#: libvips/conversion/tilecache.c:419 +msgid "Allow threaded access" +msgstr "" + +#: libvips/conversion/tilecache.c:425 +msgid "Persistent" +msgstr "" + +#: libvips/conversion/tilecache.c:426 +msgid "Keep cache between evaluations" +msgstr "" + +#: libvips/conversion/tilecache.c:708 +#, c-format +msgid "error in tile %d x %d" +msgstr "" + +#: libvips/conversion/tilecache.c:796 +#, fuzzy +msgid "cache an image as a set of tiles" +msgstr "ein Bild zwischenspeichern" + +#: libvips/conversion/tilecache.c:983 +#, fuzzy +msgid "cache an image as a set of lines" +msgstr "ein Bild zwischenspeichern" + +#: libvips/conversion/transpose3d.c:135 +msgid "bad page_height" +msgstr "" + +#: libvips/conversion/transpose3d.c:163 +#, fuzzy +msgid "transpose3d an image" +msgstr "ein Bild einfügen" + +#: libvips/conversion/transpose3d.c:173 libvips/foreign/foreign.c:1915 +#, fuzzy +msgid "Page height" +msgstr "Kachelhöhe" + +#: libvips/conversion/transpose3d.c:174 +#, fuzzy +msgid "Height of each input page" +msgstr "Höhe des extrahierten Bereichs" + +#: libvips/conversion/unpremultiply.c:317 +#, fuzzy +msgid "unpremultiply image alpha" +msgstr "zwei Bilder multiplizieren" + +#: libvips/conversion/unpremultiply.c:336 +#, fuzzy +msgid "Alpha band" +msgstr "falsche Bänder" + +#: libvips/conversion/unpremultiply.c:337 +msgid "Unpremultiply with this alpha" +msgstr "" + +#: libvips/conversion/wrap.c:115 +msgid "wrap image origin" +msgstr "" + +#: libvips/conversion/zoom.c:328 +msgid "zoom factors too large" +msgstr "Zoomfaktoren zu groß" + +#: libvips/conversion/zoom.c:367 +#, fuzzy +msgid "zoom an image" +msgstr "ein Bild kopieren" + +#: libvips/conversion/zoom.c:380 +#, fuzzy +msgid "Horizontal zoom factor" +msgstr "horizontaler Versatz vom Ursprung" + +#: libvips/conversion/zoom.c:387 +#, fuzzy +msgid "Vertical zoom factor" +msgstr "vertikaler Versatz vom Ursprung" + +#: libvips/convolution/canny.c:436 +msgid "Canny edge detector" +msgstr "" + +#: libvips/convolution/canny.c:454 libvips/convolution/gaussblur.c:144 +#: libvips/convolution/sharpen.c:334 libvips/create/gaussmat.c:185 +#: libvips/create/gaussnoise.c:188 +msgid "Sigma" +msgstr "" + +#: libvips/convolution/canny.c:455 libvips/convolution/gaussblur.c:145 +#: libvips/convolution/sharpen.c:335 libvips/create/gaussmat.c:186 +msgid "Sigma of Gaussian" +msgstr "" + +#: libvips/convolution/canny.c:461 libvips/convolution/compass.c:184 +#: libvips/convolution/conv.c:134 libvips/convolution/convsep.c:130 +#: libvips/convolution/gaussblur.c:158 libvips/create/gaussmat.c:213 +#: libvips/create/logmat.c:229 +#, fuzzy +msgid "Precision" +msgstr "Komprimierung" + +#: libvips/convolution/canny.c:462 libvips/convolution/compass.c:185 +#: libvips/convolution/conv.c:135 libvips/convolution/convsep.c:131 +#: libvips/convolution/gaussblur.c:159 +msgid "Convolve with this precision" +msgstr "" + +#: libvips/convolution/compass.c:159 +msgid "convolve with rotating mask" +msgstr "" + +#: libvips/convolution/compass.c:163 +msgid "Times" +msgstr "" + +#: libvips/convolution/compass.c:164 +msgid "Rotate and convolve this many times" +msgstr "" + +#: libvips/convolution/compass.c:171 +msgid "Rotate mask by this much between convolutions" +msgstr "" + +#: libvips/convolution/compass.c:178 +msgid "Combine convolution results like this" +msgstr "" + +#: libvips/convolution/compass.c:191 libvips/convolution/conva.c:1323 +#: libvips/convolution/convasep.c:918 libvips/convolution/conv.c:141 +#: libvips/convolution/convsep.c:137 +msgid "Layers" +msgstr "" + +#: libvips/convolution/compass.c:192 libvips/convolution/conva.c:1324 +#: libvips/convolution/convasep.c:919 libvips/convolution/conv.c:142 +#: libvips/convolution/convsep.c:138 +msgid "Use this many layers in approximation" +msgstr "" + +#: libvips/convolution/compass.c:198 libvips/convolution/conva.c:1330 +#: libvips/convolution/conv.c:148 libvips/convolution/convsep.c:144 +msgid "Cluster" +msgstr "" + +#: libvips/convolution/compass.c:199 libvips/convolution/conva.c:1331 +#: libvips/convolution/conv.c:149 libvips/convolution/convsep.c:145 +msgid "Cluster lines closer than this in approximation" +msgstr "" + +#: libvips/convolution/conva.c:236 libvips/convolution/conva.c:242 +#: libvips/convolution/conva.c:760 libvips/convolution/convasep.c:151 +msgid "mask too complex" +msgstr "Maske zu komplex" + +#: libvips/convolution/conva.c:997 libvips/convolution/conva.c:1247 +#: libvips/convolution/convasep.c:840 +msgid "image too small for mask" +msgstr "Bild zu klein für Maske" + +#: libvips/convolution/conva.c:1319 +msgid "approximate integer convolution" +msgstr "" + +#: libvips/convolution/convasep.c:914 +msgid "approximate separable integer convolution" +msgstr "" + +#: libvips/convolution/conv.c:130 +#, fuzzy +msgid "convolution operation" +msgstr "Umwandlungstransaktionen" + +#: libvips/convolution/convf.c:374 +#, fuzzy +msgid "float convolution operation" +msgstr "Umwandlungstransaktionen" + +#: libvips/convolution/convi.c:1245 +#, fuzzy +msgid "int convolution operation" +msgstr "Umwandlungstransaktionen" + +#: libvips/convolution/convolution.c:119 +#, fuzzy +msgid "convolution operations" +msgstr "Umwandlungstransaktionen" + +#: libvips/convolution/convolution.c:140 libvips/convolution/correlation.c:156 +#: libvips/draw/draw_mask.c:332 libvips/freqfilt/freqmult.c:130 +#: libvips/morphology/labelregions.c:124 libvips/morphology/morph.c:965 +msgid "Mask" +msgstr "" + +#: libvips/convolution/convolution.c:141 libvips/morphology/morph.c:966 +#, fuzzy +msgid "Input matrix image" +msgstr "Eingabebild" + +#: libvips/convolution/convsep.c:126 +#, fuzzy +msgid "separable convolution operation" +msgstr "Umwandlungstransaktionen" + +#: libvips/convolution/correlation.c:144 +#, fuzzy +msgid "correlation operation" +msgstr "Umwandlungstransaktionen" + +#: libvips/convolution/correlation.c:157 +#, fuzzy +msgid "Input reference image" +msgstr "Zeilensprungbild" + +#: libvips/convolution/edge.c:213 +#, fuzzy +msgid "Edge detector" +msgstr "falscher Bild-Deskriptor" + +#: libvips/convolution/edge.c:258 +msgid "Sobel edge detector" +msgstr "" + +#: libvips/convolution/edge.c:291 +msgid "Scharr edge detector" +msgstr "" + +#: libvips/convolution/edge.c:324 +msgid "Prewitt edge detector" +msgstr "" + +#: libvips/convolution/fastcor.c:218 +#, fuzzy +msgid "fast correlation" +msgstr "Interpretation" + +#: libvips/convolution/gaussblur.c:126 +msgid "gaussian blur" +msgstr "" + +#: libvips/convolution/gaussblur.c:151 libvips/create/gaussmat.c:192 +msgid "Minimum amplitude" +msgstr "" + +#: libvips/convolution/gaussblur.c:152 libvips/create/gaussmat.c:193 +#: libvips/create/logmat.c:209 +#, fuzzy +msgid "Minimum amplitude of Gaussian" +msgstr "Minimalwert des Bildes" + +#: libvips/convolution/sharpen.c:316 +msgid "unsharp masking for print" +msgstr "" + +#: libvips/convolution/sharpen.c:341 libvips/draw/draw_line.c:284 +#, fuzzy +msgid "x1" +msgstr "x" + +#: libvips/convolution/sharpen.c:342 +msgid "Flat/jaggy threshold" +msgstr "" + +#: libvips/convolution/sharpen.c:348 libvips/draw/draw_line.c:305 +#, fuzzy +msgid "y2" +msgstr "y" + +#: libvips/convolution/sharpen.c:349 +msgid "Maximum brightening" +msgstr "" + +#: libvips/convolution/sharpen.c:355 +#, fuzzy +msgid "y3" +msgstr "y" + +#: libvips/convolution/sharpen.c:356 +msgid "Maximum darkening" +msgstr "" + +#: libvips/convolution/sharpen.c:362 +msgid "m1" +msgstr "" + +#: libvips/convolution/sharpen.c:363 +msgid "Slope for flat areas" +msgstr "" + +#: libvips/convolution/sharpen.c:369 +msgid "m2" +msgstr "" + +#: libvips/convolution/sharpen.c:370 +msgid "Slope for jaggy areas" +msgstr "" + +#: libvips/convolution/sharpen.c:378 libvips/create/logmat.c:201 +#: libvips/create/mask_butterworth_band.c:136 +#: libvips/create/mask_gaussian_band.c:121 libvips/create/mask_ideal_band.c:112 +#: libvips/create/sdf.c:326 libvips/draw/draw_circle.c:248 +msgid "Radius" +msgstr "" + +#: libvips/convolution/sharpen.c:379 libvips/create/logmat.c:202 +msgid "Radius of Gaussian" +msgstr "" + +#: libvips/convolution/spcor.c:317 +msgid "spatial correlation" +msgstr "" + +#: libvips/create/black.c:136 +msgid "make a black image" +msgstr "ein schwarzes Bild erstellen" + +#: libvips/create/buildlut.c:134 +#, fuzzy, c-format +msgid "x value row %d not an int" +msgstr "x-Wert keine Ganzzahl" + +#: libvips/create/buildlut.c:149 +msgid "x range too small" +msgstr "x-Bereich zu klein" + +#: libvips/create/buildlut.c:259 libvips/create/tonelut.c:221 +msgid "build a look-up table" +msgstr "" + +#: libvips/create/buildlut.c:264 libvips/create/invertlut.c:289 +#, fuzzy +msgid "Matrix of XY coordinates" +msgstr "Matrix der Koeffizienten" + +#: libvips/create/create.c:120 +#, fuzzy +msgid "create operations" +msgstr "Transaktionen" + +#: libvips/create/eye.c:103 +msgid "make an image showing the eye's spatial response" +msgstr "" + +#: libvips/create/eye.c:109 +msgid "Maximum spatial frequency" +msgstr "" + +#: libvips/create/fractsurf.c:100 +#, fuzzy +msgid "make a fractal surface" +msgstr "ein schwarzes Bild erstellen" + +#: libvips/create/fractsurf.c:118 libvips/create/fractsurf.c:119 +#: libvips/create/mask_fractal.c:93 libvips/create/mask_fractal.c:94 +#, fuzzy +msgid "Fractal dimension" +msgstr "falsche Abmessungen" + +#: libvips/create/gaussmat.c:129 libvips/create/logmat.c:147 +#, fuzzy +msgid "mask too large" +msgstr "Maske zu komplex" + +#: libvips/create/gaussmat.c:181 +#, fuzzy +msgid "make a gaussian image" +msgstr "ein schwarzes Bild erstellen" + +#: libvips/create/gaussmat.c:199 libvips/create/logmat.c:215 +#, fuzzy +msgid "Separable" +msgstr "Trenner" + +#: libvips/create/gaussmat.c:200 libvips/create/logmat.c:216 +msgid "Generate separable Gaussian" +msgstr "" + +#: libvips/create/gaussmat.c:206 libvips/create/logmat.c:222 +#, fuzzy +msgid "Integer" +msgstr "Zeilensprung" + +#: libvips/create/gaussmat.c:207 libvips/create/logmat.c:223 +#, fuzzy +msgid "Generate integer Gaussian" +msgstr "Rest nach Ganzzahldivision" + +#: libvips/create/gaussmat.c:214 libvips/create/logmat.c:230 +msgid "Generate with this precision" +msgstr "" + +#: libvips/create/gaussnoise.c:159 +#, fuzzy +msgid "make a gaussnoise image" +msgstr "ein schwarzes Bild erstellen" + +#: libvips/create/gaussnoise.c:181 libvips/histogram/stdif.c:329 +msgid "Mean" +msgstr "" + +#: libvips/create/gaussnoise.c:182 +#, fuzzy +msgid "Mean of pixels in generated image" +msgstr "keine Bildpunktdaten in angehängtem Bild" + +#: libvips/create/gaussnoise.c:189 +#, fuzzy +msgid "Standard deviation of pixels in generated image" +msgstr "Standardabweichung des Bildes" + +#: libvips/create/gaussnoise.c:195 libvips/create/perlin.c:322 +#: libvips/create/worley.c:328 +msgid "Seed" +msgstr "" + +#: libvips/create/gaussnoise.c:196 libvips/create/perlin.c:323 +#: libvips/create/worley.c:329 +#, fuzzy +msgid "Random number seed" +msgstr "falsche Achsenanzahl %d" + +#: libvips/create/grey.c:89 +#, fuzzy +msgid "make a grey ramp image" +msgstr "ein schwarzes Bild erstellen" + +#: libvips/create/identity.c:139 +msgid "make a 1D image where pixel values are indexes" +msgstr "" + +#: libvips/create/identity.c:144 +#, fuzzy +msgid "Number of bands in LUT" +msgstr "Anzahl der Bänder in einem Bild" + +#: libvips/create/identity.c:150 +msgid "Ushort" +msgstr "" + +#: libvips/create/identity.c:151 +msgid "Create a 16-bit LUT" +msgstr "" + +#: libvips/create/identity.c:158 +msgid "Size of 16-bit LUT" +msgstr "" + +#: libvips/create/invertlut.c:124 +msgid "bad input matrix" +msgstr "falsche Eingabematrix" + +#: libvips/create/invertlut.c:129 +msgid "bad size" +msgstr "falsche Größe" + +#: libvips/create/invertlut.c:149 +#, fuzzy, c-format +msgid "element (%d, %d) is %g, outside range [0,1]" +msgstr "Element außerhalb des Bereichs [0,1]" + +#: libvips/create/invertlut.c:284 +msgid "build an inverted look-up table" +msgstr "" + +#: libvips/create/invertlut.c:295 +msgid "LUT size to generate" +msgstr "" + +#: libvips/create/logmat.c:197 +#, fuzzy +msgid "make a Laplacian of Gaussian image" +msgstr "ein schwarzes Bild erstellen" + +#: libvips/create/mask_butterworth_band.c:110 +msgid "make a butterworth_band filter" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:115 +#: libvips/create/mask_butterworth.c:91 +msgid "Order" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:116 +#: libvips/create/mask_butterworth.c:92 +msgid "Filter order" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:122 +#: libvips/create/mask_butterworth_band.c:123 +#: libvips/create/mask_gaussian_band.c:107 +#: libvips/create/mask_gaussian_band.c:108 libvips/create/mask_ideal_band.c:98 +#: libvips/create/mask_ideal_band.c:99 +msgid "Frequency cutoff x" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:129 +#: libvips/create/mask_butterworth_band.c:130 +#: libvips/create/mask_gaussian_band.c:114 +#: libvips/create/mask_gaussian_band.c:115 libvips/create/mask_ideal_band.c:105 +#: libvips/create/mask_ideal_band.c:106 +msgid "Frequency cutoff y" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:137 +#: libvips/create/mask_gaussian_band.c:122 libvips/create/mask_ideal_band.c:113 +msgid "Radius of circle" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:143 +#: libvips/create/mask_butterworth_band.c:144 +#: libvips/create/mask_butterworth.c:105 libvips/create/mask_butterworth.c:106 +#: libvips/create/mask_gaussian_band.c:128 +#: libvips/create/mask_gaussian_band.c:129 libvips/create/mask_gaussian.c:93 +#: libvips/create/mask_gaussian.c:94 +msgid "Amplitude cutoff" +msgstr "" + +#: libvips/create/mask_butterworth.c:86 +msgid "make a butterworth filter" +msgstr "" + +#: libvips/create/mask_butterworth.c:98 libvips/create/mask_butterworth.c:99 +#: libvips/create/mask_gaussian.c:86 libvips/create/mask_gaussian.c:87 +#: libvips/create/mask_ideal.c:84 libvips/create/mask_ideal.c:85 +msgid "Frequency cutoff" +msgstr "" + +#: libvips/create/mask_butterworth_ring.c:101 +msgid "make a butterworth ring filter" +msgstr "" + +#: libvips/create/mask_butterworth_ring.c:106 +#: libvips/create/mask_butterworth_ring.c:107 +#: libvips/create/mask_gaussian_ring.c:101 +#: libvips/create/mask_gaussian_ring.c:102 libvips/create/mask_ideal_ring.c:98 +#: libvips/create/mask_ideal_ring.c:99 +#, fuzzy +msgid "Ringwidth" +msgstr "Kachelbreite" + +#: libvips/create/mask.c:114 +msgid "base class for frequency filters" +msgstr "" + +#: libvips/create/mask.c:122 +msgid "Optical" +msgstr "" + +#: libvips/create/mask.c:123 +msgid "Rotate quadrants to optical space" +msgstr "" + +#: libvips/create/mask.c:129 +msgid "Reject" +msgstr "" + +#: libvips/create/mask.c:130 +msgid "Invert the sense of the filter" +msgstr "" + +#: libvips/create/mask.c:136 +msgid "Nodc" +msgstr "" + +#: libvips/create/mask.c:137 +msgid "Remove DC component" +msgstr "" + +#: libvips/create/mask_fractal.c:88 +msgid "make fractal filter" +msgstr "" + +#: libvips/create/mask_gaussian_band.c:102 libvips/create/mask_gaussian.c:81 +msgid "make a gaussian filter" +msgstr "" + +#: libvips/create/mask_gaussian_ring.c:96 +msgid "make a gaussian ring filter" +msgstr "" + +#: libvips/create/mask_ideal_band.c:93 +msgid "make an ideal band filter" +msgstr "" + +#: libvips/create/mask_ideal.c:79 +msgid "make an ideal filter" +msgstr "" + +#: libvips/create/mask_ideal_ring.c:93 +msgid "make an ideal ring filter" +msgstr "" + +#: libvips/create/perlin.c:290 +#, fuzzy +msgid "make a perlin noise image" +msgstr "ein schwarzes Bild erstellen" + +#: libvips/create/perlin.c:308 libvips/create/worley.c:321 +msgid "Cell size" +msgstr "" + +#: libvips/create/perlin.c:309 +msgid "Size of Perlin cells" +msgstr "" + +#: libvips/create/perlin.c:315 libvips/create/point.c:155 +msgid "Uchar" +msgstr "" + +#: libvips/create/perlin.c:316 libvips/create/point.c:156 +#, fuzzy +msgid "Output an unsigned char image" +msgstr "kein »uchar«-Bild mit einem Band" + +#: libvips/create/point.c:132 +#, fuzzy +msgid "make a point image" +msgstr "ein schwarzes Bild erstellen" + +#: libvips/create/sdf.c:178 +msgid "circle needs a, r to be set" +msgstr "" + +#: libvips/create/sdf.c:183 +msgid "rounded-box needs 2 values for a" +msgstr "" + +#: libvips/create/sdf.c:196 +msgid "box needs a, b to be set" +msgstr "" + +#: libvips/create/sdf.c:202 +msgid "box needs 2 values for a, b" +msgstr "" + +#: libvips/create/sdf.c:216 +msgid "rounded-box needs a, b to be set" +msgstr "" + +#: libvips/create/sdf.c:222 +msgid "rounded-box needs 2 values for a, b" +msgstr "" + +#: libvips/create/sdf.c:227 +msgid "rounded-box needs 4 values for corners" +msgstr "" + +#: libvips/create/sdf.c:242 +msgid "line needs sx, sy to be set" +msgstr "" + +#: libvips/create/sdf.c:248 +msgid "line needs 2 values for a, b" +msgstr "" + +#: libvips/create/sdf.c:259 +#, fuzzy, c-format +msgid "unknown SDF %d" +msgstr "unbekannte Kodierung" + +#: libvips/create/sdf.c:300 +#, fuzzy +msgid "create an SDF image" +msgstr "ein Bild drehen" + +#: libvips/create/sdf.c:318 +msgid "Shape" +msgstr "" + +#: libvips/create/sdf.c:319 +msgid "SDF shape to create" +msgstr "" + +#: libvips/create/sdf.c:325 +msgid "r" +msgstr "" + +#: libvips/create/sdf.c:333 +msgid "Point a" +msgstr "" + +#: libvips/create/sdf.c:340 +msgid "Point b" +msgstr "" + +#: libvips/create/sdf.c:346 +msgid "corners" +msgstr "" + +#: libvips/create/sdf.c:347 +msgid "Corner radii" +msgstr "" + +#: libvips/create/sines.c:122 +msgid "make a 2D sine wave" +msgstr "" + +#: libvips/create/sines.c:128 +msgid "hfreq" +msgstr "" + +#: libvips/create/sines.c:129 +#, fuzzy +msgid "Horizontal spatial frequency" +msgstr "horizontaler Versatz vom Ursprung" + +#: libvips/create/sines.c:135 +msgid "vfreq" +msgstr "" + +#: libvips/create/sines.c:136 +msgid "Vertical spatial frequency" +msgstr "" + +#: libvips/create/text.c:406 +msgid "invalid markup in text" +msgstr "ungültige Auszeichnung im Text" + +#: libvips/create/text.c:428 +#, fuzzy, c-format +msgid "unable to load fontfile \"%s\"" +msgstr "Profil »%s« kann nicht geöffnet werden" + +#: libvips/create/text.c:467 +msgid "no text to render" +msgstr "kein Text zu rendern" + +#: libvips/create/text.c:549 +#, fuzzy +msgid "make a text image" +msgstr "ein schwarzes Bild erstellen" + +#: libvips/create/text.c:553 +msgid "Text" +msgstr "" + +#: libvips/create/text.c:554 +#, fuzzy +msgid "Text to render" +msgstr "kein Text zu rendern" + +#: libvips/create/text.c:560 +msgid "Font" +msgstr "" + +#: libvips/create/text.c:561 +#, fuzzy +msgid "Font to render with" +msgstr "kein Text zu rendern" + +#: libvips/create/text.c:568 +#, fuzzy +msgid "Maximum image width in pixels" +msgstr "Bildbreite in Bildpunkten" + +#: libvips/create/text.c:575 +#, fuzzy +msgid "Maximum image height in pixels" +msgstr "Bildhöhe in Bildpunkten" + +#: libvips/create/text.c:582 +#, fuzzy +msgid "Align on the low, centre or high edge" +msgstr "am Rand der unteren, mittleren oder höchsten Koordinate ausrichten" + +#: libvips/create/text.c:588 +msgid "Justify" +msgstr "" + +#: libvips/create/text.c:589 +#, fuzzy +msgid "Justify lines" +msgstr "leere Zeile" + +#: libvips/create/text.c:595 libvips/foreign/pdfiumload.c:709 +#: libvips/foreign/popplerload.c:559 libvips/foreign/svgload.c:717 +msgid "DPI" +msgstr "" + +#: libvips/create/text.c:596 libvips/foreign/pdfiumload.c:710 +#: libvips/foreign/popplerload.c:560 +#, fuzzy +msgid "DPI to render at" +msgstr "kein Text zu rendern" + +#: libvips/create/text.c:602 +msgid "Autofit DPI" +msgstr "" + +#: libvips/create/text.c:603 +msgid "DPI selected by autofit" +msgstr "" + +#: libvips/create/text.c:609 +msgid "Spacing" +msgstr "" + +#: libvips/create/text.c:610 +msgid "Line spacing" +msgstr "" + +#: libvips/create/text.c:616 +#, fuzzy +msgid "Font file" +msgstr "Profil" + +#: libvips/create/text.c:617 +#, fuzzy +msgid "Load this font file" +msgstr "diese Seite aus der Datei laden" + +#: libvips/create/text.c:623 +msgid "RGBA" +msgstr "" + +#: libvips/create/text.c:624 +msgid "Enable RGBA output" +msgstr "" + +#: libvips/create/text.c:630 +msgid "Wrap" +msgstr "" + +#: libvips/create/text.c:631 +msgid "Wrap lines on word or character boundaries" +msgstr "" + +#: libvips/create/tonelut.c:225 +msgid "In-max" +msgstr "" + +#: libvips/create/tonelut.c:226 +msgid "Size of LUT to build" +msgstr "" + +#: libvips/create/tonelut.c:232 +msgid "Out-max" +msgstr "" + +#: libvips/create/tonelut.c:233 +#, fuzzy +msgid "Maximum value in output LUT" +msgstr "Maximalwert des Bildes" + +#: libvips/create/tonelut.c:239 +msgid "Black point" +msgstr "" + +#: libvips/create/tonelut.c:240 +#, fuzzy +msgid "Lowest value in output" +msgstr "linker Rand der Eingabe in der Ausgabe" + +#: libvips/create/tonelut.c:246 +msgid "White point" +msgstr "" + +#: libvips/create/tonelut.c:247 +msgid "Highest value in output" +msgstr "" + +#: libvips/create/tonelut.c:253 +msgid "Shadow point" +msgstr "" + +#: libvips/create/tonelut.c:254 +msgid "Position of shadow" +msgstr "" + +#: libvips/create/tonelut.c:260 +msgid "Mid-tone point" +msgstr "" + +#: libvips/create/tonelut.c:261 +msgid "Position of mid-tones" +msgstr "" + +#: libvips/create/tonelut.c:267 +msgid "Highlight point" +msgstr "" + +#: libvips/create/tonelut.c:268 +msgid "Position of highlights" +msgstr "" + +#: libvips/create/tonelut.c:274 +msgid "Shadow adjust" +msgstr "" + +#: libvips/create/tonelut.c:275 +msgid "Adjust shadows by this much" +msgstr "" + +#: libvips/create/tonelut.c:281 +msgid "Mid-tone adjust" +msgstr "" + +#: libvips/create/tonelut.c:282 +msgid "Adjust mid-tones by this much" +msgstr "" + +#: libvips/create/tonelut.c:288 +msgid "Highlight adjust" +msgstr "" + +#: libvips/create/tonelut.c:289 +msgid "Adjust highlights by this much" +msgstr "" + +#: libvips/create/worley.c:303 +#, fuzzy +msgid "make a worley noise image" +msgstr "ein schwarzes Bild erstellen" + +#: libvips/create/worley.c:322 +msgid "Size of Worley cells" +msgstr "" + +#: libvips/create/xyz.c:139 +#, fuzzy +msgid "lower dimensions not set" +msgstr "Abfragen der Abmessungen: %s" + +#: libvips/create/xyz.c:156 libvips/foreign/heifsave.c:682 +#: libvips/foreign/webpsave.c:734 +#, fuzzy +msgid "image too large" +msgstr "Bild zu schmal" + +#: libvips/create/xyz.c:187 +msgid "make an image where pixel values are coordinates" +msgstr "" + +#: libvips/create/xyz.c:205 +#, fuzzy +msgid "csize" +msgstr "falsche Größe" + +#: libvips/create/xyz.c:206 +msgid "Size of third dimension" +msgstr "" + +#: libvips/create/xyz.c:212 +#, fuzzy +msgid "dsize" +msgstr "falsche Größe" + +#: libvips/create/xyz.c:213 +msgid "Size of fourth dimension" +msgstr "" + +#: libvips/create/xyz.c:219 +#, fuzzy +msgid "esize" +msgstr "falsche Größe" + +#: libvips/create/xyz.c:220 +msgid "Size of fifth dimension" +msgstr "" + +#: libvips/create/zone.c:90 +msgid "make a zone plate" +msgstr "" + +#: libvips/draw/draw.c:131 +#, fuzzy +msgid "draw operations" +msgstr "Transaktionen" + +#: libvips/draw/draw.c:138 +#, fuzzy +msgid "Image" +msgstr "Eingabebild" + +#: libvips/draw/draw.c:139 +#, fuzzy +msgid "Image to draw on" +msgstr "zu speicherndes Bild" + +#: libvips/draw/draw_circle.c:230 +#, fuzzy +msgid "draw a circle on an image" +msgstr "einen Bereich eines Bildes extrahieren" + +#: libvips/draw/draw_circle.c:234 +#, fuzzy +msgid "cx" +msgstr "x" + +#: libvips/draw/draw_circle.c:235 libvips/draw/draw_circle.c:242 +msgid "Centre of draw_circle" +msgstr "" + +#: libvips/draw/draw_circle.c:241 +#, fuzzy +msgid "cy" +msgstr "y" + +#: libvips/draw/draw_circle.c:249 +#, fuzzy +msgid "Radius in pixels" +msgstr "Bildbreite in Bildpunkten" + +#: libvips/draw/draw_circle.c:255 libvips/draw/draw_rect.c:201 +msgid "Fill" +msgstr "" + +#: libvips/draw/draw_circle.c:256 libvips/draw/draw_rect.c:202 +msgid "Draw a solid object" +msgstr "" + +#: libvips/draw/draw_flood.c:562 +msgid "flood-fill an area" +msgstr "" + +#: libvips/draw/draw_flood.c:567 libvips/draw/draw_flood.c:574 +msgid "DrawFlood start point" +msgstr "" + +#: libvips/draw/draw_flood.c:580 +msgid "Test" +msgstr "" + +#: libvips/draw/draw_flood.c:581 +#, fuzzy +msgid "Test pixels in this image" +msgstr "keine Bildpunktdaten in angehängtem Bild" + +#: libvips/draw/draw_flood.c:586 +msgid "Equal" +msgstr "" + +#: libvips/draw/draw_flood.c:587 +msgid "DrawFlood while equal to edge" +msgstr "" + +#: libvips/draw/draw_flood.c:594 +#, fuzzy +msgid "Left edge of modified area" +msgstr "linke Kante eines extrahierten Bereichs" + +#: libvips/draw/draw_flood.c:601 +#, fuzzy +msgid "Top edge of modified area" +msgstr "obere Kante eines extrahierten Bereichs" + +#: libvips/draw/draw_flood.c:608 +#, fuzzy +msgid "Width of modified area" +msgstr "Breite des extrahierten Bereichs" + +#: libvips/draw/draw_flood.c:615 +#, fuzzy +msgid "Height of modified area" +msgstr "Höhe des extrahierten Bereichs" + +#: libvips/draw/draw_image.c:265 +#, fuzzy +msgid "paint an image into another image" +msgstr "ein Bild in ein größeres Bild einbetten" + +#: libvips/draw/draw_image.c:276 libvips/draw/draw_image.c:283 +#, fuzzy +msgid "Draw image here" +msgstr "- Bild-Kopfzeilen ausgeben" + +#: libvips/draw/draw_image.c:289 libvips/iofuncs/image.c:1179 +msgid "Mode" +msgstr "Modus" + +#: libvips/draw/draw_image.c:290 +msgid "Combining mode" +msgstr "" + +#: libvips/draw/drawink.c:86 +#, fuzzy +msgid "draw with ink operations" +msgstr "arithmetische Transaktionen" + +#: libvips/draw/drawink.c:90 +msgid "Ink" +msgstr "" + +#: libvips/draw/drawink.c:91 +#, fuzzy +msgid "Color for pixels" +msgstr "Farbe für neue Bildpunkte" + +#: libvips/draw/draw_line.c:280 +#, fuzzy +msgid "draw a line on an image" +msgstr "eine mathematische Funktion für ein Bild ausführen" + +#: libvips/draw/draw_line.c:285 libvips/draw/draw_line.c:292 +msgid "Start of draw_line" +msgstr "" + +#: libvips/draw/draw_line.c:291 +#, fuzzy +msgid "y1" +msgstr "y" + +#: libvips/draw/draw_line.c:298 +#, fuzzy +msgid "x2" +msgstr "x" + +#: libvips/draw/draw_line.c:299 libvips/draw/draw_line.c:306 +msgid "End of draw_line" +msgstr "" + +#: libvips/draw/draw_mask.c:328 +#, fuzzy +msgid "draw a mask on an image" +msgstr "einen Bereich eines Bildes extrahieren" + +#: libvips/draw/draw_mask.c:333 +msgid "Mask of pixels to draw" +msgstr "" + +#: libvips/draw/draw_mask.c:339 libvips/draw/draw_mask.c:346 +msgid "Draw mask here" +msgstr "" + +#: libvips/draw/draw_rect.c:169 +#, fuzzy +msgid "paint a rectangle on an image" +msgstr "einen Bereich eines Bildes extrahieren" + +#: libvips/draw/draw_rect.c:174 libvips/draw/draw_rect.c:181 +#: libvips/draw/draw_rect.c:188 libvips/draw/draw_rect.c:195 +#: libvips/draw/draw_smudge.c:216 libvips/draw/draw_smudge.c:223 +#: libvips/draw/draw_smudge.c:230 libvips/draw/draw_smudge.c:237 +#, fuzzy +msgid "Rect to fill" +msgstr "Ziel zu klein" + +# http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=0650& +# db=man&fname=/usr/share/catman/p_man/cat3/il_c/ilAbsImg.z +#: libvips/draw/draw_smudge.c:211 +#, fuzzy +msgid "blur a rectangle on an image" +msgstr "absoluter Wert eines Bildes" + +#: libvips/foreign/analyze2vips.c:308 +msgid "header file size incorrect" +msgstr "Kopfdatendateigröße nicht korrekt" + +#: libvips/foreign/analyze2vips.c:352 +msgid "header size incorrect" +msgstr "Kopfdatengröße nicht korrekt" + +#: libvips/foreign/analyze2vips.c:370 libvips/foreign/niftiload.c:399 +#, c-format +msgid "%d-dimensional images not supported" +msgstr "%d-dimensionale Bilder nicht unterstützt" + +#: libvips/foreign/analyze2vips.c:423 libvips/foreign/niftiload.c:442 +#, c-format +msgid "datatype %d not supported" +msgstr "Datentyp %d nicht unterstützt" + +#: libvips/foreign/analyzeload.c:120 +msgid "load an Analyze6 image" +msgstr "ein Analyze6-Bild laden" + +#: libvips/foreign/analyzeload.c:141 libvips/foreign/cgifsave.c:1058 +#: libvips/foreign/csvload.c:590 libvips/foreign/csvsave.c:274 +#: libvips/foreign/dzsave.c:2597 libvips/foreign/fitsload.c:259 +#: libvips/foreign/fitssave.c:143 libvips/foreign/heifload.c:1271 +#: libvips/foreign/heifsave.c:897 libvips/foreign/jp2kload.c:1309 +#: libvips/foreign/jp2ksave.c:1063 libvips/foreign/jpegload.c:354 +#: libvips/foreign/jpegsave.c:361 libvips/foreign/jxlload.c:1218 +#: libvips/foreign/jxlsave.c:897 libvips/foreign/magick6load.c:238 +#: libvips/foreign/magick7load.c:851 libvips/foreign/matload.c:138 +#: libvips/foreign/matrixload.c:374 libvips/foreign/matrixsave.c:228 +#: libvips/foreign/niftiload.c:713 libvips/foreign/niftisave.c:441 +#: libvips/foreign/nsgifload.c:765 libvips/foreign/openexrload.c:149 +#: libvips/foreign/openslideload.c:1152 libvips/foreign/pdfiumload.c:812 +#: libvips/foreign/pngload.c:318 libvips/foreign/pngsave.c:378 +#: libvips/foreign/popplerload.c:689 libvips/foreign/ppmload.c:829 +#: libvips/foreign/ppmsave.c:592 libvips/foreign/radload.c:281 +#: libvips/foreign/radsave.c:154 libvips/foreign/rawload.c:139 +#: libvips/foreign/rawsave.c:196 libvips/foreign/spngload.c:835 +#: libvips/foreign/spngsave.c:858 libvips/foreign/svgload.c:929 +#: libvips/foreign/tiffload.c:382 libvips/foreign/tiffsave.c:527 +#: libvips/foreign/vips2magick.c:578 libvips/foreign/vipsload.c:236 +#: libvips/foreign/vipssave.c:197 libvips/foreign/webpload.c:346 +#: libvips/foreign/webpsave.c:1038 libvips/iofuncs/connection.c:133 +#: libvips/iofuncs/image.c:1172 libvips/resample/thumbnail.c:1198 +msgid "Filename" +msgstr "Dateiname" + +#: libvips/foreign/analyzeload.c:142 libvips/foreign/csvload.c:591 +#: libvips/foreign/fitsload.c:260 libvips/foreign/heifload.c:1272 +#: libvips/foreign/jp2kload.c:1310 libvips/foreign/jpegload.c:355 +#: libvips/foreign/jxlload.c:1219 libvips/foreign/magick6load.c:239 +#: libvips/foreign/magick7load.c:852 libvips/foreign/matload.c:139 +#: libvips/foreign/matrixload.c:375 libvips/foreign/niftiload.c:714 +#: libvips/foreign/nsgifload.c:766 libvips/foreign/openexrload.c:150 +#: libvips/foreign/openslideload.c:1153 libvips/foreign/pdfiumload.c:813 +#: libvips/foreign/pngload.c:319 libvips/foreign/popplerload.c:690 +#: libvips/foreign/ppmload.c:830 libvips/foreign/radload.c:282 +#: libvips/foreign/rawload.c:140 libvips/foreign/spngload.c:836 +#: libvips/foreign/svgload.c:930 libvips/foreign/tiffload.c:383 +#: libvips/foreign/vipsload.c:237 libvips/foreign/webpload.c:347 +msgid "Filename to load from" +msgstr "Name der Datei, aus der geladen werden soll" + +#: libvips/foreign/archive.c:138 +#, fuzzy +msgid "unable to create archive" +msgstr "es können keine Profile erstellt werden" + +#: libvips/foreign/archive.c:146 +#, fuzzy +msgid "unable to set zip format" +msgstr "Dateistatus kann nicht abgefragt werden" + +#: libvips/foreign/archive.c:163 +#, fuzzy +msgid "unable to set compression" +msgstr "»%s« kann nicht gesetzt werden" + +#: libvips/foreign/archive.c:175 +#, fuzzy +msgid "unable to set padding" +msgstr "»%s« kann nicht gesetzt werden" + +#: libvips/foreign/archive.c:184 libvips/iofuncs/target.c:129 +#, fuzzy +msgid "unable to open for write" +msgstr "»%s« kann nicht zur Eingabe geöffnet werden" + +#: libvips/foreign/archive.c:205 libvips/iofuncs/util.c:1097 +#, fuzzy, c-format +msgid "unable to create directory \"%s\", %s" +msgstr "Daten für »%s« können nicht gelesen werden, %s" + +#: libvips/foreign/archive.c:240 +#, fuzzy +msgid "unable to create entry" +msgstr "Thread kann nicht erstellt werden" + +#: libvips/foreign/archive.c:256 +#, fuzzy +msgid "unable to write header" +msgstr "Thread kann nicht erstellt werden" + +#: libvips/foreign/archive.c:265 +#, fuzzy +msgid "unable to write data" +msgstr "Daten können nicht gelesen werden" + +#: libvips/foreign/cgifsave.c:407 libvips/foreign/cgifsave.c:833 +#: libvips/foreign/quantise.c:403 libvips/foreign/quantise.c:423 +msgid "quantisation failed" +msgstr "" + +#: libvips/foreign/cgifsave.c:587 +#, fuzzy +msgid "dither failed" +msgstr "Schreiben fehlgeschlagen" + +#: libvips/foreign/cgifsave.c:772 +#, fuzzy +msgid "frame too large" +msgstr "Zoomfaktoren zu groß" + +#: libvips/foreign/cgifsave.c:811 +#, fuzzy +msgid "gif-palette too large" +msgstr "Zoomfaktoren zu groß" + +#: libvips/foreign/cgifsave.c:884 +#, fuzzy +msgid "save as gif" +msgstr "Bild als ASCII speichern" + +#: libvips/foreign/cgifsave.c:893 libvips/foreign/pngsave.c:247 +#: libvips/foreign/spngsave.c:725 +msgid "Dithering" +msgstr "" + +#: libvips/foreign/cgifsave.c:894 libvips/foreign/pngsave.c:248 +#: libvips/foreign/spngsave.c:726 +msgid "Amount of dithering" +msgstr "" + +#: libvips/foreign/cgifsave.c:900 libvips/foreign/heifsave.c:803 +#: libvips/foreign/jxlsave.c:824 libvips/foreign/pngsave.c:261 +#: libvips/foreign/spngsave.c:739 libvips/foreign/webpsave.c:890 +msgid "Effort" +msgstr "" + +#: libvips/foreign/cgifsave.c:901 +msgid "Quantisation effort" +msgstr "" + +#: libvips/foreign/cgifsave.c:907 libvips/foreign/heifsave.c:781 +#: libvips/foreign/pngsave.c:254 libvips/foreign/ppmsave.c:521 +#: libvips/foreign/spngsave.c:732 libvips/foreign/tiffsave.c:315 +#: libvips/foreign/vips2magick.c:510 +msgid "Bit depth" +msgstr "" + +#: libvips/foreign/cgifsave.c:908 libvips/foreign/heifsave.c:782 +#: libvips/foreign/vips2magick.c:511 +#, fuzzy +msgid "Number of bits per pixel" +msgstr "Anzahl der Bänder in einem Bild" + +#: libvips/foreign/cgifsave.c:914 +#, fuzzy +msgid "Maximum inter-frame error" +msgstr "interner Fehler" + +#: libvips/foreign/cgifsave.c:915 +msgid "Maximum inter-frame error for transparency" +msgstr "" + +#: libvips/foreign/cgifsave.c:921 +msgid "Reuse palette" +msgstr "" + +#: libvips/foreign/cgifsave.c:922 +msgid "Reuse palette from input" +msgstr "" + +#: libvips/foreign/cgifsave.c:928 +#, fuzzy +msgid "Maximum inter-palette error" +msgstr "interner Fehler" + +#: libvips/foreign/cgifsave.c:929 +msgid "Maximum inter-palette error for palette reusage" +msgstr "" + +#: libvips/foreign/cgifsave.c:935 +#, fuzzy +msgid "Interlaced" +msgstr "Zeilensprung" + +#: libvips/foreign/cgifsave.c:936 +msgid "Generate an interlaced (progressive) GIF" +msgstr "" + +#: libvips/foreign/cgifsave.c:945 +msgid "Reoptimise palettes" +msgstr "" + +#: libvips/foreign/cgifsave.c:946 +msgid "Reoptimise colour palettes" +msgstr "" + +#: libvips/foreign/cgifsave.c:952 +#, fuzzy +msgid "Keep duplicate frames" +msgstr "ein Bild nachmachen" + +#: libvips/foreign/cgifsave.c:953 +msgid "Keep duplicate frames in the output instead of combining them" +msgstr "" + +#: libvips/foreign/cgifsave.c:1010 libvips/foreign/csvsave.c:325 +#: libvips/foreign/dzsave.c:2537 libvips/foreign/heifsave.c:1020 +#: libvips/foreign/jp2ksave.c:1182 libvips/foreign/jpegsave.c:292 +#: libvips/foreign/jxlsave.c:1016 libvips/foreign/matrixsave.c:281 +#: libvips/foreign/pngsave.c:326 libvips/foreign/ppmsave.c:648 +#: libvips/foreign/radsave.c:207 libvips/foreign/rawsave.c:252 +#: libvips/foreign/spngsave.c:805 libvips/foreign/tiffsave.c:474 +#: libvips/foreign/vipssave.c:253 libvips/foreign/webpsave.c:987 +#: libvips/iofuncs/target.c:283 +msgid "Target" +msgstr "" + +#: libvips/foreign/cgifsave.c:1011 libvips/foreign/csvsave.c:326 +#: libvips/foreign/dzsave.c:2538 libvips/foreign/heifsave.c:1021 +#: libvips/foreign/jp2ksave.c:1183 libvips/foreign/jpegsave.c:293 +#: libvips/foreign/jxlsave.c:1017 libvips/foreign/matrixsave.c:282 +#: libvips/foreign/pngsave.c:327 libvips/foreign/ppmsave.c:649 +#: libvips/foreign/radsave.c:208 libvips/foreign/rawsave.c:253 +#: libvips/foreign/spngsave.c:806 libvips/foreign/tiffsave.c:475 +#: libvips/foreign/vipssave.c:254 libvips/foreign/webpsave.c:988 +#, fuzzy +msgid "Target to save to" +msgstr "zu speicherndes Bild" + +#: libvips/foreign/cgifsave.c:1059 libvips/foreign/csvsave.c:275 +#: libvips/foreign/dzsave.c:2598 libvips/foreign/fitssave.c:144 +#: libvips/foreign/heifsave.c:898 libvips/foreign/jp2ksave.c:1064 +#: libvips/foreign/jpegsave.c:362 libvips/foreign/jxlsave.c:898 +#: libvips/foreign/matrixsave.c:229 libvips/foreign/niftisave.c:442 +#: libvips/foreign/pngsave.c:379 libvips/foreign/ppmsave.c:593 +#: libvips/foreign/radsave.c:155 libvips/foreign/rawsave.c:197 +#: libvips/foreign/spngsave.c:859 libvips/foreign/tiffsave.c:528 +#: libvips/foreign/vips2magick.c:579 libvips/foreign/vipssave.c:198 +#: libvips/foreign/webpsave.c:1039 +msgid "Filename to save to" +msgstr "Name der Datei in die gespeichert werden soll" + +#: libvips/foreign/cgifsave.c:1117 libvips/foreign/dzsave.c:2656 +#: libvips/foreign/heifload.c:1340 libvips/foreign/heifsave.c:962 +#: libvips/foreign/jp2kload.c:1385 libvips/foreign/jp2ksave.c:1126 +#: libvips/foreign/jpegload.c:430 libvips/foreign/jpegsave.c:439 +#: libvips/foreign/jxlload.c:1293 libvips/foreign/jxlsave.c:960 +#: libvips/foreign/magick6load.c:313 libvips/foreign/magick7load.c:932 +#: libvips/foreign/nsgifload.c:843 libvips/foreign/pdfiumload.c:872 +#: libvips/foreign/pngload.c:394 libvips/foreign/pngsave.c:437 +#: libvips/foreign/popplerload.c:749 libvips/foreign/radload.c:356 +#: libvips/foreign/radsave.c:273 libvips/foreign/rawsave.c:314 +#: libvips/foreign/spngload.c:911 libvips/foreign/spngsave.c:918 +#: libvips/foreign/svgload.c:997 libvips/foreign/tiffload.c:460 +#: libvips/foreign/tiffsave.c:588 libvips/foreign/vips2magick.c:650 +#: libvips/foreign/webpload.c:424 libvips/foreign/webpsave.c:1096 +#: libvips/resample/thumbnail.c:1445 +msgid "Buffer" +msgstr "Puffer" + +#: libvips/foreign/cgifsave.c:1118 libvips/foreign/dzsave.c:2657 +#: libvips/foreign/heifsave.c:963 libvips/foreign/jp2ksave.c:1127 +#: libvips/foreign/jpegsave.c:440 libvips/foreign/jxlsave.c:961 +#: libvips/foreign/pngsave.c:438 libvips/foreign/radsave.c:274 +#: libvips/foreign/rawsave.c:315 libvips/foreign/spngsave.c:919 +#: libvips/foreign/tiffsave.c:589 libvips/foreign/vips2magick.c:651 +#: libvips/foreign/webpsave.c:1097 +msgid "Buffer to save to" +msgstr "Puffer, in den gespeichert werden soll" + +#: libvips/foreign/csvload.c:301 +#, fuzzy, c-format +msgid "bad number, line %d, column %d" +msgstr "Fehler beim Auswerten von Nummer, Zeile %d, Spalte %d" + +#: libvips/foreign/csvload.c:341 libvips/foreign/csvload.c:402 +#: libvips/foreign/csvload.c:434 +#, fuzzy +msgid "unexpected end of file" +msgstr "Unerwartetes Ende der Zeichenkette" + +#: libvips/foreign/csvload.c:440 +#, c-format +msgid "line %d has only %d columns" +msgstr "" + +#: libvips/foreign/csvload.c:479 +#, fuzzy +msgid "load csv" +msgstr "CSV aus Datei laden" + +#: libvips/foreign/csvload.c:492 +msgid "Skip" +msgstr "überspringen" + +#: libvips/foreign/csvload.c:493 +msgid "Skip this many lines at the start of the file" +msgstr "so viele Zeilen ab dem Dateianfang überspringen" + +#: libvips/foreign/csvload.c:499 +msgid "Lines" +msgstr "Zeilen" + +#: libvips/foreign/csvload.c:500 +msgid "Read this many lines from the file" +msgstr "so viele Zeilen aus der Datei lesen" + +#: libvips/foreign/csvload.c:506 +msgid "Whitespace" +msgstr "Leerraum" + +#: libvips/foreign/csvload.c:507 +msgid "Set of whitespace characters" +msgstr "Satz von Leerraumzeichen" + +#: libvips/foreign/csvload.c:513 libvips/foreign/csvsave.c:223 +msgid "Separator" +msgstr "Trenner" + +#: libvips/foreign/csvload.c:514 +msgid "Set of separator characters" +msgstr "Satz von Trennzeichen" + +#: libvips/foreign/csvload.c:661 libvips/foreign/fitsload.c:338 +#: libvips/foreign/heifload.c:1414 libvips/foreign/jp2kload.c:1448 +#: libvips/foreign/jpegload.c:278 libvips/foreign/jxlload.c:1357 +#: libvips/foreign/matrixload.c:462 libvips/foreign/niftiload.c:792 +#: libvips/foreign/nsgifload.c:909 libvips/foreign/openslideload.c:1230 +#: libvips/foreign/pdfiumload.c:932 libvips/foreign/pngload.c:242 +#: libvips/foreign/popplerload.c:809 libvips/foreign/ppmload.c:890 +#: libvips/foreign/radload.c:205 libvips/foreign/spngload.c:757 +#: libvips/foreign/svgload.c:836 libvips/foreign/tiffload.c:302 +#: libvips/foreign/vipsload.c:312 libvips/foreign/webpload.c:266 +#: libvips/resample/thumbnail.c:1658 +msgid "Source" +msgstr "" + +#: libvips/foreign/csvload.c:662 libvips/foreign/fitsload.c:339 +#: libvips/foreign/heifload.c:1415 libvips/foreign/jp2kload.c:1449 +#: libvips/foreign/jpegload.c:279 libvips/foreign/jxlload.c:1358 +#: libvips/foreign/matrixload.c:463 libvips/foreign/niftiload.c:793 +#: libvips/foreign/nsgifload.c:910 libvips/foreign/openslideload.c:1231 +#: libvips/foreign/pdfiumload.c:933 libvips/foreign/pngload.c:243 +#: libvips/foreign/popplerload.c:810 libvips/foreign/ppmload.c:891 +#: libvips/foreign/radload.c:206 libvips/foreign/spngload.c:758 +#: libvips/foreign/svgload.c:837 libvips/foreign/tiffload.c:303 +#: libvips/foreign/vipsload.c:313 libvips/foreign/webpload.c:267 +#: libvips/iofuncs/sbuf.c:89 libvips/resample/thumbnail.c:1659 +#, fuzzy +msgid "Source to load from" +msgstr "Puffer, aus dem geladen werden soll" + +#: libvips/foreign/csvsave.c:215 +#, fuzzy +msgid "save image to csv" +msgstr "Bild in CSV-Datei speichern" + +#: libvips/foreign/csvsave.c:224 +msgid "Separator characters" +msgstr "Trennzeichen" + +#: libvips/foreign/dzsave.c:2008 +#, fuzzy +msgid "overlap too large" +msgstr "Überlappen zu schmal" + +# http://de.wikipedia.org/wiki/Portable_Pixmap +#: libvips/foreign/dzsave.c:2319 +#, fuzzy +msgid "save image to deep zoom format" +msgstr "Bild in PPM-Datei speichern" + +#: libvips/foreign/dzsave.c:2329 libvips/foreign/dzsave.c:2330 +#, fuzzy +msgid "Image name" +msgstr "Bilddateiname" + +#: libvips/foreign/dzsave.c:2336 +msgid "Layout" +msgstr "" + +#: libvips/foreign/dzsave.c:2337 +msgid "Directory layout" +msgstr "" + +#: libvips/foreign/dzsave.c:2343 +msgid "Suffix" +msgstr "" + +#: libvips/foreign/dzsave.c:2344 +msgid "Filename suffix for tiles" +msgstr "" + +#: libvips/foreign/dzsave.c:2350 +#, fuzzy +msgid "Overlap" +msgstr "kein Überlappen" + +#: libvips/foreign/dzsave.c:2351 +#, fuzzy +msgid "Tile overlap in pixels" +msgstr "Kachelhöhe in Bildpunkten" + +#: libvips/foreign/dzsave.c:2357 +#, fuzzy +msgid "Tile size" +msgstr "Kachelbreite" + +#: libvips/foreign/dzsave.c:2358 +#, fuzzy +msgid "Tile size in pixels" +msgstr "Kachelbreite in Bildpunkten" + +#: libvips/foreign/dzsave.c:2365 libvips/foreign/tiffsave.c:379 +#, fuzzy +msgid "Pyramid depth" +msgstr "Pyramide" + +#: libvips/foreign/dzsave.c:2371 +msgid "Center" +msgstr "" + +#: libvips/foreign/dzsave.c:2372 +#, fuzzy +msgid "Center image in tile" +msgstr "Bild in PNG-Datei speichern" + +#: libvips/foreign/dzsave.c:2379 +msgid "Rotate image during save" +msgstr "" + +#: libvips/foreign/dzsave.c:2385 +msgid "Container" +msgstr "" + +#: libvips/foreign/dzsave.c:2386 +msgid "Pyramid container type" +msgstr "" + +#: libvips/foreign/dzsave.c:2392 libvips/foreign/heifsave.c:795 +#: libvips/foreign/pngsave.c:211 libvips/foreign/spngsave.c:689 +#: libvips/foreign/tiffsave.c:257 +msgid "Compression" +msgstr "Komprimierung" + +#: libvips/foreign/dzsave.c:2393 +msgid "ZIP deflate compression level" +msgstr "" + +#: libvips/foreign/dzsave.c:2399 libvips/foreign/tiffsave.c:357 +msgid "Region shrink" +msgstr "" + +#: libvips/foreign/dzsave.c:2400 libvips/foreign/tiffsave.c:358 +msgid "Method to shrink regions" +msgstr "" + +#: libvips/foreign/dzsave.c:2406 +msgid "Skip blanks" +msgstr "" + +#: libvips/foreign/dzsave.c:2407 +msgid "Skip tiles which are nearly equal to the background" +msgstr "" + +#: libvips/foreign/dzsave.c:2413 +msgid "id" +msgstr "" + +#: libvips/foreign/dzsave.c:2414 +msgid "Resource ID" +msgstr "" + +#: libvips/foreign/dzsave.c:2420 libvips/foreign/heifsave.c:774 +#: libvips/foreign/jp2ksave.c:1000 libvips/foreign/jpegsave.c:164 +#: libvips/foreign/jxlsave.c:838 libvips/foreign/tiffsave.c:265 +#: libvips/foreign/webpsave.c:826 +msgid "Q" +msgstr "Q" + +#: libvips/foreign/dzsave.c:2421 libvips/foreign/heifsave.c:775 +#: libvips/foreign/jp2ksave.c:1001 libvips/foreign/jpegsave.c:165 +#: libvips/foreign/tiffsave.c:266 libvips/foreign/webpsave.c:827 +msgid "Q factor" +msgstr "Q-Faktor" + +#: libvips/foreign/dzsave.c:2430 +msgid "No strip" +msgstr "" + +#: libvips/foreign/dzsave.c:2431 +msgid "Don't strip tile metadata" +msgstr "" + +#: libvips/foreign/dzsave.c:2437 +#, fuzzy +msgid "Base name" +msgstr "Bilddateiname" + +#: libvips/foreign/dzsave.c:2438 +#, fuzzy +msgid "Base name to save to" +msgstr "Name der Datei in die gespeichert werden soll" + +#: libvips/foreign/dzsave.c:2444 +#, fuzzy +msgid "Directory name" +msgstr "Richtung" + +#: libvips/foreign/dzsave.c:2445 +#, fuzzy +msgid "Directory name to save to" +msgstr "Name der Datei in die gespeichert werden soll" + +#: libvips/foreign/dzsave.c:2465 libvips/foreign/tiffsave.c:350 +#, fuzzy +msgid "Properties" +msgstr "Transaktionen" + +#: libvips/foreign/dzsave.c:2466 +msgid "Write a properties file to the output directory" +msgstr "" + +# http://de.wikipedia.org/wiki/Portable_Pixmap +#: libvips/foreign/dzsave.c:2533 +#, fuzzy +msgid "save image to deepzoom target" +msgstr "Bild in PPM-Datei speichern" + +# http://de.wikipedia.org/wiki/Portable_Pixmap +#: libvips/foreign/dzsave.c:2593 +#, fuzzy +msgid "save image to deepzoom file" +msgstr "Bild in PPM-Datei speichern" + +#: libvips/foreign/dzsave.c:2652 +#, fuzzy +msgid "save image to dz buffer" +msgstr "Bild in den PNG-Puffer speichern" + +#: libvips/foreign/exif.c:199 +#, fuzzy +msgid "exif too small" +msgstr "Ziel zu klein" + +#: libvips/foreign/exif.c:203 +#, fuzzy +msgid "exif too large" +msgstr "Fenster zu groß" + +#: libvips/foreign/exif.c:208 +#, fuzzy +msgid "unable to init exif" +msgstr "kann nicht gekürzt werden" + +#: libvips/foreign/exif.c:1260 libvips/foreign/exif.c:1270 +#: libvips/foreign/exif.c:1279 libvips/foreign/exif.c:1319 +#, fuzzy, c-format +msgid "bad exif meta \"%s\"" +msgstr "falscher Modus »%s«" + +#: libvips/foreign/exif.c:1496 +msgid "error saving EXIF" +msgstr "Fehler beim Speichern von EXIF" + +#: libvips/foreign/fits.c:184 libvips/foreign/matlab.c:113 +#: libvips/iofuncs/vips.c:159 libvips/mosaicing/global_balance.c:1240 +#: libvips/mosaicing/global_balance.c:1690 +#, c-format +msgid "unable to open \"%s\"" +msgstr "»%s« kann nicht geöffnet werden" + +#: libvips/foreign/fits.c:237 +msgid "no HDU found with naxes > 0" +msgstr "" + +#: libvips/foreign/fits.c:275 +msgid "dimensions above 3 must be size 1" +msgstr "Dimensionen größer drei müssen die Größe eins haben" + +#: libvips/foreign/fits.c:290 +#, c-format +msgid "bad number of axis %d" +msgstr "falsche Achsenanzahl %d" + +#: libvips/foreign/fits.c:301 +#, c-format +msgid "unsupported bitpix %d\n" +msgstr "nicht unterstützte »bitpix« %d\n" + +#: libvips/foreign/fits.c:586 libvips/iofuncs/vips.c:222 +#, c-format +msgid "unable to write to \"%s\"" +msgstr "auf »%s« kann nicht geschrieben werden" + +#: libvips/foreign/fits.c:729 +#, c-format +msgid "unsupported BandFmt %d\n" +msgstr "nicht unterstütztes BandFmt %d\n" + +#: libvips/foreign/fitsload.c:101 libvips/foreign/niftiload.c:130 +#: libvips/foreign/openslideload.c:916 +msgid "no filename available" +msgstr "" + +#: libvips/foreign/fitsload.c:183 +#, fuzzy +msgid "FITS loader base class" +msgstr "Basisklasse" + +#: libvips/foreign/fitsload.c:251 +msgid "load a FITS image" +msgstr "ein FITS-Bild laden" + +#: libvips/foreign/fitsload.c:329 +#, fuzzy +msgid "load FITS from a source" +msgstr "ein FITS-Bild laden" + +# http://de.wikipedia.org/wiki/Flexible_Image_Transport_System +#: libvips/foreign/fitssave.c:129 +msgid "save image to fits file" +msgstr "Bild in FITS-Datei speichern" + +#: libvips/foreign/foreign.c:408 +msgid "load and save image files" +msgstr "Bilddateien laden und speichern" + +#: libvips/foreign/foreign.c:607 +#, fuzzy, c-format +msgid "file \"%s\" does not exist" +msgstr "Datei »%s« nicht gefunden" + +#: libvips/foreign/foreign.c:612 +#, c-format +msgid "\"%s\" is a directory" +msgstr "" + +#: libvips/foreign/foreign.c:621 libvips/foreign/foreign.c:2003 +#, c-format +msgid "\"%s\" is not a known file format" +msgstr "»%s« ist kein bekanntes Dateiformat" + +#: libvips/foreign/foreign.c:708 +#, fuzzy +msgid "buffer is not in a known format" +msgstr "»%s« ist kein bekanntes Dateiformat" + +#: libvips/foreign/foreign.c:769 +#, fuzzy +msgid "source is not in a known format" +msgstr "»%s« ist kein bekanntes Dateiformat" + +#: libvips/foreign/foreign.c:979 +#, fuzzy +msgid "images do not match between header and load" +msgstr "Bilder passen in der Bildpunktgröße nicht zusammen" + +#: libvips/foreign/foreign.c:1210 +#, fuzzy +msgid "loaders" +msgstr "Dateilader" + +#: libvips/foreign/foreign.c:1221 +msgid "Flags" +msgstr "Schalter" + +#: libvips/foreign/foreign.c:1222 +msgid "Flags for this file" +msgstr "Schalter für diese Datei" + +#: libvips/foreign/foreign.c:1228 libvips/iofuncs/target.c:294 +msgid "Memory" +msgstr "" + +#: libvips/foreign/foreign.c:1229 +msgid "Force open via memory" +msgstr "" + +#: libvips/foreign/foreign.c:1236 +#, fuzzy +msgid "Required access pattern for this file" +msgstr "Komprimierung für diese Datei" + +#: libvips/foreign/foreign.c:1242 libvips/resample/thumbnail.c:1037 +#, fuzzy +msgid "Fail on" +msgstr "scheitern" + +#: libvips/foreign/foreign.c:1243 libvips/resample/thumbnail.c:1038 +msgid "Error level to fail on" +msgstr "" + +#: libvips/foreign/foreign.c:1249 +msgid "Revalidate" +msgstr "" + +#: libvips/foreign/foreign.c:1250 +msgid "Don't use a cached result for this operation" +msgstr "" + +#: libvips/foreign/foreign.c:1256 +msgid "Sequential" +msgstr "sequenziell" + +#: libvips/foreign/foreign.c:1257 +msgid "Sequential read only" +msgstr "sequenziell nur mit Lesezugriff" + +#: libvips/foreign/foreign.c:1263 +msgid "Fail" +msgstr "scheitern" + +#: libvips/foreign/foreign.c:1264 +msgid "Fail on first warning" +msgstr "scheitert bei erster Warnung" + +#: libvips/foreign/foreign.c:1270 +msgid "Disc" +msgstr "Platte" + +#: libvips/foreign/foreign.c:1271 +msgid "Open to disc" +msgstr "offen zur Platte" + +#: libvips/foreign/foreign.c:1871 +#, fuzzy +msgid "savers" +msgstr "Dateispeicherer" + +#: libvips/foreign/foreign.c:1895 +msgid "Image to save" +msgstr "zu speicherndes Bild" + +#: libvips/foreign/foreign.c:1900 +msgid "Keep" +msgstr "" + +#: libvips/foreign/foreign.c:1901 +msgid "Which metadata to retain" +msgstr "" + +#: libvips/foreign/foreign.c:1916 +msgid "Set page height for multipage save" +msgstr "" + +#: libvips/foreign/foreign.c:1923 +#, fuzzy +msgid "Filename of ICC profile to embed" +msgstr "einzubettendes ICC-Profil" + +#: libvips/foreign/foreign.c:1929 +msgid "Strip" +msgstr "" + +#: libvips/foreign/foreign.c:1930 +#, fuzzy +msgid "Strip all metadata from image" +msgstr "einen Bereich eines Bildes extrahieren" + +#: libvips/foreign/foreign.c:2158 +#, fuzzy, c-format +msgid "\"%s\" is not a known target format" +msgstr "»%s« ist kein bekanntes Dateiformat" + +#: libvips/foreign/foreign.c:2216 +#, fuzzy, c-format +msgid "\"%s\" is not a known buffer format" +msgstr "»%s« ist kein bekanntes Dateiformat" + +#: libvips/foreign/heifload.c:820 libvips/foreign/jxlload.c:753 +#: libvips/foreign/nsgifload.c:448 libvips/foreign/webp2vips.c:501 +#, fuzzy +msgid "bad page number" +msgstr "falsche Seitennummer %d" + +#: libvips/foreign/heifload.c:872 +msgid "undefined bits per pixel" +msgstr "" + +#: libvips/foreign/heifload.c:884 +msgid "not all pages are the same size" +msgstr "" + +#: libvips/foreign/heifload.c:983 +#, fuzzy +msgid "bad image dimensions on decode" +msgstr "Überlaufganzzahl der Bildabmessungen" + +#: libvips/foreign/heifload.c:990 +#, fuzzy +msgid "unable to get image data" +msgstr "Dateistatus kann nicht abgefragt werden" + +#: libvips/foreign/heifload.c:1075 +#, fuzzy +msgid "load a HEIF image" +msgstr "ein FITS-Bild laden" + +#: libvips/foreign/heifload.c:1083 libvips/foreign/jp2kload.c:1229 +#: libvips/foreign/jxlload.c:1132 libvips/foreign/magick6load.c:141 +#: libvips/foreign/magick7load.c:382 libvips/foreign/nsgifload.c:620 +#: libvips/foreign/pdfiumload.c:695 libvips/foreign/popplerload.c:545 +#: libvips/foreign/tiffload.c:196 libvips/foreign/webpload.c:178 +msgid "Page" +msgstr "Seite" + +#: libvips/foreign/heifload.c:1084 libvips/foreign/jxlload.c:1133 +#: libvips/foreign/magick6load.c:142 libvips/foreign/magick7load.c:383 +#: libvips/foreign/nsgifload.c:621 libvips/foreign/pdfiumload.c:696 +#: libvips/foreign/popplerload.c:546 libvips/foreign/tiffload.c:197 +#: libvips/foreign/webpload.c:179 +#, fuzzy +msgid "First page to load" +msgstr "Name der Datei, aus der geladen werden soll" + +#: libvips/foreign/heifload.c:1091 libvips/foreign/jxlload.c:1140 +#: libvips/foreign/magick6load.c:149 libvips/foreign/magick7load.c:390 +#: libvips/foreign/nsgifload.c:628 libvips/foreign/pdfiumload.c:703 +#: libvips/foreign/popplerload.c:553 libvips/foreign/tiffload.c:204 +#: libvips/foreign/webpload.c:186 +#, fuzzy +msgid "Number of pages to load, -1 for all" +msgstr "Anzahl der Patches ein Diagramm hinunter" + +#: libvips/foreign/heifload.c:1097 +msgid "Thumbnail" +msgstr "" + +#: libvips/foreign/heifload.c:1098 +#, fuzzy +msgid "Fetch thumbnail image" +msgstr "Miniaturansicht auf GRÖẞE setzen" + +#: libvips/foreign/heifload.c:1104 libvips/foreign/jpegload.c:198 +#: libvips/foreign/tiffload.c:210 +msgid "Autorotate" +msgstr "" + +#: libvips/foreign/heifload.c:1105 libvips/foreign/jpegload.c:199 +msgid "Rotate image using exif orientation" +msgstr "" + +#: libvips/foreign/heifload.c:1112 libvips/foreign/jpegload.c:206 +#: libvips/foreign/pngload.c:171 libvips/foreign/spngload.c:678 +#: libvips/foreign/svgload.c:732 libvips/foreign/tiffload.c:225 +msgid "Unlimited" +msgstr "" + +#: libvips/foreign/heifload.c:1113 libvips/foreign/jpegload.c:207 +#: libvips/foreign/pngload.c:172 libvips/foreign/spngload.c:679 +#: libvips/foreign/tiffload.c:226 +msgid "Remove all denial of service limits" +msgstr "" + +#: libvips/foreign/heifload.c:1341 libvips/foreign/jp2kload.c:1386 +#: libvips/foreign/jpegload.c:431 libvips/foreign/jxlload.c:1294 +#: libvips/foreign/magick6load.c:314 libvips/foreign/magick7load.c:933 +#: libvips/foreign/nsgifload.c:844 libvips/foreign/pdfiumload.c:873 +#: libvips/foreign/pngload.c:395 libvips/foreign/popplerload.c:750 +#: libvips/foreign/radload.c:357 libvips/foreign/spngload.c:912 +#: libvips/foreign/svgload.c:998 libvips/foreign/tiffload.c:461 +#: libvips/foreign/webpload.c:425 libvips/resample/thumbnail.c:1446 +msgid "Buffer to load from" +msgstr "Puffer, aus dem geladen werden soll" + +#: libvips/foreign/heifsave.c:441 +#, fuzzy +msgid "unimplemented format conversion" +msgstr "nicht implementierte Maske" + +#: libvips/foreign/heifsave.c:550 +#, fuzzy, c-format +msgid "%d-bit colour depth not supported" +msgstr "%d-dimensionale Bilder nicht unterstützt" + +#: libvips/foreign/heifsave.c:583 +#, fuzzy +msgid "Unsupported compression" +msgstr "nicht unterstützter Farbtyp" + +#: libvips/foreign/heifsave.c:767 +#, fuzzy +msgid "save image in HEIF format" +msgstr "Bild in den PNG-Puffer speichern" + +#: libvips/foreign/heifsave.c:788 libvips/foreign/jp2ksave.c:985 +#: libvips/foreign/jxlsave.c:831 libvips/foreign/tiffsave.c:371 +#: libvips/foreign/webpsave.c:833 +msgid "Lossless" +msgstr "" + +#: libvips/foreign/heifsave.c:789 libvips/foreign/jp2ksave.c:986 +#: libvips/foreign/jxlsave.c:832 libvips/foreign/webpsave.c:834 +msgid "Enable lossless compression" +msgstr "" + +#: libvips/foreign/heifsave.c:796 +#, fuzzy +msgid "Compression format" +msgstr "Komprimierungsfaktor" + +#: libvips/foreign/heifsave.c:804 libvips/foreign/heifsave.c:819 +msgid "CPU effort" +msgstr "" + +#: libvips/foreign/heifsave.c:810 libvips/foreign/jp2ksave.c:992 +#: libvips/foreign/jpegsave.c:220 +#, fuzzy +msgid "Subsample mode" +msgstr "Öffnen-Modus" + +#: libvips/foreign/heifsave.c:811 libvips/foreign/jp2ksave.c:993 +#: libvips/foreign/jpegsave.c:221 +msgid "Select chroma subsample operation mode" +msgstr "" + +#: libvips/foreign/heifsave.c:818 +msgid "Speed" +msgstr "" + +#: libvips/foreign/heifsave.c:825 +msgid "Encoder" +msgstr "" + +#: libvips/foreign/heifsave.c:826 +msgid "Select encoder to use" +msgstr "" + +#: libvips/foreign/heifsave.c:1047 +#, fuzzy +msgid "save image in AVIF format" +msgstr "Bild in den PNG-Puffer speichern" + +#: libvips/foreign/jp2kload.c:235 +#, fuzzy +msgid "unable to create jp2k stream" +msgstr "Thread kann nicht erstellt werden" + +#: libvips/foreign/jp2kload.c:548 +#, fuzzy, c-format +msgid "unsupported colourspace %d" +msgstr "nicht unterstützter Farbraum %d" + +#: libvips/foreign/jp2kload.c:597 +#, fuzzy +msgid "too many image bands" +msgstr "zu viele Argumente" + +#: libvips/foreign/jp2kload.c:601 +#, fuzzy +msgid "no image components" +msgstr "keine Bilddaten" + +#: libvips/foreign/jp2kload.c:618 +msgid "components differ in geometry" +msgstr "" + +#: libvips/foreign/jp2kload.c:625 +msgid "components differ in precision" +msgstr "" + +#: libvips/foreign/jp2kload.c:996 libvips/foreign/jp2kload.c:1093 +#, fuzzy +msgid "decoded image does not match container" +msgstr "»ink«-Bild passt nicht in das Bild" + +#: libvips/foreign/jp2kload.c:1217 +#, fuzzy +msgid "load JPEG2000 image" +msgstr "ein FITS-Bild laden" + +#: libvips/foreign/jp2kload.c:1230 +#, fuzzy +msgid "Load this page from the image" +msgstr "diese Seite aus der Datei laden" + +#: libvips/foreign/jp2kload.c:1600 libvips/foreign/jp2ksave.c:1434 +#, fuzzy +msgid "libvips built without JPEG2000 support" +msgstr "VIPS wurde ohne FFT-Unterstützung konfiguriert" + +#: libvips/foreign/jp2ksave.c:818 +#, fuzzy +msgid "not an integer format" +msgstr "»%s« ist kein bekanntes Dateiformat" + +#: libvips/foreign/jp2ksave.c:963 +msgid "save image in JPEG2000 format" +msgstr "" + +#: libvips/foreign/jpeg2vips.c:415 +#, c-format +msgid "read gave %ld warnings" +msgstr "Lesen ergab %ld Warnungen" + +#: libvips/foreign/jpeg2vips.c:886 libvips/foreign/spngload.c:529 +#: libvips/foreign/vipspng.c:723 +#, c-format +msgid "out of order read at line %d" +msgstr "" + +#: libvips/foreign/jpegload.c:116 +#, c-format +msgid "bad shrink factor %d" +msgstr "falscher Schrumpffaktor %d" + +#: libvips/foreign/jpegload.c:177 +msgid "load jpeg" +msgstr "JPEG laden" + +#: libvips/foreign/jpegload.c:191 libvips/foreign/webpload.c:199 +msgid "Shrink" +msgstr "verkleinern" + +#: libvips/foreign/jpegload.c:192 libvips/foreign/webpload.c:200 +msgid "Shrink factor on load" +msgstr "falscher Verkleinerungsfaktor %d" + +#: libvips/foreign/jpegload.c:270 +#, fuzzy +msgid "load image from jpeg source" +msgstr "Bild in den JPEG-Puffer speichern" + +#: libvips/foreign/jpegload.c:346 +msgid "load jpeg from file" +msgstr "JPEG aus Datei laden" + +#: libvips/foreign/jpegload.c:424 +msgid "load jpeg from buffer" +msgstr "JPEG aus Puffer laden" + +#: libvips/foreign/jpegsave.c:153 +msgid "save jpeg" +msgstr "JPEG speichern" + +#: libvips/foreign/jpegsave.c:171 +#, fuzzy +msgid "Optimize coding" +msgstr "Bildpunktkodierung" + +#: libvips/foreign/jpegsave.c:172 +msgid "Compute optimal Huffman coding tables" +msgstr "" + +#: libvips/foreign/jpegsave.c:178 libvips/foreign/pngsave.c:218 +#: libvips/foreign/spngsave.c:696 +msgid "Interlace" +msgstr "Zeilensprung" + +#: libvips/foreign/jpegsave.c:179 +msgid "Generate an interlaced (progressive) jpeg" +msgstr "" + +#: libvips/foreign/jpegsave.c:185 +msgid "No subsample" +msgstr "" + +#: libvips/foreign/jpegsave.c:186 +msgid "Disable chroma subsample" +msgstr "" + +#: libvips/foreign/jpegsave.c:192 +msgid "Trellis quantisation" +msgstr "" + +#: libvips/foreign/jpegsave.c:193 +msgid "Apply trellis quantisation to each 8x8 block" +msgstr "" + +#: libvips/foreign/jpegsave.c:199 +msgid "Overshoot de-ringing" +msgstr "" + +#: libvips/foreign/jpegsave.c:200 +msgid "Apply overshooting to samples with extreme values" +msgstr "" + +#: libvips/foreign/jpegsave.c:206 +msgid "Optimize scans" +msgstr "" + +#: libvips/foreign/jpegsave.c:207 +msgid "Split spectrum of DCT coefficients into separate scans" +msgstr "" + +#: libvips/foreign/jpegsave.c:213 +msgid "Quantization table" +msgstr "" + +#: libvips/foreign/jpegsave.c:214 +msgid "Use predefined quantization table with given index" +msgstr "" + +#: libvips/foreign/jpegsave.c:228 +msgid "Restart interval" +msgstr "" + +#: libvips/foreign/jpegsave.c:229 +msgid "Add restart markers every specified number of mcu" +msgstr "" + +#: libvips/foreign/jpegsave.c:288 +#, fuzzy +msgid "save image to jpeg target" +msgstr "Bild in JPEG-Datei speichern" + +#: libvips/foreign/jpegsave.c:357 +msgid "save image to jpeg file" +msgstr "Bild in JPEG-Datei speichern" + +#: libvips/foreign/jpegsave.c:435 +msgid "save image to jpeg buffer" +msgstr "Bild in den JPEG-Puffer speichern" + +# http://de.wikipedia.org/wiki/MIME#image +#: libvips/foreign/jpegsave.c:511 +msgid "save image to jpeg mime" +msgstr "Bild in JPEG-MIME speichern" + +#: libvips/foreign/jxlload.c:251 libvips/foreign/jxlsave.c:433 +#: libvips/iofuncs/dbuf.c:81 libvips/iofuncs/util.c:684 +msgid "out of memory" +msgstr "Hauptspeicher reicht nicht aus" + +#: libvips/foreign/jxlload.c:576 +#, fuzzy +msgid "bad buffer size" +msgstr "falsche Größe" + +#: libvips/foreign/jxlload.c:602 libvips/foreign/webp2vips.c:724 +msgid "not enough frames" +msgstr "" + +#: libvips/foreign/jxlload.c:683 libvips/foreign/radiance.c:704 +#, fuzzy +msgid "image size out of bounds" +msgstr "Bild muss ein Band haben" + +#: libvips/foreign/jxlload.c:1119 +#, fuzzy +msgid "load JPEG-XL image" +msgstr "ein OpenEXR-Bild laden" + +#: libvips/foreign/jxlsave.c:748 libvips/foreign/webpsave.c:744 +#, c-format +msgid "failed to allocate %zu bytes" +msgstr "" + +#: libvips/foreign/jxlsave.c:796 +msgid "save image in JPEG-XL format" +msgstr "" + +#: libvips/foreign/jxlsave.c:810 +msgid "Tier" +msgstr "" + +#: libvips/foreign/jxlsave.c:811 +msgid "Decode speed tier" +msgstr "" + +#: libvips/foreign/jxlsave.c:817 libvips/morphology/nearest.c:315 +msgid "Distance" +msgstr "" + +#: libvips/foreign/jxlsave.c:818 +msgid "Target butteraugli distance" +msgstr "" + +#: libvips/foreign/jxlsave.c:825 +msgid "Encoding effort" +msgstr "" + +#: libvips/foreign/jxlsave.c:839 +#, fuzzy +msgid "Quality factor" +msgstr "Q-Faktor" + +#: libvips/foreign/magick2vips.c:305 +#, c-format +msgid "unsupported image type %d" +msgstr "nicht unterstützter Bildtyp %d" + +#: libvips/foreign/magick2vips.c:354 libvips/foreign/magick7load.c:471 +#, c-format +msgid "bad image dimensions %d x %d pixels, %d bands" +msgstr "" + +#: libvips/foreign/magick2vips.c:384 +#, c-format +msgid "unsupported bit depth %d" +msgstr "nicht unterstützte Bit-Tiefe %d" + +#: libvips/foreign/magick2vips.c:791 libvips/foreign/webp2vips.c:638 +msgid "unable to read pixels" +msgstr "Bildpunkte können nicht gelesen werden" + +#: libvips/foreign/magick2vips.c:823 libvips/foreign/magick2vips.c:861 +#, fuzzy, c-format +msgid "unable to read file \"%s\"" +msgstr "Profil kann nicht gelesen werden" + +#: libvips/foreign/magick2vips.c:870 libvips/foreign/magick2vips.c:949 +msgid "bad image size" +msgstr "falsche Bildgröße" + +#: libvips/foreign/magick2vips.c:902 +#, fuzzy +msgid "unable to read buffer" +msgstr "In den Puffer kann nicht geschrieben werden." + +#: libvips/foreign/magick2vips.c:940 +#, fuzzy +msgid "unable to ping blob" +msgstr "»%s« kann nicht geöffnet werden" + +#: libvips/foreign/magick6load.c:113 +#, fuzzy +msgid "load with ImageMagick" +msgstr "Datei mit ImageMagick laden" + +#: libvips/foreign/magick6load.c:134 libvips/foreign/magick7load.c:375 +msgid "Density" +msgstr "" + +#: libvips/foreign/magick6load.c:135 libvips/foreign/magick7load.c:376 +msgid "Canvas resolution for rendering vector formats like SVG" +msgstr "" + +#: libvips/foreign/magick6load.c:155 libvips/foreign/magick7load.c:396 +msgid "All frames" +msgstr "" + +#: libvips/foreign/magick6load.c:156 libvips/foreign/magick7load.c:397 +#, fuzzy +msgid "Read all frames from an image" +msgstr "einen Bereich eines Bildes extrahieren" + +#: libvips/foreign/magick6load.c:231 +msgid "load file with ImageMagick" +msgstr "Datei mit ImageMagick laden" + +#: libvips/foreign/magick6load.c:306 +#, fuzzy +msgid "load buffer with ImageMagick" +msgstr "Datei mit ImageMagick laden" + +#: libvips/foreign/magick7load.c:353 +#, fuzzy +msgid "load with ImageMagick7" +msgstr "Datei mit ImageMagick laden" + +#: libvips/foreign/magick7load.c:414 +#, c-format +msgid "Magick: %s %s" +msgstr "" + +#: libvips/foreign/magick7load.c:491 +#, fuzzy, c-format +msgid "unsupported bit depth %zd" +msgstr "nicht unterstützte Bit-Tiefe %d" + +#: libvips/foreign/magick7load.c:845 +#, fuzzy +msgid "load file with ImageMagick7" +msgstr "Datei mit ImageMagick laden" + +#: libvips/foreign/magick7load.c:926 +#, fuzzy +msgid "load buffer with ImageMagick7" +msgstr "Datei mit ImageMagick laden" + +#: libvips/foreign/magick.c:804 +#, fuzzy, c-format +msgid "libMagick error: %s %s" +msgstr "" +"Datei »%s« kann nicht gelesen werden\n" +"libMagick-Fehler: %s %s" + +#: libvips/foreign/magick.c:807 +#, fuzzy, c-format +msgid "libMagick error: %s" +msgstr "EXR-Fehler: %s" + +#: libvips/foreign/magick.c:810 +msgid "libMagick error:" +msgstr "" + +#: libvips/foreign/matlab.c:121 +#, c-format +msgid "no matrix variables in \"%s\"" +msgstr "keine Matrixvariablen in »%s«" + +#: libvips/foreign/matlab.c:203 +#, c-format +msgid "unsupported rank %d\n" +msgstr "nicht unterstützte Rangstufe %d\n" + +#: libvips/foreign/matlab.c:211 +#, c-format +msgid "unsupported class type %d\n" +msgstr "nicht unterstützter Klassentyp %d\n" + +#: libvips/foreign/matlab.c:265 +msgid "Mat_VarReadDataAll failed" +msgstr "»Mat_VarReadDataAll« fehlgeschlagen" + +# http://www.dateiendung.com/format/mat +#: libvips/foreign/matload.c:122 +msgid "load mat from file" +msgstr "Mat aus Datei laden" + +#: libvips/foreign/matrixload.c:128 libvips/foreign/matrixload.c:242 +#, fuzzy, c-format +msgid "bad number \"%s\"" +msgstr "falscher Modus »%s«" + +#: libvips/foreign/matrixload.c:137 +msgid "no width / height" +msgstr "" + +#: libvips/foreign/matrixload.c:143 +msgid "width / height not int" +msgstr "" + +#: libvips/foreign/matrixload.c:156 +#, fuzzy +msgid "width / height out of range" +msgstr "Parameter außerhalb des Bereichs" + +#: libvips/foreign/matrixload.c:160 +msgid "zero scale" +msgstr "" + +#: libvips/foreign/matrixload.c:251 +#, c-format +msgid "line %d too short" +msgstr "" + +# http://www.dateiendung.com/format/mat +#: libvips/foreign/matrixload.c:273 +#, fuzzy +msgid "load matrix" +msgstr "Mat aus Datei laden" + +# http://de.wikipedia.org/wiki/Rohdatenformat_(Fotografie) +#: libvips/foreign/matrixsave.c:175 +#, fuzzy +msgid "save image to matrix" +msgstr "Bild in Rohdatenformatdatei speichern" + +#: libvips/foreign/matrixsave.c:323 +#, fuzzy +msgid "print matrix" +msgstr "falsche Eingabematrix" + +#: libvips/foreign/niftiload.c:406 +#, fuzzy +msgid "invalid dimension" +msgstr "falsche Abmessungen" + +#: libvips/foreign/niftiload.c:417 +#, fuzzy +msgid "invalid resolution" +msgstr "ungültiges Argument" + +#: libvips/foreign/niftiload.c:431 libvips/foreign/niftiload.c:435 +#: libvips/foreign/niftisave.c:309 +#, fuzzy +msgid "dimension overflow" +msgstr "Überlaufganzzahl der Bildabmessungen" + +#: libvips/foreign/niftiload.c:536 +#, fuzzy +msgid "unable to read NIFTI header" +msgstr "Kopfdaten für »%s« können nicht gelesen werden" + +#: libvips/foreign/niftiload.c:564 +#, fuzzy +msgid "unable to load NIFTI file" +msgstr "Profil kann nicht gelesen werden" + +#: libvips/foreign/niftiload.c:594 +#, fuzzy +msgid "load a NIFTI image" +msgstr "ein FITS-Bild laden" + +#: libvips/foreign/niftiload.c:705 +msgid "load NIfTI volume" +msgstr "" + +#: libvips/foreign/niftiload.c:783 +msgid "load NIfTI volumes" +msgstr "" + +#: libvips/foreign/niftisave.c:115 libvips/foreign/niftisave.c:322 +#, fuzzy +msgid "unsupported libvips image type" +msgstr "nicht unterstützter Bildtyp %d" + +#: libvips/foreign/niftisave.c:122 +#, fuzzy +msgid "8-bit colour images only" +msgstr "nur skalare Bilder" + +#: libvips/foreign/niftisave.c:132 +#, fuzzy +msgid "3 or 4 band colour images only" +msgstr "nur RGB-TIFF mit drei oder vier Bändern" + +#: libvips/foreign/niftisave.c:251 +msgid "bad nifti-ext- field name" +msgstr "" + +#: libvips/foreign/niftisave.c:260 +#, fuzzy +msgid "unable to attach nifti ext" +msgstr "Dateistatus kann nicht abgefragt werden" + +#: libvips/foreign/niftisave.c:315 libvips/foreign/nsgifload.c:644 +#: libvips/foreign/webp2vips.c:550 +#, fuzzy +msgid "bad image dimensions" +msgstr "falsche Abmessungen" + +#: libvips/foreign/niftisave.c:375 +#, fuzzy +msgid "unable to set nifti filename" +msgstr "Dateistatus kann nicht abgefragt werden" + +# http://de.wikipedia.org/wiki/Flexible_Image_Transport_System +#: libvips/foreign/niftisave.c:427 +#, fuzzy +msgid "save image to nifti file" +msgstr "Bild in FITS-Datei speichern" + +#: libvips/foreign/nsgifload.c:420 +msgid "no frames in GIF" +msgstr "" + +#: libvips/foreign/nsgifload.c:463 +#, fuzzy +msgid "bad frame" +msgstr "falscher Parameter" + +#: libvips/foreign/nsgifload.c:607 libvips/foreign/nsgifload.c:757 +#: libvips/foreign/nsgifload.c:837 +msgid "load GIF with libnsgif" +msgstr "" + +#: libvips/foreign/nsgifload.c:901 +#, fuzzy +msgid "load gif from source" +msgstr "TIFF aus Datei laden" + +#: libvips/foreign/openexr2vips.c:123 +#, c-format +msgid "EXR error: %s" +msgstr "EXR-Fehler: %s" + +#: libvips/foreign/openexrload.c:129 +msgid "load an OpenEXR image" +msgstr "ein OpenEXR-Bild laden" + +#: libvips/foreign/openslideload.c:207 +msgid "invalid associated image name" +msgstr "ungültiger zugehöriger Bildname" + +#: libvips/foreign/openslideload.c:252 +msgid "specify only one of level and associated image" +msgstr "" + +#: libvips/foreign/openslideload.c:259 +msgid "specify only one of attach_assicated and associated image" +msgstr "" + +#: libvips/foreign/openslideload.c:376 libvips/foreign/openslideload.c:491 +#: libvips/foreign/openslideload.c:652 +#, fuzzy, c-format +msgid "opening slide: %s" +msgstr "Fehler beim Öffnen des Dias" + +#: libvips/foreign/openslideload.c:398 +#, c-format +msgid "reading associated image: %s" +msgstr "zugehöriges Bild wird gelesen: %s" + +#: libvips/foreign/openslideload.c:485 +#, fuzzy +msgid "unsupported slide format" +msgstr "nicht unterstützte Bit-Tiefe" + +#: libvips/foreign/openslideload.c:498 +msgid "invalid slide level" +msgstr "ungültige Diastufe" + +#: libvips/foreign/openslideload.c:590 +#, c-format +msgid "getting dimensions: %s" +msgstr "Abfragen der Abmessungen: %s" + +#: libvips/foreign/openslideload.c:597 +msgid "image dimensions overflow int" +msgstr "Überlaufganzzahl der Bildabmessungen" + +#: libvips/foreign/openslideload.c:753 +#, c-format +msgid "reading region: %s" +msgstr "Region wird gelesen: %s" + +#: libvips/foreign/openslideload.c:1017 +msgid "load OpenSlide base class" +msgstr "" + +#: libvips/foreign/openslideload.c:1046 libvips/foreign/tiffsave.c:364 +msgid "Level" +msgstr "Ebene" + +#: libvips/foreign/openslideload.c:1047 +msgid "Load this level from the file" +msgstr "diese Ebene aus der Datei laden" + +#: libvips/foreign/openslideload.c:1053 +msgid "Autocrop" +msgstr "" + +#: libvips/foreign/openslideload.c:1054 +#, fuzzy +msgid "Crop to image bounds" +msgstr "Transaktionen für Bänder von Bildern" + +#: libvips/foreign/openslideload.c:1060 +msgid "Associated" +msgstr "dazugehörig" + +#: libvips/foreign/openslideload.c:1061 +msgid "Load this associated image" +msgstr "dieses zugehörige Bild laden" + +#: libvips/foreign/openslideload.c:1067 +#, fuzzy +msgid "Attach associated" +msgstr "dazugehörig" + +#: libvips/foreign/openslideload.c:1068 +#, fuzzy +msgid "Attach all associated images" +msgstr "dieses zugehörige Bild laden" + +#: libvips/foreign/openslideload.c:1074 +#, fuzzy +msgid "RGB" +msgstr "GB" + +#: libvips/foreign/openslideload.c:1075 +msgid "Output RGB (not RGBA)" +msgstr "" + +#: libvips/foreign/openslideload.c:1144 +msgid "load file with OpenSlide" +msgstr "Datei mit OpenSlide laden" + +#: libvips/foreign/openslideload.c:1223 +#, fuzzy +msgid "load source with OpenSlide" +msgstr "Datei mit OpenSlide laden" + +#: libvips/foreign/pdfiumload.c:196 +#, fuzzy +msgid "unknown error" +msgstr "Unix-Fehler" + +#: libvips/foreign/pdfiumload.c:291 +#, c-format +msgid "%s: too large for pdfium" +msgstr "" + +#: libvips/foreign/pdfiumload.c:307 +#, fuzzy, c-format +msgid "%s: unable to load" +msgstr "»fd« kann nicht geschlossen werden" + +#: libvips/foreign/pdfiumload.c:318 +#, c-format +msgid "%s: unable to initialize form fill environment" +msgstr "" + +#: libvips/foreign/pdfiumload.c:366 libvips/foreign/popplerload.c:239 +#, fuzzy, c-format +msgid "unable to load page %d" +msgstr "»fd« kann nicht geschlossen werden" + +#: libvips/foreign/pdfiumload.c:478 libvips/foreign/popplerload.c:333 +#, fuzzy +msgid "pages out of range" +msgstr "Parameter außerhalb des Bereichs" + +#: libvips/foreign/pdfiumload.c:513 +#, fuzzy +msgid "page size out of range" +msgstr "Parameter außerhalb des Bereichs" + +#: libvips/foreign/pdfiumload.c:685 +msgid "load PDF with PDFium" +msgstr "" + +#: libvips/foreign/pdfiumload.c:717 libvips/foreign/popplerload.c:567 +#: libvips/foreign/webpload.c:193 +msgid "Factor to scale by" +msgstr "" + +#: libvips/foreign/pdfiumload.c:724 libvips/foreign/popplerload.c:574 +#, fuzzy +msgid "Background colour" +msgstr "Hintergrund" + +#: libvips/foreign/pdfiumload.c:730 libvips/foreign/popplerload.c:580 +msgid "Password" +msgstr "" + +#: libvips/foreign/pdfiumload.c:731 libvips/foreign/popplerload.c:581 +msgid "Password to decrypt with" +msgstr "" + +# Portable Pixmap +#: libvips/foreign/pdfiumload.c:803 libvips/foreign/popplerload.c:680 +#, fuzzy +msgid "load PDF from file" +msgstr "PPM aus Datei laden" + +#: libvips/foreign/pdfiumload.c:866 libvips/foreign/popplerload.c:743 +#, fuzzy +msgid "load PDF from buffer" +msgstr "JPEG aus Puffer laden" + +#: libvips/foreign/pdfiumload.c:924 libvips/foreign/popplerload.c:801 +#, fuzzy +msgid "load PDF from source" +msgstr "JPEG aus Puffer laden" + +#: libvips/foreign/pngload.c:157 libvips/foreign/spngload.c:664 +#, fuzzy +msgid "load png base class" +msgstr "Basisklasse" + +#: libvips/foreign/pngload.c:234 libvips/foreign/spngload.c:749 +#, fuzzy +msgid "load png from source" +msgstr "PNG-Datei aus Datei laden" + +#: libvips/foreign/pngload.c:310 libvips/foreign/spngload.c:827 +msgid "load png from file" +msgstr "PNG-Datei aus Datei laden" + +#: libvips/foreign/pngload.c:388 libvips/foreign/spngload.c:905 +#, fuzzy +msgid "load png from buffer" +msgstr "JPEG aus Puffer laden" + +#: libvips/foreign/pngsave.c:202 +msgid "save png" +msgstr "PNG speichern" + +#: libvips/foreign/pngsave.c:212 libvips/foreign/spngsave.c:690 +msgid "Compression factor" +msgstr "Komprimierungsfaktor" + +#: libvips/foreign/pngsave.c:219 libvips/foreign/spngsave.c:697 +msgid "Interlace image" +msgstr "Zeilensprungbild" + +#: libvips/foreign/pngsave.c:225 libvips/foreign/spngsave.c:703 +msgid "Filter" +msgstr "" + +#: libvips/foreign/pngsave.c:226 +msgid "libpng row filter flag(s)" +msgstr "" + +#: libvips/foreign/pngsave.c:233 libvips/foreign/spngsave.c:711 +msgid "Palette" +msgstr "" + +#: libvips/foreign/pngsave.c:234 libvips/foreign/spngsave.c:712 +msgid "Quantise to 8bpp palette" +msgstr "" + +#: libvips/foreign/pngsave.c:240 libvips/foreign/spngsave.c:718 +#: libvips/foreign/vips2magick.c:489 +msgid "Quality" +msgstr "" + +#: libvips/foreign/pngsave.c:241 libvips/foreign/spngsave.c:719 +msgid "Quantisation quality" +msgstr "" + +#: libvips/foreign/pngsave.c:255 libvips/foreign/spngsave.c:733 +msgid "Write as a 1, 2, 4, 8 or 16 bit image" +msgstr "" + +#: libvips/foreign/pngsave.c:262 libvips/foreign/spngsave.c:740 +msgid "Quantisation CPU effort" +msgstr "" + +#: libvips/foreign/pngsave.c:268 libvips/foreign/spngsave.c:746 +msgid "Colours" +msgstr "" + +#: libvips/foreign/pngsave.c:269 libvips/foreign/spngsave.c:747 +#, fuzzy +msgid "Max number of palette colours" +msgstr "maximale Anzahl von Kacheln, die zwischengespeichert werden soll" + +# http://de.wikipedia.org/wiki/Rohdatenformat_(Fotografie) +#: libvips/foreign/pngsave.c:322 libvips/foreign/spngsave.c:801 +#, fuzzy +msgid "save image to target as PNG" +msgstr "Bild in Rohdatenformatdatei speichern" + +#: libvips/foreign/pngsave.c:374 +msgid "save image to png file" +msgstr "Bild in PNG-Datei speichern" + +#: libvips/foreign/pngsave.c:433 +msgid "save image to png buffer" +msgstr "Bild in den PNG-Puffer speichern" + +#: libvips/foreign/popplerload.c:531 +msgid "load PDF with libpoppler" +msgstr "" + +#: libvips/foreign/ppmload.c:264 +msgid "bad magic number" +msgstr "falsche magische Zahl" + +#: libvips/foreign/ppmload.c:521 +#, fuzzy +msgid "file truncated" +msgstr "Datei wurde gekürzt" + +#: libvips/foreign/ppmload.c:746 +#, fuzzy +msgid "load ppm base class" +msgstr "Basisklasse" + +# Portable Pixmap +#: libvips/foreign/ppmload.c:823 +msgid "load ppm from file" +msgstr "PPM aus Datei laden" + +#: libvips/foreign/ppmsave.c:321 +#, fuzzy +msgid "too few bands for format" +msgstr "unbekanntes Bandformat %d" + +# http://de.wikipedia.org/wiki/Portable_Pixmap +#: libvips/foreign/ppmsave.c:499 +#, fuzzy +msgid "save to ppm" +msgstr "Bild in PPM-Datei speichern" + +#: libvips/foreign/ppmsave.c:507 libvips/foreign/vips2magick.c:483 +#, fuzzy +msgid "Format to save in" +msgstr "Format, in das umgewandelt werden soll" + +#: libvips/foreign/ppmsave.c:514 +msgid "ASCII" +msgstr "ASCII" + +#: libvips/foreign/ppmsave.c:515 +#, fuzzy +msgid "Save as ascii" +msgstr "Bild als ASCII speichern" + +#: libvips/foreign/ppmsave.c:522 +msgid "Set to 1 to write as a 1 bit image" +msgstr "" + +#: libvips/foreign/ppmsave.c:528 libvips/foreign/tiffsave.c:406 +msgid "Squash" +msgstr "quetschen" + +#: libvips/foreign/ppmsave.c:529 +msgid "Save as one bit" +msgstr "" + +# http://de.wikipedia.org/wiki/Portable_Pixmap +#: libvips/foreign/ppmsave.c:586 +msgid "save image to ppm file" +msgstr "Bild in PPM-Datei speichern" + +# http://de.wikipedia.org/wiki/Portable_Pixmap +#: libvips/foreign/ppmsave.c:675 +#, fuzzy +msgid "save image in pbm format" +msgstr "Bild in PPM-Datei speichern" + +#: libvips/foreign/ppmsave.c:707 +#, fuzzy +msgid "save image in pgm format" +msgstr "Bild in den PNG-Puffer speichern" + +# http://de.wikipedia.org/wiki/Portable_Pixmap +#: libvips/foreign/ppmsave.c:739 +#, fuzzy +msgid "save image in pfm format" +msgstr "Bild in PPM-Datei speichern" + +#: libvips/foreign/ppmsave.c:771 +#, fuzzy +msgid "save image in pnm format" +msgstr "Bild in den PNG-Puffer speichern" + +#: libvips/foreign/quantise.c:469 +msgid "libvips not built with quantisation support" +msgstr "" + +#: libvips/foreign/radiance.c:438 +msgid "scanline length mismatch" +msgstr "" + +#: libvips/foreign/radiance.c:455 +msgid "overrun" +msgstr "" + +# http://radsite.lbl.gov/radiance/refer/Notes/picture_format.html +#: libvips/foreign/radiance.c:687 +msgid "error reading radiance header" +msgstr "Fehler beim Lesen der Radiance-Kopfzeilen" + +#: libvips/foreign/radiance.c:774 +#, fuzzy, c-format +msgid "read error line %d" +msgstr "Lesefehler" + +#: libvips/foreign/radload.c:125 +#, fuzzy +msgid "load rad base class" +msgstr "Basisklasse" + +# http://www.dateiendung.com/format/mat +#: libvips/foreign/radload.c:197 +#, fuzzy +msgid "load rad from source" +msgstr "Mat aus Datei laden" + +#: libvips/foreign/radload.c:273 +msgid "load a Radiance image from a file" +msgstr "ein Radiance-Bild aus einer Datei laden" + +#: libvips/foreign/radload.c:350 +#, fuzzy +msgid "load rad from buffer" +msgstr "JPEG aus Puffer laden" + +#: libvips/foreign/radsave.c:92 +#, fuzzy +msgid "save Radiance" +msgstr "Bild in Radiance-Datei speichern" + +#: libvips/foreign/radsave.c:150 +msgid "save image to Radiance file" +msgstr "Bild in Radiance-Datei speichern" + +#: libvips/foreign/radsave.c:203 +#, fuzzy +msgid "save image to Radiance target" +msgstr "Bild in Radiance-Datei speichern" + +#: libvips/foreign/radsave.c:269 +#, fuzzy +msgid "save image to Radiance buffer" +msgstr "Bild in Radiance-Datei speichern" + +#: libvips/foreign/rawload.c:131 +msgid "load raw data from a file" +msgstr "Rohdaten aus einer Datei laden" + +#: libvips/foreign/rawload.c:167 libvips/iofuncs/image.c:1200 +msgid "Size of header" +msgstr "Größe der Kopfdaten" + +#: libvips/foreign/rawload.c:168 libvips/iofuncs/image.c:1201 +msgid "Offset in bytes from start of file" +msgstr "Versatz in Byte vom Anfang der Datei" + +# http://de.wikipedia.org/wiki/Rohdatenformat_(Fotografie) +#: libvips/foreign/rawsave.c:138 +#, fuzzy +msgid "save image to raw" +msgstr "Bild in Rohdatenformatdatei speichern" + +# http://de.wikipedia.org/wiki/Rohdatenformat_(Fotografie) +#: libvips/foreign/rawsave.c:190 +msgid "save image to raw file" +msgstr "Bild in Rohdatenformatdatei speichern" + +#: libvips/foreign/rawsave.c:246 +#, fuzzy +msgid "write raw image to target" +msgstr "Rohdatenbild in Datei-Deskriptor schreiben" + +#: libvips/foreign/rawsave.c:308 +#, fuzzy +msgid "write raw image to buffer" +msgstr "Rohdatenbild in Datei-Deskriptor schreiben" + +#: libvips/foreign/spngload.c:252 libvips/foreign/vipspng.c:582 +#, c-format +msgid "%d text chunks, only %d text chunks will be loaded" +msgstr "" + +#: libvips/foreign/spngload.c:403 +#, fuzzy +msgid "unknown color type" +msgstr "unbekannter Kodierungstyp" + +#: libvips/foreign/spngload.c:562 +#, fuzzy +msgid "libspng read error" +msgstr "Lesefehler" + +#: libvips/foreign/spngsave.c:164 libvips/foreign/vipspng.c:1013 +#, fuzzy +msgid "bad png comment key" +msgstr "falsche Gittergeometrie" + +#: libvips/foreign/spngsave.c:680 +#, fuzzy +msgid "save spng" +msgstr "PNG speichern" + +#: libvips/foreign/spngsave.c:704 +msgid "libspng row filter flag(s)" +msgstr "" + +# http://de.wikipedia.org/wiki/Rohdatenformat_(Fotografie) +#: libvips/foreign/spngsave.c:854 +#, fuzzy +msgid "save image to file as PNG" +msgstr "Bild in Rohdatenformatdatei speichern" + +#: libvips/foreign/spngsave.c:914 +#, fuzzy +msgid "save image to buffer as PNG" +msgstr "Bild in den PNG-Puffer speichern" + +#: libvips/foreign/svgload.c:626 libvips/foreign/svgload.c:644 +msgid "SVG rendering failed" +msgstr "" + +#: libvips/foreign/svgload.c:700 +msgid "load SVG with rsvg" +msgstr "" + +#: libvips/foreign/svgload.c:718 +msgid "Render at this DPI" +msgstr "" + +#: libvips/foreign/svgload.c:725 +msgid "Scale output by this factor" +msgstr "" + +#: libvips/foreign/svgload.c:733 +msgid "Allow SVG of any size" +msgstr "" + +#: libvips/foreign/svgload.c:827 +#, fuzzy +msgid "load svg from source" +msgstr "CSV aus Datei laden" + +#: libvips/foreign/tiff2vips.c:480 libvips/foreign/tiff2vips.c:498 +#, c-format +msgid "required field %d missing" +msgstr "benötigtes Feld %d fehlt" + +#: libvips/foreign/tiff2vips.c:540 +msgid "unknown resolution unit" +msgstr "unbekannte Auflösungseinheit" + +#: libvips/foreign/tiff2vips.c:680 +#, c-format +msgid "bad page number %d" +msgstr "falsche Seitennummer %d" + +#: libvips/foreign/tiff2vips.c:690 +#, fuzzy, c-format +msgid "bad number of pages %d" +msgstr "falsche Achsenanzahl %d" + +#: libvips/foreign/tiff2vips.c:718 libvips/foreign/tiff2vips.c:760 +#: libvips/iofuncs/source.c:812 +msgid "read error" +msgstr "Lesefehler" + +#: libvips/foreign/tiff2vips.c:802 +#, fuzzy, c-format +msgid "TIFF does not contain page %d" +msgstr "TIFF-Datei enthält nicht Seite %d" + +#: libvips/foreign/tiff2vips.c:812 +msgid "no SUBIFD tag" +msgstr "" + +#: libvips/foreign/tiff2vips.c:818 +#, c-format +msgid "subifd %d out of range, only 0-%d available" +msgstr "" + +#: libvips/foreign/tiff2vips.c:826 +msgid "subdirectory unreadable" +msgstr "" + +#: libvips/foreign/tiff2vips.c:867 +#, fuzzy, c-format +msgid "not %d bands" +msgstr "nicht ein Band oder %d Bänder" + +#: libvips/foreign/tiff2vips.c:880 +#, c-format +msgid "not at least %d samples per pixel" +msgstr "" + +#: libvips/foreign/tiff2vips.c:895 +msgid "samples_per_pixel not a whole number of bytes" +msgstr "" + +#: libvips/foreign/tiff2vips.c:908 +#, fuzzy, c-format +msgid "not photometric interpretation %d" +msgstr "unbekannte fotometrische Deutung %d" + +#: libvips/foreign/tiff2vips.c:920 +#, c-format +msgid "not %d bits per sample" +msgstr "" + +#: libvips/foreign/tiff2vips.c:936 +#, c-format +msgid "%d bits per sample palette image not supported" +msgstr "%d Bit pro Musterfarbpalettenbild nicht unterstützt" + +#: libvips/foreign/tiff2vips.c:995 +#, fuzzy +msgid "unsupported tiff image type\n" +msgstr "nicht unterstützter Bildtyp %d" + +#: libvips/foreign/tiff2vips.c:1603 +msgid "bad colormap" +msgstr "falsche Farbzusammenstellung" + +#: libvips/foreign/tiff2vips.c:2330 +#, c-format +msgid "decompress error tile %d x %d" +msgstr "" + +#: libvips/foreign/tiff2vips.c:2608 +#, fuzzy +msgid "tiled separate planes not supported" +msgstr "Datentyp %d nicht unterstützt" + +#: libvips/foreign/tiff2vips.c:2627 libvips/foreign/tiff2vips.c:2910 +#: libvips/foreign/tiff2vips.c:3034 +#, fuzzy +msgid "unsupported tiff image type" +msgstr "nicht unterstützter Bildtyp %d" + +#: libvips/foreign/tiff2vips.c:2761 +#, c-format +msgid "out of order read -- at line %d, but line %d requested" +msgstr "" + +#: libvips/foreign/tiff2vips.c:3070 +#, fuzzy +msgid "subsampled images not supported" +msgstr "%d-dimensionale Bilder nicht unterstützt" + +#: libvips/foreign/tiff2vips.c:3082 +msgid "not SGI-compressed LOGLUV" +msgstr "" + +#: libvips/foreign/tiff2vips.c:3099 +#, fuzzy +msgid "width/height out of range" +msgstr "Parameter außerhalb des Bereichs" + +#: libvips/foreign/tiff2vips.c:3108 +#, fuzzy +msgid "samples out of range" +msgstr "Parameter außerhalb des Bereichs" + +#: libvips/foreign/tiff2vips.c:3194 libvips/foreign/tiff2vips.c:3222 +#, fuzzy +msgid "tile size out of range" +msgstr "Parameter außerhalb des Bereichs" + +#: libvips/foreign/tiff2vips.c:3414 +#, c-format +msgid "page %d differs from page %d" +msgstr "" + +#: libvips/foreign/tiff.c:207 libvips/foreign/tiff.c:222 +#, fuzzy +msgid "unable to open source for input" +msgstr "»%s« kann nicht zur Eingabe geöffnet werden" + +#: libvips/foreign/tiff.c:330 libvips/foreign/tiff.c:345 +#, fuzzy +msgid "unable to open target for output" +msgstr "»%s« kann nicht zur Ausgabe geöffnet werden" + +#: libvips/foreign/tiffload.c:183 +#, fuzzy +msgid "load tiff" +msgstr "TIFF aus Datei laden" + +#: libvips/foreign/tiffload.c:211 +msgid "Rotate image using orientation tag" +msgstr "" + +#: libvips/foreign/tiffload.c:217 +msgid "subifd" +msgstr "" + +#: libvips/foreign/tiffload.c:218 +msgid "Subifd index" +msgstr "" + +#: libvips/foreign/tiffload.c:294 +#, fuzzy +msgid "load tiff from source" +msgstr "TIFF aus Datei laden" + +#: libvips/foreign/tiffload.c:374 +msgid "load tiff from file" +msgstr "TIFF aus Datei laden" + +#: libvips/foreign/tiffload.c:454 +#, fuzzy +msgid "load tiff from buffer" +msgstr "TIFF aus Datei laden" + +#: libvips/foreign/tiffsave.c:248 +#, fuzzy +msgid "save image as tiff" +msgstr "Bild in TIFF-Datei speichern" + +#: libvips/foreign/tiffsave.c:258 +msgid "Compression for this file" +msgstr "Komprimierung für diese Datei" + +# http://de.wikipedia.org/wiki/Abhängige_und_unabhängige_Variable +#: libvips/foreign/tiffsave.c:272 +#, fuzzy +msgid "Predictor" +msgstr "Prädiktor" + +#: libvips/foreign/tiffsave.c:273 +msgid "Compression prediction" +msgstr "Prognose der Komprimierung" + +#: libvips/foreign/tiffsave.c:280 +msgid "Tile" +msgstr "Kachel" + +#: libvips/foreign/tiffsave.c:281 +msgid "Write a tiled tiff" +msgstr "ein gekacheltes TIFF schreiben" + +#: libvips/foreign/tiffsave.c:301 +msgid "Pyramid" +msgstr "Pyramide" + +#: libvips/foreign/tiffsave.c:302 +msgid "Write a pyramidal tiff" +msgstr "ein pyramidenförmiges TIFF schreiben" + +#: libvips/foreign/tiffsave.c:308 +msgid "Miniswhite" +msgstr "" + +#: libvips/foreign/tiffsave.c:309 +msgid "Use 0 for white in 1-bit images" +msgstr "" + +#: libvips/foreign/tiffsave.c:316 +#, fuzzy +msgid "Write as a 1, 2, 4 or 8 bit image" +msgstr "ein BigTIFF-Bild schreiben" + +#: libvips/foreign/tiffsave.c:322 libvips/foreign/tiffsave.c:323 +msgid "Resolution unit" +msgstr "Einheit der Auflösung" + +# http://de.wikipedia.org/wiki/Liste_von_Dateinamenserweiterungen/T +#: libvips/foreign/tiffsave.c:343 +msgid "Bigtiff" +msgstr "BigTIFF" + +#: libvips/foreign/tiffsave.c:344 +msgid "Write a bigtiff image" +msgstr "ein BigTIFF-Bild schreiben" + +#: libvips/foreign/tiffsave.c:351 +msgid "Write a properties document to IMAGEDESCRIPTION" +msgstr "" + +#: libvips/foreign/tiffsave.c:365 +msgid "Deflate (1-9, default 6) or ZSTD (1-22, default 9) compression level" +msgstr "" + +#: libvips/foreign/tiffsave.c:372 +#, fuzzy +msgid "Enable WEBP lossless mode" +msgstr "»fd« kann nicht geschlossen werden" + +#: libvips/foreign/tiffsave.c:385 +msgid "Sub-IFD" +msgstr "" + +#: libvips/foreign/tiffsave.c:386 +msgid "Save pyr layers as sub-IFDs" +msgstr "" + +#: libvips/foreign/tiffsave.c:392 +msgid "Premultiply" +msgstr "" + +#: libvips/foreign/tiffsave.c:393 +msgid "Save with premultiplied alpha" +msgstr "" + +#: libvips/foreign/tiffsave.c:399 +msgid "RGB JPEG" +msgstr "" + +#: libvips/foreign/tiffsave.c:400 +msgid "Output RGB JPEG rather than YCbCr" +msgstr "" + +#: libvips/foreign/tiffsave.c:407 +msgid "Squash images down to 1 bit" +msgstr "Bilder auf ein Bit zusammenquetschen" + +#: libvips/foreign/tiffsave.c:470 +#, fuzzy +msgid "save image to tiff target" +msgstr "Bild in TIFF-Datei speichern" + +#: libvips/foreign/tiffsave.c:523 +msgid "save image to tiff file" +msgstr "Bild in TIFF-Datei speichern" + +#: libvips/foreign/tiffsave.c:584 +#, fuzzy +msgid "save image to tiff buffer" +msgstr "Bild in TIFF-Datei speichern" + +#: libvips/foreign/vips2jpeg.c:176 +#, c-format +msgid "%s" +msgstr "%s" + +#: libvips/foreign/vips2jpeg.c:273 +#, c-format +msgid "field \"%s\" is too large for a single JPEG marker, ignoring" +msgstr "" + +#: libvips/foreign/vips2jpeg.c:1059 +#, fuzzy +msgid "libvips built without JPEG support" +msgstr "VIPS wurde ohne FFT-Unterstützung konfiguriert" + +#: libvips/foreign/vips2magick.c:319 +#, fuzzy +msgid "unsupported image format" +msgstr "nicht unterstützter Bildtyp %d" + +#: libvips/foreign/vips2magick.c:349 +#, fuzzy +msgid "unsupported number of image bands" +msgstr "nicht unterstützter Bildtyp %d" + +#: libvips/foreign/vips2magick.c:464 +#, fuzzy +msgid "save with ImageMagick" +msgstr "Datei mit ImageMagick laden" + +#: libvips/foreign/vips2magick.c:490 +#, fuzzy +msgid "Quality to use" +msgstr "kann nicht gesucht werden" + +#: libvips/foreign/vips2magick.c:496 +msgid "Optimize_gif_frames" +msgstr "" + +#: libvips/foreign/vips2magick.c:497 +msgid "Apply GIF frames optimization" +msgstr "" + +#: libvips/foreign/vips2magick.c:503 +msgid "Optimize_gif_transparency" +msgstr "" + +#: libvips/foreign/vips2magick.c:504 +msgid "Apply GIF transparency optimization" +msgstr "" + +#: libvips/foreign/vips2magick.c:574 +#, fuzzy +msgid "save file with ImageMagick" +msgstr "Datei mit ImageMagick laden" + +#: libvips/foreign/vips2magick.c:646 +#, fuzzy +msgid "save image to magick buffer" +msgstr "Bild in den PNG-Puffer speichern" + +#: libvips/foreign/vips2magick.c:677 +#, fuzzy +msgid "save bmp image with ImageMagick" +msgstr "Datei mit ImageMagick laden" + +#: libvips/foreign/vips2magick.c:710 +#, fuzzy +msgid "save bmp image to magick buffer" +msgstr "Bild in den PNG-Puffer speichern" + +#: libvips/foreign/vips2magick.c:743 +#, fuzzy +msgid "save gif image with ImageMagick" +msgstr "Datei mit ImageMagick laden" + +#: libvips/foreign/vips2magick.c:776 +#, fuzzy +msgid "save gif image to magick buffer" +msgstr "Bild in den PNG-Puffer speichern" + +#: libvips/foreign/vips2tiff.c:1449 +msgid "can only pyramid LABQ and non-complex images" +msgstr "" +"nur LABQ und nicht-komplexe Bilder können pyramidenartig verwendet werden" + +#: libvips/foreign/vips2tiff.c:1472 +msgid "tile size not a multiple of 16" +msgstr "Bildgröße kein Vielfaches von 16" + +#: libvips/foreign/vips2tiff.c:1830 libvips/foreign/vips2tiff.c:2019 +msgid "TIFF write tile failed" +msgstr "Schreiben des TIFF-Bildes fehlgeschlagen" + +#: libvips/foreign/vipsload.c:126 +msgid "no filename associated with source" +msgstr "" + +#: libvips/foreign/vipsload.c:157 +#, fuzzy +msgid "load vips base class" +msgstr "Basisklasse" + +#: libvips/foreign/vipsload.c:228 +msgid "load vips from file" +msgstr "Vips aus einer Datei laden" + +#: libvips/foreign/vipsload.c:303 +#, fuzzy +msgid "load vips from source" +msgstr "Vips aus einer Datei laden" + +#: libvips/foreign/vipspng.c:450 +msgid "unsupported color type" +msgstr "nicht unterstützter Farbtyp" + +#: libvips/foreign/vipspng.c:564 +#, fuzzy +msgid "unable to read PNG header" +msgstr "Kopfdaten für »%s« können nicht gelesen werden" + +#: libvips/foreign/vipspng.c:756 +#, fuzzy +msgid "libpng read error" +msgstr "Lesefehler" + +#: libvips/foreign/vipspng.c:1113 +msgid "compress should be in [0,9]" +msgstr "Komprimierung sollte in [0,9] liegen" + +#: libvips/foreign/vipspng.c:1141 +#, c-format +msgid "can't save %d band image as png" +msgstr "" + +#: libvips/foreign/vipspng.c:1349 +#, fuzzy, c-format +msgid "unable to write to target %s" +msgstr "auf »%s« kann nicht geschrieben werden" + +#: libvips/foreign/vipssave.c:114 +#, fuzzy +msgid "no filename associated with target" +msgstr "dieses zugehörige Bild laden" + +#: libvips/foreign/vipssave.c:141 +#, fuzzy +msgid "save vips base class" +msgstr "Basisklasse" + +#: libvips/foreign/vipssave.c:193 +#, fuzzy +msgid "save image to file in vips format" +msgstr "Bild in Vips-Datei speichern" + +#: libvips/foreign/vipssave.c:249 +#, fuzzy +msgid "save image to target in vips format" +msgstr "Bild in Vips-Datei speichern" + +#: libvips/foreign/webp2vips.c:407 +#, fuzzy +msgid "unable to parse image" +msgstr "es kann nicht zu einem %s-Bild ausgegeben werden" + +#: libvips/foreign/webp2vips.c:595 +#, fuzzy +msgid "unable to loop through frames" +msgstr "es kann nicht zu einem %s-Bild ausgegeben werden" + +#: libvips/foreign/webpload.c:164 +#, fuzzy +msgid "load webp" +msgstr "JPEG laden" + +# Portable Pixmap +#: libvips/foreign/webpload.c:258 +#, fuzzy +msgid "load webp from source" +msgstr "PPM aus Datei laden" + +# Portable Pixmap +#: libvips/foreign/webpload.c:338 +#, fuzzy +msgid "load webp from file" +msgstr "PPM aus Datei laden" + +#: libvips/foreign/webpload.c:418 +#, fuzzy +msgid "load webp from buffer" +msgstr "JPEG aus Puffer laden" + +#: libvips/foreign/webpsave.c:248 +#, fuzzy +msgid "picture version error" +msgstr "Version ausgeben" + +#: libvips/foreign/webpsave.c:290 +msgid "picture memory error" +msgstr "" + +#: libvips/foreign/webpsave.c:315 +#, fuzzy +msgid "anim add error" +msgstr "Lesefehler" + +#: libvips/foreign/webpsave.c:332 +#, fuzzy +msgid "unable to encode" +msgstr "kann nicht gesucht werden" + +#: libvips/foreign/webpsave.c:428 +#, fuzzy +msgid "chunk add error" +msgstr "Lesefehler" + +#: libvips/foreign/webpsave.c:534 libvips/foreign/webpsave.c:575 +#, fuzzy +msgid "mux error" +msgstr "Unix-Fehler" + +#: libvips/foreign/webpsave.c:595 libvips/foreign/webpsave.c:605 +#: libvips/foreign/webpsave.c:644 +#, fuzzy +msgid "config version error" +msgstr "Umwandlungstransaktionen" + +#: libvips/foreign/webpsave.c:625 +msgid "invalid configuration" +msgstr "" + +#: libvips/foreign/webpsave.c:655 +#, fuzzy +msgid "unable to init animation" +msgstr "kann nicht gekürzt werden" + +#: libvips/foreign/webpsave.c:698 +#, fuzzy +msgid "anim close error" +msgstr "XML-Fehler beim Speichern" + +#: libvips/foreign/webpsave.c:703 +#, fuzzy +msgid "anim build error" +msgstr "Lesefehler" + +#: libvips/foreign/webpsave.c:711 libvips/mosaicing/lrmerge.c:309 +#: libvips/mosaicing/tbmerge.c:187 libvips/mosaicing/tbmerge.c:262 +#: libvips/mosaicing/tbmerge.c:594 +msgid "internal error" +msgstr "interner Fehler" + +#: libvips/foreign/webpsave.c:817 +#, fuzzy +msgid "save as WebP" +msgstr "Bild als ASCII speichern" + +#: libvips/foreign/webpsave.c:840 +msgid "Preset" +msgstr "" + +#: libvips/foreign/webpsave.c:841 +msgid "Preset for lossy compression" +msgstr "" + +#: libvips/foreign/webpsave.c:848 +msgid "Smart subsampling" +msgstr "" + +#: libvips/foreign/webpsave.c:849 +msgid "Enable high quality chroma subsampling" +msgstr "" + +#: libvips/foreign/webpsave.c:855 +msgid "Near lossless" +msgstr "" + +#: libvips/foreign/webpsave.c:856 +msgid "Enable preprocessing in lossless mode (uses Q)" +msgstr "" + +#: libvips/foreign/webpsave.c:862 +msgid "Alpha quality" +msgstr "" + +#: libvips/foreign/webpsave.c:863 +msgid "Change alpha plane fidelity for lossy compression" +msgstr "" + +#: libvips/foreign/webpsave.c:869 +msgid "Minimise size" +msgstr "" + +#: libvips/foreign/webpsave.c:870 +msgid "Optimise for minimum size" +msgstr "" + +#: libvips/foreign/webpsave.c:876 +msgid "Minimum keyframe spacing" +msgstr "" + +#: libvips/foreign/webpsave.c:877 +#, fuzzy +msgid "Minimum number of frames between key frames" +msgstr "maximale Anzahl von Kacheln, die zwischengespeichert werden soll" + +#: libvips/foreign/webpsave.c:883 +msgid "Maximum keyframe spacing" +msgstr "" + +#: libvips/foreign/webpsave.c:884 +#, fuzzy +msgid "Maximum number of frames between key frames" +msgstr "maximale Anzahl von Kacheln, die zwischengespeichert werden soll" + +#: libvips/foreign/webpsave.c:891 libvips/foreign/webpsave.c:912 +msgid "Level of CPU effort to reduce file size" +msgstr "" + +#: libvips/foreign/webpsave.c:897 +#, fuzzy +msgid "Target size" +msgstr "falsche Bildgröße" + +#: libvips/foreign/webpsave.c:898 +msgid "Desired target size in bytes" +msgstr "" + +#: libvips/foreign/webpsave.c:904 +msgid "Passes" +msgstr "" + +#: libvips/foreign/webpsave.c:905 +msgid "Number of entropy-analysis passes (in [1..10])" +msgstr "" + +#: libvips/foreign/webpsave.c:911 +msgid "Reduction effort" +msgstr "" + +#: libvips/foreign/webpsave.c:918 +#, fuzzy +msgid "Mixed encoding" +msgstr "Bildpunktkodierung" + +#: libvips/foreign/webpsave.c:919 +msgid "Allow mixed encoding (might reduce file size)" +msgstr "" + +#: libvips/foreign/webpsave.c:925 +msgid "Smart deblocking" +msgstr "" + +#: libvips/foreign/webpsave.c:926 +msgid "Enable auto-adjusting of the deblocking filter" +msgstr "" + +# http://de.wikipedia.org/wiki/MIME#image +#: libvips/foreign/webpsave.c:1156 +#, fuzzy +msgid "save image to webp mime" +msgstr "Bild in JPEG-MIME speichern" + +#: libvips/freqfilt/freqfilt.c:94 +#, fuzzy +msgid "frequency-domain filter operations" +msgstr "unäre Transaktionen" + +#: libvips/freqfilt/freqmult.c:126 +msgid "frequency-domain filtering" +msgstr "" + +#: libvips/freqfilt/freqmult.c:131 +#, fuzzy +msgid "Input mask image" +msgstr "Eingabebild" + +#: libvips/freqfilt/fwfft.c:145 libvips/freqfilt/fwfft.c:266 +#: libvips/freqfilt/invfft.c:124 libvips/freqfilt/invfft.c:203 +msgid "unable to create transform plan" +msgstr "Umwandlungsplan kann nicht erstellt werden" + +#: libvips/freqfilt/fwfft.c:351 +msgid "forward FFT" +msgstr "" + +#: libvips/freqfilt/invfft.c:263 +msgid "inverse FFT" +msgstr "" + +#: libvips/freqfilt/invfft.c:267 +msgid "Real" +msgstr "" + +#: libvips/freqfilt/invfft.c:268 +msgid "Output only the real part of the transform" +msgstr "" + +#: libvips/freqfilt/phasecor.c:107 +msgid "calculate phase correlation" +msgstr "" + +#: libvips/freqfilt/spectrum.c:100 +msgid "make displayable power spectrum" +msgstr "" + +#: libvips/histogram/case.c:164 +#, fuzzy +msgid "bad number of cases" +msgstr "falsche Achsenanzahl %d" + +#: libvips/histogram/case.c:169 +#, fuzzy +msgid "index image not 1-band" +msgstr "»ink«-Bild nicht 1x1 Bildpunkte" + +#: libvips/histogram/case.c:233 +msgid "use pixel values to pick cases from an array of images" +msgstr "" + +#: libvips/histogram/case.c:245 +msgid "Cases" +msgstr "" + +#: libvips/histogram/case.c:246 +#, fuzzy +msgid "Array of case images" +msgstr "Feld von Eingabebildern" + +#: libvips/histogram/hist_cum.c:158 +msgid "form cumulative histogram" +msgstr "" + +#: libvips/histogram/hist_entropy.c:107 +msgid "estimate image entropy" +msgstr "" + +#: libvips/histogram/hist_entropy.c:112 +#: libvips/histogram/hist_ismonotonic.c:119 +#, fuzzy +msgid "Input histogram image" +msgstr "Eingabebild" + +#: libvips/histogram/hist_equal.c:110 +msgid "histogram equalisation" +msgstr "" + +#: libvips/histogram/hist_equal.c:127 +msgid "Equalise with this band" +msgstr "" + +#: libvips/histogram/hist_ismonotonic.c:114 +msgid "test for monotonicity" +msgstr "" + +#: libvips/histogram/hist_ismonotonic.c:124 +msgid "Monotonic" +msgstr "" + +#: libvips/histogram/hist_ismonotonic.c:125 +msgid "true if in is monotonic" +msgstr "" + +#: libvips/histogram/hist_local.c:304 libvips/histogram/stdif.c:236 +#: libvips/morphology/rank.c:491 +msgid "window too large" +msgstr "Fenster zu groß" + +#: libvips/histogram/hist_local.c:355 +msgid "local histogram equalisation" +msgstr "" + +#: libvips/histogram/hist_local.c:374 libvips/histogram/stdif.c:309 +#: libvips/morphology/rank.c:571 +#, fuzzy +msgid "Window width in pixels" +msgstr "Kachelbreite in Bildpunkten" + +#: libvips/histogram/hist_local.c:381 libvips/histogram/stdif.c:316 +#: libvips/morphology/rank.c:578 +#, fuzzy +msgid "Window height in pixels" +msgstr "Kachelhöhe in Bildpunkten" + +#: libvips/histogram/hist_local.c:387 +#, fuzzy +msgid "Max slope" +msgstr "Kacheln maximal" + +#: libvips/histogram/hist_local.c:388 +msgid "Maximum slope (CLAHE)" +msgstr "" + +#: libvips/histogram/hist_match.c:154 +msgid "match two histograms" +msgstr "" + +#: libvips/histogram/hist_match.c:162 +#, fuzzy +msgid "Input histogram" +msgstr "Eingabebild" + +#: libvips/histogram/hist_match.c:167 libvips/mosaicing/match.c:196 +#: libvips/mosaicing/merge.c:122 libvips/mosaicing/mosaic1.c:498 +#: libvips/mosaicing/mosaic.c:179 +msgid "Reference" +msgstr "" + +#: libvips/histogram/hist_match.c:168 +msgid "Reference histogram" +msgstr "" + +#: libvips/histogram/hist_norm.c:137 +msgid "normalise histogram" +msgstr "" + +#: libvips/histogram/histogram.c:223 +#, fuzzy +msgid "histogram operations" +msgstr "binäre Transaktionen" + +#: libvips/histogram/hist_plot.c:329 +msgid "plot histogram" +msgstr "" + +#: libvips/histogram/hist_unary.c:84 +#, fuzzy +msgid "hist_unary operations" +msgstr "unäre Transaktionen" + +#: libvips/histogram/maplut.c:110 +#, c-format +msgid "%d overflows detected" +msgstr "%d Überläufe entdeckt" + +#: libvips/histogram/maplut.c:738 +msgid "map an image though a lut" +msgstr "" + +#: libvips/histogram/maplut.c:756 +msgid "LUT" +msgstr "" + +#: libvips/histogram/maplut.c:757 +#, fuzzy +msgid "Look-up table image" +msgstr "ein Bild kopieren" + +#: libvips/histogram/maplut.c:763 +msgid "Apply one-band lut to this band of in" +msgstr "" + +#: libvips/histogram/percent.c:105 +msgid "find threshold for percent of pixels" +msgstr "" + +#: libvips/histogram/percent.c:115 +msgid "Percent" +msgstr "" + +#: libvips/histogram/percent.c:116 +#, fuzzy +msgid "Percent of pixels" +msgstr "Einheitsvektor von Bildpunkten" + +#: libvips/histogram/percent.c:123 +msgid "Threshold above which lie percent of pixels" +msgstr "" + +#: libvips/histogram/stdif.c:240 +#, fuzzy +msgid "too many bands" +msgstr "zu viele Argumente" + +#: libvips/histogram/stdif.c:290 +msgid "statistical difference" +msgstr "" + +#: libvips/histogram/stdif.c:322 +#, fuzzy +msgid "Mean weight" +msgstr "Kachelhöhe" + +#: libvips/histogram/stdif.c:323 +#, fuzzy +msgid "Weight of new mean" +msgstr "Höhe des extrahierten Bereichs" + +#: libvips/histogram/stdif.c:330 +msgid "New mean" +msgstr "" + +#: libvips/histogram/stdif.c:336 +msgid "Deviation weight" +msgstr "" + +#: libvips/histogram/stdif.c:337 +msgid "Weight of new deviation" +msgstr "" + +#: libvips/histogram/stdif.c:343 +#, fuzzy +msgid "Deviation" +msgstr "Beschreibung" + +#: libvips/histogram/stdif.c:344 +msgid "New deviation" +msgstr "" + +#: libvips/iofuncs/buf.c:609 +#, c-format +msgid "%zd bytes of binary data" +msgstr "" + +#: libvips/iofuncs/connection.c:126 +#, fuzzy +msgid "Descriptor" +msgstr "Beschreibung" + +#: libvips/iofuncs/connection.c:127 +#, fuzzy +msgid "File descriptor for read or write" +msgstr "Datei-Deskriptor, in den geschrieben werden soll" + +#: libvips/iofuncs/connection.c:134 +#, fuzzy +msgid "Name of file to open" +msgstr "falscher Dateityp" + +#: libvips/iofuncs/error.c:296 +#, fuzzy +msgid "system error" +msgstr "Lesefehler" + +#: libvips/iofuncs/error.c:443 +msgid "image must be uncoded" +msgstr "Bild muss unkodiert sein" + +#: libvips/iofuncs/error.c:471 +#, fuzzy +msgid "image coding must be 'none' or 'labq'" +msgstr "Bildkodierung muss NONE oder LABQ sein" + +#: libvips/iofuncs/error.c:499 +msgid "unknown image coding" +msgstr "unbekannte Bildkodierung" + +#: libvips/iofuncs/error.c:524 +#, fuzzy, c-format +msgid "coding '%s' only" +msgstr "Nur LABQ-Kodierung" + +#: libvips/iofuncs/error.c:549 +msgid "image must one band" +msgstr "Bild muss ein Band haben" + +#: libvips/iofuncs/error.c:574 +#, c-format +msgid "image must have %d bands" +msgstr "Bild muss %d Bänder haben" + +#: libvips/iofuncs/error.c:599 +msgid "image must have one or three bands" +msgstr "Bild muss ein oder drei Bänder haben" + +#: libvips/iofuncs/error.c:625 +#, fuzzy, c-format +msgid "image must have at least %d bands" +msgstr "Bild muss %d Bänder haben" + +#: libvips/iofuncs/error.c:653 +msgid "images must have the same number of bands, or one must be single-band" +msgstr "" +"Bilder müssen die gleiche Anzahl Bänder haben oder eines muss ein Band haben" + +#: libvips/iofuncs/error.c:680 +#, c-format +msgid "image must have 1 or %d bands" +msgstr "Bild muss ein oder %d Bänder haben" + +#: libvips/iofuncs/error.c:704 +msgid "image must be non-complex" +msgstr "Bild muss nicht-komplex sein" + +#: libvips/iofuncs/error.c:728 +msgid "image must be complex" +msgstr "Bild muss komplex sein" + +#: libvips/iofuncs/error.c:755 +#, fuzzy +msgid "image must be two-band or complex" +msgstr "Bild muss nicht-komplex sein" + +#: libvips/iofuncs/error.c:781 +#, c-format +msgid "image must be %s" +msgstr "Bild muss %s sein" + +#: libvips/iofuncs/error.c:806 +msgid "image must be integer" +msgstr "Bild muss ganzzahlig sein" + +#: libvips/iofuncs/error.c:831 +msgid "image must be unsigned integer" +msgstr "Bild muss aus vorzeichenlosen Ganzzahlen bestehen" + +#: libvips/iofuncs/error.c:859 +msgid "image must be 8- or 16-bit integer, signed or unsigned" +msgstr "" +"Bild muss aus 8- oder 16-Bit Ganzzahlen mit oder ohne Vorzeichen bestehen" + +#: libvips/iofuncs/error.c:885 +msgid "image must be 8- or 16-bit unsigned integer" +msgstr "Bild muss aus 8- oder 16-Bit vorzeichenlosen Ganzzahlen bestehen" + +#: libvips/iofuncs/error.c:911 +msgid "image must be 8- or 16-bit unsigned integer, or float" +msgstr "" +"Bild muss aus 8- oder 16-Bit vorzeichenlosen Ganzzahlen oder " +"Fließkommazahlen bestehen" + +#: libvips/iofuncs/error.c:938 +msgid "image must be unsigned int or float" +msgstr "" +"Bild muss aus 8- oder 16-Bit vorzeichenlosen Ganz- oder Fließkommazahlen " +"bestehen" + +#: libvips/iofuncs/error.c:964 +msgid "images must match in size" +msgstr "Bilder müssen in der Größe passen" + +#: libvips/iofuncs/error.c:990 +#, fuzzy +msgid "images must be odd and square" +msgstr "Bild muss %d Bänder haben" + +#: libvips/iofuncs/error.c:1016 +msgid "images must have the same number of bands" +msgstr "Bilder müssen die gleiche Anzahl Bänder haben" + +#: libvips/iofuncs/error.c:1070 +msgid "images must have the same band format" +msgstr "Bilder müssen das gleiche Bandformat haben" + +#: libvips/iofuncs/error.c:1096 +msgid "images must have the same coding" +msgstr "Bilder müssen die gleiche Kodierung haben" + +#: libvips/iofuncs/error.c:1119 +#, fuzzy, c-format +msgid "vector must have %d elements" +msgstr "Vektor muss 1 oder %d Elemente haben" + +#: libvips/iofuncs/error.c:1155 +#, fuzzy +msgid "vector must have 1 element" +msgstr "Vektor muss 1 oder %d Elemente haben" + +#: libvips/iofuncs/error.c:1158 +#, c-format +msgid "vector must have 1 or %d elements" +msgstr "Vektor muss 1 oder %d Elemente haben" + +#: libvips/iofuncs/error.c:1183 +msgid "histograms must have width or height 1" +msgstr "Histogramme müssen eine Breite oder Höhe von eins haben" + +#: libvips/iofuncs/error.c:1188 +msgid "histograms must have not have more than 65536 elements" +msgstr "Histogramm dürfen nicht mehr als 65536 Elemente haben" + +#: libvips/iofuncs/error.c:1224 +#, fuzzy +msgid "matrix image too large" +msgstr "Zoomfaktoren zu groß" + +#: libvips/iofuncs/error.c:1229 +#, fuzzy +msgid "matrix image must have one band" +msgstr "Bild muss %d Bänder haben" + +#: libvips/iofuncs/error.c:1263 +#, fuzzy +msgid "separable matrix images must have width or height 1" +msgstr "Histogramme müssen eine Breite oder Höhe von eins haben" + +#: libvips/iofuncs/error.c:1289 +#, fuzzy +msgid "precision must be int or float" +msgstr "" +"Bild muss aus 8- oder 16-Bit vorzeichenlosen Ganz- oder Fließkommazahlen " +"bestehen" + +#: libvips/iofuncs/generate.c:696 +msgid "demand hint not set" +msgstr "Hinweisanfrage nicht gesetzt" + +#: libvips/iofuncs/generate.c:715 libvips/iofuncs/generate.c:743 +msgid "generate() called twice" +msgstr "generate() zweimal aufgerufen" + +#: libvips/iofuncs/generate.c:784 libvips/iofuncs/image.c:3235 +#, c-format +msgid "unable to output to a %s image" +msgstr "es kann nicht zu einem %s-Bild ausgegeben werden" + +#: libvips/iofuncs/ginputsource.c:164 libvips/iofuncs/ginputsource.c:229 +#, c-format +msgid "Error while seeking: %s" +msgstr "" + +#: libvips/iofuncs/ginputsource.c:185 +msgid "Cannot truncate VipsGInputStream" +msgstr "" + +#: libvips/iofuncs/ginputsource.c:206 +#, fuzzy, c-format +msgid "Error while reading: %s" +msgstr "Fehler beim Lesen von XML: %s" + +#: libvips/iofuncs/ginputsource.c:275 +msgid "Stream to wrap" +msgstr "" + +#: libvips/iofuncs/header.c:1380 +#, c-format +msgid "field \"%s\" not found" +msgstr "Feld »%s« nicht gefunden" + +#: libvips/iofuncs/header.c:1614 +#, c-format +msgid "field \"%s\" is of type %s, not %s" +msgstr "Feld »%s« ist vom Typ %s, nicht %s" + +#: libvips/iofuncs/header.c:1888 +#, fuzzy, c-format +msgid "field \"%s\" is of type %s, not VipsRefString" +msgstr "Feld »%s« ist vom Typ %s, nicht %s" + +#: libvips/iofuncs/image.c:539 +msgid "unable to close fd" +msgstr "»fd« kann nicht geschlossen werden" + +#: libvips/iofuncs/image.c:762 +#, fuzzy, c-format +msgid "%s %s: %d x %d pixels, %d threads, %d x %d tiles, %d lines in buffer" +msgstr "%s %s: %d Threads, %d x %d Kacheln, Gruppen von %d Scan-Zeilen" + +#: libvips/iofuncs/image.c:775 +#, c-format +msgid "%s %s: %d%% complete" +msgstr "%s %s: %d%% komplett" + +#: libvips/iofuncs/image.c:794 +#, fuzzy, c-format +msgid "%s %s: done in %.3gs \n" +msgstr "%s %s: Erledigt in %ds \n" + +#: libvips/iofuncs/image.c:976 +#, c-format +msgid "unable to open \"%s\", file too short" +msgstr "»%s« kann nicht geöffnet werden, Datei zu klein" + +#: libvips/iofuncs/image.c:985 +#, c-format +msgid "%s is longer than expected" +msgstr "%s ist länger als erwartet" + +#: libvips/iofuncs/image.c:1003 +#, c-format +msgid "bad mode \"%s\"" +msgstr "falscher Modus »%s«" + +#: libvips/iofuncs/image.c:1075 +msgid "image class" +msgstr "Bildklasse" + +#: libvips/iofuncs/image.c:1173 +msgid "Image filename" +msgstr "Bilddateiname" + +#: libvips/iofuncs/image.c:1180 +msgid "Open mode" +msgstr "Öffnen-Modus" + +#: libvips/iofuncs/image.c:1186 +msgid "Kill" +msgstr "töten" + +#: libvips/iofuncs/image.c:1187 +msgid "Block evaluation on this image" +msgstr "Blockauswertung dieses Bildes" + +#: libvips/iofuncs/image.c:1193 +msgid "Demand style" +msgstr "Nachfragestil" + +#: libvips/iofuncs/image.c:1194 +msgid "Preferred demand style for this image" +msgstr "für dieses Bild bevorzugter Nachfragestil" + +#: libvips/iofuncs/image.c:1207 +msgid "Foreign buffer" +msgstr "Fremdpuffer" + +#: libvips/iofuncs/image.c:1208 +msgid "Pointer to foreign pixels" +msgstr "Puffer für fremde Bildpunkte" + +#: libvips/iofuncs/image.c:1660 +#, c-format +msgid "killed for image \"%s\"" +msgstr "für Bild »%s« abgeschossen" + +#: libvips/iofuncs/image.c:2069 +msgid "memory area too small --- should be %" +msgstr "" + +#: libvips/iofuncs/image.c:2258 +#, fuzzy +msgid "unable to load source" +msgstr "Verlauf kann nicht gelesen werden" + +#: libvips/iofuncs/image.c:2369 +#, c-format +msgid "bad array length --- should be %d, you passed %d" +msgstr "" + +#: libvips/iofuncs/image.c:2886 libvips/iofuncs/image.c:2888 +#: libvips/iofuncs/memory.c:336 libvips/iofuncs/memory.c:338 +#: libvips/iofuncs/memory.c:409 libvips/iofuncs/memory.c:411 +#, c-format +msgid "out of memory --- size == %dMB" +msgstr "Hauptspeicher reicht nicht aus – Größe == %dMB" + +#: libvips/iofuncs/image.c:3179 +msgid "bad image descriptor" +msgstr "falscher Bild-Deskriptor" + +#: libvips/iofuncs/image.c:3298 +#, c-format +msgid "auto-rewind for %s failed" +msgstr "automatischer Rücklauf für %s fehlgeschlagen" + +#: libvips/iofuncs/image.c:3372 libvips/iofuncs/image.c:3502 +#: libvips/iofuncs/image.c:3679 +msgid "image not readable" +msgstr "Bild nicht lesbar" + +#: libvips/iofuncs/image.c:3417 libvips/iofuncs/image.c:3643 +msgid "no image data" +msgstr "keine Bilddaten" + +#: libvips/iofuncs/image.c:3523 libvips/iofuncs/image.c:3709 +#: libvips/iofuncs/image.c:3718 +msgid "image already written" +msgstr "Bild bereits geschrieben" + +#: libvips/iofuncs/image.c:3547 libvips/iofuncs/image.c:3730 +msgid "image not writeable" +msgstr "Bild nicht schreibbar" + +#: libvips/iofuncs/image.c:3602 +msgid "bad file type" +msgstr "falscher Dateityp" + +#: libvips/iofuncs/init.c:316 tools/vips.c:772 +#, fuzzy, c-format +msgid "unable to load \"%s\" -- %s" +msgstr "»mmap« nicht möglich: \"%s\" - %s" + +#: libvips/iofuncs/init.c:1270 +#, fuzzy +msgid "flag not in [0, 5]" +msgstr "Schalter nicht -1 oder 1" + +#: libvips/iofuncs/mapfile.c:189 libvips/iofuncs/mapfile.c:355 +msgid "unable to CreateFileMapping" +msgstr "»CreateFileMapping« nicht möglich" + +#: libvips/iofuncs/mapfile.c:196 libvips/iofuncs/mapfile.c:367 +msgid "unable to MapViewOfFile" +msgstr "»MapViewOfFile« nicht möglich" + +#: libvips/iofuncs/mapfile.c:235 +msgid "unable to mmap" +msgstr "»mmap« nicht möglich" + +#: libvips/iofuncs/mapfile.c:250 libvips/iofuncs/mapfile.c:361 +msgid "unable to UnmapViewOfFile" +msgstr "»UnmapViewOfFile« nicht möglich" + +#: libvips/iofuncs/mapfile.c:256 +msgid "unable to munmap file" +msgstr "»munmap« der Datei nicht möglich" + +#: libvips/iofuncs/mapfile.c:278 +msgid "file is less than 64 bytes" +msgstr "Datei ist weniger als 64 Byte groß" + +#: libvips/iofuncs/mapfile.c:283 libvips/iofuncs/mapfile.c:317 +msgid "unable to get file status" +msgstr "Dateistatus kann nicht abgefragt werden" + +#: libvips/iofuncs/mapfile.c:289 +msgid "not a regular file" +msgstr "keine reguläre Datei" + +#: libvips/iofuncs/mapfile.c:323 +msgid "unable to read data" +msgstr "Daten können nicht gelesen werden" + +#: libvips/iofuncs/mapfile.c:387 +#, c-format +msgid "unable to mmap: \"%s\" - %s" +msgstr "»mmap« nicht möglich: \"%s\" - %s" + +#: libvips/iofuncs/mapfile.c:398 +#, c-format +msgid "unable to mmap \"%s\" to same address" +msgstr "»mmap %s« zur gleichen Adresse nicht möglich" + +#: libvips/iofuncs/object.c:346 +#, c-format +msgid "parameter %s not set" +msgstr "Parameter %s nicht gesetzt" + +#: libvips/iofuncs/object.c:781 +#, c-format +msgid "no property named `%s'" +msgstr "keine Eigenschaft namens »%s«" + +#: libvips/iofuncs/object.c:787 +#, c-format +msgid "no vips argument named `%s'" +msgstr "kein VIPS-Argument namens »%s«" + +#: libvips/iofuncs/object.c:793 +#, c-format +msgid "argument `%s' has no instance" +msgstr "Argument »%s« hat keine Instanz" + +#: libvips/iofuncs/object.c:1533 libvips/iofuncs/operation.c:749 +#: libvips/resample/interpolate.c:659 +#, c-format +msgid "class \"%s\" not found" +msgstr "Klasse »%s« nicht gefunden" + +#: libvips/iofuncs/object.c:1584 +msgid "base class" +msgstr "Basisklasse" + +#: libvips/iofuncs/object.c:1598 +msgid "Nickname" +msgstr "Nickname" + +#: libvips/iofuncs/object.c:1599 +msgid "Class nickname" +msgstr "Klassen-Nickname" -#: libvips/foreign/openslideload.c:190 -msgid "Associated" -msgstr "dazugehörig" +#: libvips/iofuncs/object.c:1605 +msgid "Description" +msgstr "Beschreibung" -#: libvips/foreign/openslideload.c:191 -msgid "Load this associated image" -msgstr "dieses zugehörige Bild laden" +#: libvips/iofuncs/object.c:1606 +msgid "Class description" +msgstr "Klassenbeschreibung" -#: libvips/foreign/tiffload.c:130 -msgid "load tiff from file" -msgstr "TIFF aus Datei laden" +#: libvips/iofuncs/object.c:1844 +#, c-format +msgid "no value supplied for argument '%s'" +msgstr "" -#: libvips/foreign/tiffload.c:149 -msgid "Page" -msgstr "Seite" +#: libvips/iofuncs/object.c:1847 +#, c-format +msgid "no value supplied for argument '%s' ('%s')" +msgstr "" -#: libvips/foreign/tiffload.c:150 -msgid "Load this page from the file" -msgstr "diese Seite aus der Datei laden" +#: libvips/iofuncs/object.c:2039 libvips/iofuncs/object.c:2058 +#, fuzzy, c-format +msgid "'%s' is not an integer" +msgstr "»%s« ist keine positive Ganzzahl" -#: libvips/foreign/fitsload.c:107 -msgid "load a FITS image" -msgstr "ein FITS-Bild laden" +#: libvips/iofuncs/object.c:2481 +#, fuzzy, c-format +msgid "expected string or ), saw %s" +msgstr "%s erwartet, %s gesehen" -#: libvips/foreign/vipssave.c:114 -msgid "save image to vips file" -msgstr "Bild in Vips-Datei speichern" +#: libvips/iofuncs/object.c:2524 +#, c-format +msgid "unable to set '%s'" +msgstr "»%s« kann nicht gesetzt werden" -#: libvips/foreign/radsave.c:108 -msgid "save image to Radiance file" -msgstr "Bild in Radiance-Datei speichern" +#: libvips/iofuncs/object.c:2537 +msgid "not , or ) after parameter" +msgstr "kein »,« oder »)« nach Parameter" -#: libvips/foreign/openexrload.c:125 -msgid "load an OpenEXR image" -msgstr "ein OpenEXR-Bild laden" +#: libvips/iofuncs/object.c:2544 +msgid "extra tokens after ')'" +msgstr "keine zusätzlichen Token nach »)«" -#: libvips/foreign/analyzeload.c:114 -msgid "load an Analyze6 image" -msgstr "ein Analyze6-Bild laden" +#: libvips/iofuncs/operation.c:235 +#, c-format +msgid "%d pixels calculated" +msgstr "" -#: libvips/foreign/pngload.c:124 -msgid "load png from file" -msgstr "PNG-Datei aus Datei laden" +#: libvips/iofuncs/operation.c:343 +msgid "default enum" +msgstr "" -#: libvips/foreign/tiffsave.c:159 -msgid "save image to tiff file" -msgstr "Bild in TIFF-Datei speichern" +#: libvips/iofuncs/operation.c:347 +msgid "allowed enums" +msgstr "" -#: libvips/foreign/tiffsave.c:176 libvips/foreign/pngsave.c:103 -msgid "Compression" -msgstr "Komprimierung" +#: libvips/iofuncs/operation.c:375 +msgid "default flags" +msgstr "" -#: libvips/foreign/tiffsave.c:177 -msgid "Compression for this file" -msgstr "Komprimierung für diese Datei" +#: libvips/iofuncs/operation.c:380 +msgid "allowed flags" +msgstr "" -#: libvips/foreign/tiffsave.c:184 libvips/foreign/jpegsave.c:124 -msgid "Q" -msgstr "Q" +#: libvips/iofuncs/operation.c:396 libvips/iofuncs/operation.c:404 +#: libvips/iofuncs/operation.c:416 +msgid "default" +msgstr "" -#: libvips/foreign/tiffsave.c:185 libvips/foreign/jpegsave.c:125 -msgid "Q factor" -msgstr "Q-Faktor" +#: libvips/iofuncs/operation.c:407 libvips/iofuncs/operation.c:419 +#, fuzzy +msgid "min" +msgstr "in" -#: libvips/foreign/tiffsave.c:191 -# http://de.wikipedia.org/wiki/Abhängige_und_unabhängige_Variable -msgid "predictor" -msgstr "Prädiktor" +#: libvips/iofuncs/operation.c:409 libvips/iofuncs/operation.c:421 +msgid "max" +msgstr "" -#: libvips/foreign/tiffsave.c:192 -msgid "Compression prediction" -msgstr "Prognose der Komprimierung" +#: libvips/iofuncs/operation.c:618 +#, fuzzy +msgid "operation is blocked" +msgstr "Transaktionen" -#: libvips/foreign/tiffsave.c:199 libvips/foreign/jpegsave.c:131 -msgid "profile" -msgstr "Profil" +#: libvips/iofuncs/operation.c:664 +msgid "operations" +msgstr "Transaktionen" -#: libvips/foreign/tiffsave.c:200 libvips/foreign/jpegsave.c:132 -msgid "ICC profile to embed" -msgstr "einzubettendes ICC-Profil" +#: libvips/iofuncs/operation.c:755 +#, fuzzy, c-format +msgid "\"%s\" is not an instantiable class" +msgstr "»%s« ist kein bekanntes Dateiformat" -#: libvips/foreign/tiffsave.c:206 -msgid "Tile" -msgstr "Kachel" +#: libvips/iofuncs/operation.c:1225 +#, c-format +msgid "unknown argument '%s'" +msgstr "unbekanntes Argument »%s«" -#: libvips/foreign/tiffsave.c:207 -msgid "Write a tiled tiff" -msgstr "ein gekacheltes TIFF schreiben" +#: libvips/iofuncs/operation.c:1350 +msgid "too few arguments" +msgstr "zu wenige Argumente" -#: libvips/foreign/tiffsave.c:227 -msgid "Pyramid" -msgstr "Pyramide" +#: libvips/iofuncs/operation.c:1469 +msgid "too many arguments" +msgstr "zu viele Argumente" -#: libvips/foreign/tiffsave.c:228 -msgid "Write a pyramidal tiff" -msgstr "ein pyramidenförmiges TIFF schreiben" +#: libvips/iofuncs/region.c:565 libvips/iofuncs/region.c:635 +#: libvips/iofuncs/region.c:777 libvips/iofuncs/region.c:1848 +msgid "valid clipped to nothing" +msgstr "gültig an nichts angeklammert" -#: libvips/foreign/tiffsave.c:234 -msgid "Squash" -msgstr "quetschen" +#: libvips/iofuncs/region.c:675 +msgid "bad image type" +msgstr "falscher Bildtyp" -#: libvips/foreign/tiffsave.c:235 -msgid "Squash images down to 1 bit" -msgstr "Bilder auf ein Bit zusammenquetschen" +#: libvips/iofuncs/region.c:719 +msgid "no pixel data on attached image" +msgstr "keine Bildpunktdaten in angehängtem Bild" -#: libvips/foreign/tiffsave.c:241 libvips/foreign/tiffsave.c:242 -msgid "Resolution unit" -msgstr "Einheit der Auflösung" +#: libvips/iofuncs/region.c:725 +msgid "images do not match in pixel size" +msgstr "Bilder passen in der Bildpunktgröße nicht zusammen" -#: libvips/foreign/tiffsave.c:263 -# http://de.wikipedia.org/wiki/Liste_von_Dateinamenserweiterungen/T -msgid "Bigtiff" -msgstr "BigTIFF" +#: libvips/iofuncs/region.c:758 libvips/iofuncs/region.c:1830 +msgid "dest too small" +msgstr "Ziel zu klein" -#: libvips/foreign/tiffsave.c:264 -msgid "Write a bigtiff image" -msgstr "ein BigTIFF-Bild schreiben" +#: libvips/iofuncs/region.c:847 +msgid "bad position" +msgstr "falsche Position" + +#: libvips/iofuncs/region.c:1628 +#, fuzzy +msgid "stop requested" +msgstr "Fehler abgefragt" -#: libvips/foreign/csv.c:183 +#: libvips/iofuncs/region.c:1711 libvips/iofuncs/region.c:1901 #, c-format -msgid "error parsing number, line %d, column %d" -msgstr "Fehler beim Auswerten von Nummer, Zeile %d, Spalte %d" +msgid "unable to input from a %s image" +msgstr "Eingabe von einem %s-Bild nicht möglich" + +#: libvips/iofuncs/region.c:1735 +msgid "incomplete header" +msgstr "unvollständige Kopfzeilen" -#: libvips/foreign/csv.c:237 -msgid "end of file while skipping start" -msgstr "Dateiende während des Überspringens des Startes" +#: libvips/iofuncs/region.c:1804 +msgid "inappropriate region type" +msgstr "Ungeeigneter Regionstyp" -#: libvips/foreign/csv.c:246 libvips/iofuncs/util.c:1072 -#: libvips/iofuncs/util.c:1078 -msgid "unable to seek" -msgstr "kann nicht gesucht werden" +#: libvips/iofuncs/sbuf.c:85 +msgid "buffered source" +msgstr "" -#: libvips/foreign/csv.c:257 -msgid "empty line" -msgstr "leere Zeile" +#: libvips/iofuncs/sbuf.c:280 +#, fuzzy +msgid "end of file" +msgstr "ln des Bildes" -#: libvips/foreign/csv.c:301 +#: libvips/iofuncs/sink.c:262 #, c-format -msgid "unexpected EOF, line %d col %d" -msgstr "unerwartetes Dateiende, Zeile %d, Spalte %d" +msgid "stop function failed for image \"%s\"" +msgstr "»stop«-Funktion für Bild »%s« fehlgeschlagen" -#: libvips/foreign/csv.c:307 +#: libvips/iofuncs/sink.c:299 #, c-format -msgid "unexpected EOL, line %d col %d" -msgstr "unerwartetes Zeilenende, Zeile %d, Spalte %d" +msgid "start function failed for image \"%s\"" +msgstr "»start«-Funktion für Bild »%s« fehlgeschlagen" -#: libvips/foreign/vipsload.c:121 -msgid "load vips from file" -msgstr "Vips aus einer Datei laden" +#: libvips/iofuncs/sink.c:331 +msgid "per-thread state for sink" +msgstr "Status pro Thread für »sink«" -#: libvips/foreign/magickload.c:131 -msgid "load file with ImageMagick" -msgstr "Datei mit ImageMagick laden" +#: libvips/iofuncs/sinkdisc.c:108 libvips/iofuncs/util.c:477 +msgid "write failed" +msgstr "Schreiben fehlgeschlagen" -#: libvips/foreign/matload.c:116 -# http://www.dateiendung.com/format/mat -msgid "load mat from file" -msgstr "Mat aus Datei laden" +#: libvips/iofuncs/sinkdisc.c:137 +msgid "per-thread state for sinkdisc" +msgstr "Status pro Thread für »sinkdisc«" -#: libvips/foreign/jpegload.c:118 -#, c-format -msgid "bad shrink factor %d" +#: libvips/iofuncs/sinkmemory.c:109 +msgid "per-thread state for sinkmemory" +msgstr "Status pro Thread für »sinkmemory«" + +#: libvips/iofuncs/sinkscreen.c:196 +msgid "per-thread state for render" +msgstr "Status pro Thread für »render«" + +#: libvips/iofuncs/sinkscreen.c:1122 +msgid "bad parameters" +msgstr "falsche Parameter" + +#: libvips/iofuncs/source.c:281 libvips/iofuncs/target.c:114 +#, fuzzy +msgid "don't set 'filename' and 'descriptor'" +msgstr "kein Datei-Deskriptor" + +#: libvips/iofuncs/source.c:358 +msgid "input source" +msgstr "" + +#: libvips/iofuncs/source.c:366 libvips/iofuncs/target.c:304 +msgid "Blob" +msgstr "" + +#: libvips/iofuncs/source.c:367 +#, fuzzy +msgid "Blob to load from" +msgstr "Puffer, aus dem geladen werden soll" + +#: libvips/iofuncs/source.c:512 +#, fuzzy +msgid "unimplemented target" +msgstr "nicht implementierte Maske" + +#: libvips/iofuncs/source.c:649 +#, fuzzy +msgid "unable to open for read" +msgstr "Datei »%s« kann nicht zum Lesen geöffnet werden" + +#: libvips/iofuncs/source.c:890 +#, fuzzy +msgid "pipe too long" +msgstr "»%s« zu lang" + +#: libvips/iofuncs/source.c:1165 libvips/iofuncs/source.c:1190 +#: libvips/iofuncs/target.c:206 +msgid "bad 'whence'" +msgstr "" + +#: libvips/iofuncs/source.c:1211 +#, fuzzy +msgid "bad seek to %" msgstr "falscher Schrumpffaktor %d" -#: libvips/foreign/jpegload.c:140 -msgid "load jpeg" -msgstr "JPEG laden" +#: libvips/iofuncs/sourcecustom.c:173 +msgid "Custom source" +msgstr "" -#: libvips/foreign/jpegload.c:146 -msgid "Shrink" -msgstr "verkleinern" +#: libvips/iofuncs/sourceginput.c:219 +msgid "GInputStream source" +msgstr "" -#: libvips/foreign/jpegload.c:147 -msgid "Shrink factor on load" -msgstr "falscher Verkleinerungsfaktor %d" +#: libvips/iofuncs/sourceginput.c:227 +msgid "Stream" +msgstr "" -#: libvips/foreign/jpegload.c:153 -msgid "Fail" -msgstr "scheitern" +#: libvips/iofuncs/sourceginput.c:228 +#, fuzzy +msgid "GInputStream to read from" +msgstr "Name der Datei, aus der geladen werden soll" -#: libvips/foreign/jpegload.c:154 -msgid "Fail on first warning" -msgstr "scheitert bei erster Warnung" +#: libvips/iofuncs/system.c:185 +#, fuzzy +msgid "unable to substitute input filename" +msgstr "»munmap« der Datei nicht möglich" -#: libvips/foreign/jpegload.c:234 -msgid "load jpeg from file" -msgstr "JPEG aus Datei laden" +#: libvips/iofuncs/system.c:191 +#, fuzzy +msgid "unable to substitute output filename" +msgstr "es kann nicht zu einem %s-Bild ausgegeben werden" -#: libvips/foreign/jpegload.c:309 -msgid "load jpeg from buffer" -msgstr "JPEG aus Puffer laden" +#: libvips/iofuncs/system.c:226 +#, fuzzy, c-format +msgid "command \"%s\" failed" +msgstr "Befehl fehlgeschlagen: »%s«" -#: libvips/foreign/jpegload.c:315 libvips/foreign/jpegsave.c:260 -#: libvips/foreign/pngsave.c:228 -msgid "Buffer" -msgstr "Puffer" +#: libvips/iofuncs/system.c:234 +#, c-format +msgid "stderr output: %s" +msgstr "" -#: libvips/foreign/jpegload.c:316 -msgid "Buffer to load from" -msgstr "Puffer, aus dem geladen werden soll" +#: libvips/iofuncs/system.c:269 +msgid "run an external command" +msgstr "" -#: libvips/foreign/openslide2vips.c:134 -msgid "invalid associated image name" -msgstr "ungültiger zugehöriger Bildname" +#: libvips/iofuncs/system.c:290 +msgid "Command" +msgstr "" -#: libvips/foreign/openslide2vips.c:159 -msgid "failure opening slide" -msgstr "Fehler beim Öffnen des Dias" +#: libvips/iofuncs/system.c:291 +msgid "Command to run" +msgstr "" -#: libvips/foreign/openslide2vips.c:166 -msgid "invalid slide level" -msgstr "ungültige Diastufe" +#: libvips/iofuncs/system.c:297 +#, fuzzy +msgid "Input format" +msgstr "Eingabebild" + +#: libvips/iofuncs/system.c:298 +#, fuzzy +msgid "Format for input filename" +msgstr "erstes Eingabebild" + +#: libvips/iofuncs/system.c:304 +#, fuzzy +msgid "Output format" +msgstr "Ausgabebild" + +#: libvips/iofuncs/system.c:305 +msgid "Format for output filename" +msgstr "" + +#: libvips/iofuncs/system.c:312 +msgid "Command log" +msgstr "" + +#: libvips/iofuncs/target.c:295 +#, fuzzy +msgid "File descriptor should output to memory" +msgstr "Datei-Deskriptor, in den geschrieben werden soll" + +#: libvips/iofuncs/target.c:305 +#, fuzzy +msgid "Blob to save to" +msgstr "Puffer, in den gespeichert werden soll" + +#: libvips/iofuncs/target.c:474 +#, fuzzy +msgid "write error" +msgstr "Lesefehler" + +#: libvips/iofuncs/targetcustom.c:235 +msgid "Custom target" +msgstr "" + +#: libvips/iofuncs/thread.c:179 +msgid "unable to create thread" +msgstr "Thread kann nicht erstellt werden" + +#: libvips/iofuncs/thread.c:214 libvips/iofuncs/thread.c:243 +#, c-format +msgid "threads clipped to %d" +msgstr "Threads an %d angeheftet" + +#: libvips/iofuncs/threadpool.c:193 +msgid "per-thread state for vipsthreadpool" +msgstr "Status pro Thread für »vipsthreadpool«" + +#: libvips/iofuncs/type.c:958 +#, fuzzy, c-format +msgid "unable to convert \"%s\" to int" +msgstr "»%s« kann nicht zur Eingabe geöffnet werden" + +#: libvips/iofuncs/util.c:455 +msgid "unable to get file stats" +msgstr "Dateistatus kann nicht abgefragt werden" + +#: libvips/iofuncs/util.c:619 +#, c-format +msgid "unable to open file \"%s\" for reading" +msgstr "Datei »%s« kann nicht zum Lesen geöffnet werden" + +#: libvips/iofuncs/util.c:641 +#, c-format +msgid "unable to open file \"%s\" for writing" +msgstr "Datei »%s« kann nicht zum Schreiben geöffnet werden" + +#: libvips/iofuncs/util.c:662 +#, c-format +msgid "\"%s\" too long" +msgstr "»%s« zu lang" + +#: libvips/iofuncs/util.c:710 +#, c-format +msgid "error reading from file \"%s\"" +msgstr "Fehler beim Lesen von Datei »%s«" + +#: libvips/iofuncs/util.c:756 +#, fuzzy, c-format +msgid "write error (%zd out of %zd blocks written)" +msgstr "Schreibfehler (%zd aus %zd Blöcken geschrieben) … Platte voll?" + +#: libvips/iofuncs/util.c:1003 +msgid "unable to seek" +msgstr "kann nicht gesucht werden" + +#: libvips/iofuncs/util.c:1028 libvips/iofuncs/util.c:1035 +msgid "unable to truncate" +msgstr "kann nicht gekürzt werden" -#: libvips/foreign/openslide2vips.c:202 -#, c-format -msgid "getting dimensions: %s" -msgstr "Abfragen der Abmessungen: %s" +#: libvips/iofuncs/util.c:1121 +#, fuzzy, c-format +msgid "unable to remove directory \"%s\", %s" +msgstr "Daten für »%s« können nicht gelesen werden, %s" -#: libvips/foreign/openslide2vips.c:209 -msgid "image dimensions overflow int" -msgstr "Überlaufganzzahl der Bildabmessungen" +#: libvips/iofuncs/util.c:1138 +#, fuzzy, c-format +msgid "unable to rename file \"%s\" as \"%s\", %s" +msgstr "" +"Datei »%s« kann nicht gelesen werden\n" +"libMagick-Fehler: %s %s" -#: libvips/foreign/openslide2vips.c:274 -#, c-format -msgid "reading region: %s" -msgstr "Region wird gelesen: %s" +#: libvips/iofuncs/util.c:1267 +msgid "unexpected end of string" +msgstr "Unerwartetes Ende der Zeichenkette" -#: libvips/foreign/openslide2vips.c:348 +#: libvips/iofuncs/util.c:1285 libvips/iofuncs/util.c:1355 #, c-format -msgid "reading associated image: %s" -msgstr "zugehöriges Bild wird gelesen: %s" +msgid "expected %s, saw %s" +msgstr "%s erwartet, %s gesehen" -#: libvips/foreign/analyze2vips.c:308 -msgid "header file size incorrect" -msgstr "Kopfdatendateigröße nicht korrekt" +#: libvips/iofuncs/util.c:1664 +msgid "no such enum type" +msgstr "" -#: libvips/foreign/analyze2vips.c:353 -msgid "header size incorrect" -msgstr "Kopfdatengröße nicht korrekt" +#: libvips/iofuncs/util.c:1682 +#, fuzzy, c-format +msgid "enum '%s' has no member '%s', should be one of: %s" +msgstr "Aufzählung »%s« hat keinen Bestandteil »%s«" -#: libvips/foreign/analyze2vips.c:371 -#, c-format -msgid "%d-dimensional images not supported" -msgstr "%d-dimensionale Bilder nicht unterstützt" +#: libvips/iofuncs/util.c:1701 +msgid "no such flag type" +msgstr "" -#: libvips/foreign/analyze2vips.c:424 -#, c-format -msgid "datatype %d not supported" -msgstr "Datentyp %d nicht unterstützt" +#: libvips/iofuncs/util.c:1720 +#, fuzzy, c-format +msgid "flags '%s' has no member '%s'" +msgstr "Aufzählung »%s« hat keinen Bestandteil »%s«" -#: libvips/foreign/tiff2vips.c:262 libvips/foreign/tiff2vips.c:285 -#: libvips/foreign/tiff2vips.c:303 +#: libvips/iofuncs/vips.c:338 #, c-format -msgid "required field %d missing" -msgstr "benötigtes Feld %d fehlt" +msgid "\"%s\" is not a VIPS image" +msgstr "»%s« ist kein VIPS-Bild" -#: libvips/foreign/tiff2vips.c:266 -#, c-format -msgid "required field %d=%d, not %d" -msgstr "benötigtes Feld %d=%d, nicht %d" +#: libvips/iofuncs/vips.c:395 +msgid "unknown coding" +msgstr "unbekannte Kodierung" -#: libvips/foreign/tiff2vips.c:650 -#, c-format -msgid "%d bits per sample palette image not supported" -msgstr "%d Bit pro Musterfarbpalettenbild nicht unterstützt" +#: libvips/iofuncs/vips.c:405 +msgid "malformed LABQ image" +msgstr "" -#: libvips/foreign/tiff2vips.c:659 -msgid "bad colormap" -msgstr "falsche Farbzusammenstellung" +#: libvips/iofuncs/vips.c:414 +#, fuzzy +msgid "malformed RAD image" +msgstr "kein RAD-Bild" -#: libvips/foreign/tiff2vips.c:716 libvips/foreign/tiff2vips.c:747 -msgid "3 or 4 bands RGB TIFF only" -msgstr "nur RGB-TIFF mit drei oder vier Bändern" +#: libvips/iofuncs/vips.c:485 +msgid "unable to read history" +msgstr "Verlauf kann nicht gelesen werden" -#: libvips/foreign/tiff2vips.c:818 -msgid "4 or 5 bands CMYK TIFF only" -msgstr "nur CMYK-TIFF mit vier oder fünf Bändern" +#: libvips/iofuncs/vips.c:518 +#, fuzzy +msgid "more than 100 megabytes of XML? sufferin' succotash!" +msgstr "mehr als 10 Megabyte XML? Leidende Succotash!" -#: libvips/foreign/tiff2vips.c:869 -msgid "unknown resolution unit" -msgstr "unbekannte Auflösungseinheit" +#: libvips/iofuncs/vips.c:552 +#, fuzzy +msgid "unable to allocate read buffer" +msgstr "In den Puffer kann nicht geschrieben werden." -#: libvips/foreign/tiff2vips.c:874 -#, c-format -msgid "" -"no resolution information for TIFF image \"%s\" -- defaulting to 1 pixel per " -"mm" +#: libvips/iofuncs/vips.c:558 +msgid "read error while fetching XML" msgstr "" -"Keine Auflösungsinformationen für TIFF-Bild »%s« – Standard auf 1 Bildpunkt " -"pro mm" -#: libvips/foreign/tiff2vips.c:946 -#, c-format -msgid "unsupported sample format %d for lab image" -msgstr "nicht unterstütztes Musterformat %d für LAB-Bild" +#: libvips/iofuncs/vips.c:570 +#, fuzzy +msgid "XML parse error" +msgstr "Lesefehler" -#: libvips/foreign/tiff2vips.c:956 -#, c-format -msgid "unsupported depth %d for LAB image" -msgstr "nicht unterstützte Tiefe %d für LAB-Bild" +#: libvips/iofuncs/vips.c:635 +msgid "incorrect namespace in XML" +msgstr "falscher Namensraum in XML" -#: libvips/foreign/tiff2vips.c:995 -#, c-format -msgid "unsupported sample format %d for greyscale image" -msgstr "nicht unterstütztes Musterformat %d für Graustufenbild" +#: libvips/iofuncs/vips.c:683 +msgid "error transforming from save format" +msgstr "Fehler beim Umwandeln vom gespeicherten Format" -#: libvips/foreign/tiff2vips.c:1004 -#, c-format -msgid "unsupported depth %d for greyscale image" -msgstr "nicht unterstützte Tiefe %d für Graustufenbild" +#: libvips/iofuncs/vips.c:784 libvips/iofuncs/vips.c:1056 +#: libvips/iofuncs/window.c:232 +msgid "file has been truncated" +msgstr "Datei wurde gekürzt" -#: libvips/foreign/tiff2vips.c:1052 -#, c-format -msgid "unsupported sample format %d for rgb image" -msgstr "nicht unterstütztes Musterformat %d für RGB-Bild" +#: libvips/iofuncs/vips.c:836 libvips/iofuncs/vips.c:927 +msgid "error transforming to save format" +msgstr "Fehler beim Umwandeln in das zu speichernde Format" -#: libvips/foreign/tiff2vips.c:1061 +#: libvips/iofuncs/vips.c:1041 #, c-format -msgid "unsupported depth %d for RGB image" -msgstr "nicht unterstützte Tiefe %d für RGB-Bild" +msgid "unable to read header for \"%s\"" +msgstr "Kopfdaten für »%s« können nicht gelesen werden" -#: libvips/foreign/tiff2vips.c:1075 +#: libvips/iofuncs/vips.c:1055 libvips/iofuncs/window.c:231 #, c-format -msgid "unknown photometric interpretation %d" -msgstr "unbekannte fotometrische Deutung %d" +msgid "unable to read data for \"%s\", %s" +msgstr "Daten für »%s« können nicht gelesen werden, %s" -#: libvips/foreign/tiff2vips.c:1331 libvips/foreign/radiance.c:959 -msgid "read error" -msgstr "Lesefehler" +# http://radsite.lbl.gov/radiance/refer/Notes/picture_format.html +#: libvips/iofuncs/vips.c:1067 +#, fuzzy, c-format +msgid "error reading vips image metadata: %s" +msgstr "Fehler beim Lesen der Radiance-Kopfzeilen" -#: libvips/foreign/tiff2vips.c:1444 -#, c-format -msgid "bad page number %d" -msgstr "falsche Seitennummer %d" +# http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=0650& +# db=man&fname=/usr/share/catman/p_man/cat3/il_c/ilAbsImg.z +#: libvips/morphology/countlines.c:135 +#, fuzzy +msgid "count lines in an image" +msgstr "absoluter Wert eines Bildes" -#: libvips/foreign/tiff2vips.c:1465 libvips/foreign/vips2tiff.c:286 -#, c-format -msgid "unable to open \"%s\" for input" -msgstr "»%s« kann nicht zur Eingabe geöffnet werden" +#: libvips/morphology/countlines.c:139 +#, fuzzy +msgid "Nolines" +msgstr "Zeilen" -#: libvips/foreign/tiff2vips.c:1520 libvips/foreign/tiff2vips.c:1550 -#, c-format -msgid "TIFF file does not contain page %d" -msgstr "TIFF-Datei enthält nicht Seite %d" +#: libvips/morphology/countlines.c:140 +#, fuzzy +msgid "Number of lines" +msgstr "Anzahl der Bänder in einem Bild" -#: libvips/foreign/jpegsave.c:118 -msgid "save jpeg" -msgstr "JPEG speichern" +#: libvips/morphology/countlines.c:147 +#, fuzzy +msgid "Countlines left-right or up-down" +msgstr "von links nach rechts oder von oben nach unten zusammenführen" -#: libvips/foreign/jpegsave.c:187 -msgid "save image to jpeg file" -msgstr "Bild in JPEG-Datei speichern" +#: libvips/morphology/labelregions.c:120 +#, fuzzy +msgid "label regions in an image" +msgstr "Anzahl der Bänder in einem Bild" -#: libvips/foreign/jpegsave.c:256 -msgid "save image to jpeg buffer" -msgstr "Bild in den JPEG-Puffer speichern" +#: libvips/morphology/labelregions.c:125 +msgid "Mask of region labels" +msgstr "" -#: libvips/foreign/jpegsave.c:261 libvips/foreign/pngsave.c:229 -msgid "Buffer to save to" -msgstr "Puffer, in den gespeichert werden soll" +#: libvips/morphology/labelregions.c:130 +msgid "Segments" +msgstr "" -#: libvips/foreign/jpegsave.c:303 -msgid "error writing output" -msgstr "Fehler beim Schreiben der Ausgabe" +#: libvips/morphology/labelregions.c:131 +msgid "Number of discrete contiguous regions" +msgstr "" -#: libvips/foreign/jpegsave.c:319 -# http://de.wikipedia.org/wiki/MIME#image -msgid "save image to jpeg mime" -msgstr "Bild in JPEG-MIME speichern" +#: libvips/morphology/morph.c:885 +#, fuzzy, c-format +msgid "bad mask element (%f should be 0, 128 or 255)" +msgstr "falsches Maskenelement (%d sollte 0, 128 oder 255 sein)" -#: libvips/foreign/rawsave.c:159 -# http://de.wikipedia.org/wiki/Rohdatenformat_(Fotografie) -msgid "save image to raw file" -msgstr "Bild in Rohdatenformatdatei speichern" +#: libvips/morphology/morph.c:955 +#, fuzzy +msgid "morphology operation" +msgstr "unäre Transaktionen" -#: libvips/foreign/rawsave.c:266 -msgid "write raw image to file descriptor" -msgstr "Rohdatenbild in Datei-Deskriptor schreiben" +#: libvips/morphology/morph.c:971 +msgid "Morphology" +msgstr "" -#: libvips/foreign/rawsave.c:273 -msgid "File descriptor" -msgstr "Datei-Deskriptor" +#: libvips/morphology/morph.c:972 +#, fuzzy +msgid "Morphological operation to perform" +msgstr "durchzuführende Rundungstransakktion" -#: libvips/foreign/rawsave.c:274 -msgid "File descriptor to write to" -msgstr "Datei-Deskriptor, in den geschrieben werden soll" +#: libvips/morphology/morphology.c:115 +#, fuzzy +msgid "morphological operations" +msgstr "arithmetische Transaktionen" -#: libvips/foreign/ppmsave.c:109 -# http://de.wikipedia.org/wiki/Portable_Pixmap -msgid "save image to ppm file" -msgstr "Bild in PPM-Datei speichern" +#: libvips/morphology/nearest.c:305 +msgid "fill image zeros with nearest non-zero pixel" +msgstr "" -#: libvips/foreign/ppmsave.c:125 -msgid "ASCII" -msgstr "ASCII" +#: libvips/morphology/nearest.c:309 +#, fuzzy +msgid "Out" +msgstr "Ausgabe" -#: libvips/foreign/ppmsave.c:126 -msgid "save as ascii" -msgstr "Bild als ASCII speichern" +#: libvips/morphology/nearest.c:310 +msgid "Value of nearest non-zero pixel" +msgstr "" -#: libvips/foreign/vips2jpeg.c:132 -#, c-format -msgid "%s" -msgstr "%s" +#: libvips/morphology/nearest.c:316 +msgid "Distance to nearest non-zero pixel" +msgstr "" -#: libvips/foreign/vips2jpeg.c:363 -msgid "error setting JPEG resolution" -msgstr "Fehler beim Setzen der JPEG-Auflösung" +#: libvips/morphology/rank.c:496 +#, fuzzy +msgid "index out of range" +msgstr " »bins« außerhalb des Bereichs [1,%d]" -#: libvips/foreign/vips2jpeg.c:510 -msgid "error saving EXIF" -msgstr "Fehler beim Speichern von EXIF" +#: libvips/morphology/rank.c:560 +msgid "rank filter" +msgstr "" -#: libvips/foreign/openexr2vips.c:115 -#, c-format -msgid "EXR error: %s" -msgstr "EXR-Fehler: %s" +#: libvips/morphology/rank.c:585 +msgid "Select pixel at index" +msgstr "" -#: libvips/foreign/magick2vips.c:215 -#, c-format -msgid "unsupported image type %d" -msgstr "nicht unterstützter Bildtyp %d" +#: libvips/mosaicing/chkpair.c:200 +msgid "inputs incompatible" +msgstr "Eingaben inkompatibel" -#: libvips/foreign/magick2vips.c:275 -#, c-format -msgid "unsupported bit depth %d" -msgstr "nicht unterstützte Bit-Tiefe %d" +#: libvips/mosaicing/chkpair.c:204 libvips/mosaicing/im_tbcalcon.c:105 +msgid "help!" +msgstr "Hilfe!" -#: libvips/foreign/magick2vips.c:307 -#, c-format -msgid "unsupported colorspace %d" -msgstr "nicht unterstützter Farbraum %d" +#: libvips/mosaicing/global_balance.c:151 +msgid "no matching '>'" +msgstr "kein passendes »>«" -#: libvips/foreign/magick2vips.c:622 -msgid "unable to read pixels" -msgstr "Bildpunkte können nicht gelesen werden" +#: libvips/mosaicing/global_balance.c:160 +msgid "too many items" +msgstr "zu viele Elemente" -#: libvips/foreign/magick2vips.c:658 -#, c-format -msgid "" -"unable to read file \"%s\"\n" -"libMagick error: %s %s" -msgstr "" -"Datei »%s« kann nicht gelesen werden\n" -"libMagick-Fehler: %s %s" +# Propogate a transform down a tree. If dirty is set, we've been here before, +# so there is a doubling up of this node. If this is a leaf, then we have the +# same leaf twice (which, in fact, we can cope with); if this is a node, we +# have circularity. +#: libvips/mosaicing/global_balance.c:463 +msgid "circularity detected" +msgstr "Zirkularität entdeckt" -#: libvips/foreign/magick2vips.c:692 +#: libvips/mosaicing/global_balance.c:497 +#: libvips/mosaicing/global_balance.c:557 #, c-format -msgid "" -"unable to ping file \"%s\"\n" -"libMagick error: %s %s" -msgstr "" -"Datei »%s« kann nicht angepingt werden\n" -"libMagick-Fehler: %s %s" - -#: libvips/foreign/magick2vips.c:703 -msgid "bad image size" -msgstr "falsche Bildgröße" +msgid "image \"%s\" used twice as output" +msgstr "Bild »%s« zweimal als Ausgabe benutzt" -#: libvips/foreign/vipspng.c:230 -msgid "unsupported color type" -msgstr "nicht unterstützter Farbtyp" +#: libvips/mosaicing/global_balance.c:606 +msgid "bad number of args in join line" +msgstr "falsche Anzahl von Argumenten in »join«-Zeile" -#: libvips/foreign/vipspng.c:570 -msgid "compress should be in [0,9]" -msgstr "Komprimierung sollte in [0,9] liegen" +#: libvips/mosaicing/global_balance.c:648 +msgid "bad number of args in join1 line" +msgstr "falsche Anzahl von Argumenten in »join1«-Zeile" -#: libvips/foreign/vipspng.c:650 -#, c-format -msgid "unable to write \"%s\"" -msgstr "»%s« kann nicht geschrieben werden" +#: libvips/mosaicing/global_balance.c:684 +msgid "bad number of args in copy line" +msgstr "falsche Anzahl von Argumenten in »copy«-Zeile" -#: libvips/foreign/vipspng.c:749 -msgid "unable to write to buffer" -msgstr "In den Puffer kann nicht geschrieben werden." +#: libvips/mosaicing/global_balance.c:742 +msgid "" +"mosaic root not found in desc file\n" +"is this really a mosaiced image?" +msgstr "" +"Mosaik-Wurzel nicht in Beschreibungsdatei gefunden\n" +"ist das wirklich ein Bild?" -#: libvips/foreign/matlab.c:106 libvips/foreign/fits.c:178 -#: libvips/iofuncs/vips.c:143 libvips/mosaicing/global_balance.c:1181 -#: libvips/mosaicing/global_balance.c:1516 -#, c-format -msgid "unable to open \"%s\"" -msgstr "»%s« kann nicht geöffnet werden" +#: libvips/mosaicing/global_balance.c:753 +msgid "more than one root" +msgstr "mehr als eine Wurzel" -#: libvips/foreign/matlab.c:114 -#, c-format -msgid "no matrix variables in \"%s\"" -msgstr "keine Matrixvariablen in »%s«" +#: libvips/mosaicing/global_balance.c:1525 +msgid "bad sizes" +msgstr "falsche Größen" -#: libvips/foreign/matlab.c:175 -#, c-format -msgid "unsupported rank %d\n" -msgstr "nicht unterstützte Rangstufe %d\n" +#: libvips/mosaicing/global_balance.c:1920 +#, fuzzy +msgid "global balance an image mosaic" +msgstr "ein Radiance-Bild aus einer Datei laden" -#: libvips/foreign/matlab.c:188 -#, c-format -msgid "unsupported class type %d\n" -msgstr "nicht unterstützter Klassentyp %d\n" +#: libvips/mosaicing/global_balance.c:1936 +msgid "Gamma" +msgstr "" -#: libvips/foreign/matlab.c:236 -msgid "Mat_VarReadDataAll failed" -msgstr "»Mat_VarReadDataAll« fehlgeschlagen" +#: libvips/mosaicing/global_balance.c:1937 +#, fuzzy +msgid "Image gamma" +msgstr "Bilddateiname" -#: libvips/foreign/jpeg2vips.c:167 -#, c-format -msgid "read gave %ld warnings" -msgstr "Lesen ergab %ld Warnungen" +#: libvips/mosaicing/global_balance.c:1943 +#, fuzzy +msgid "Int output" +msgstr "Ausgabe" -#: libvips/foreign/jpeg2vips.c:489 -msgid "error reading resolution" -msgstr "Fehler beim Lesen der Auflösung" +#: libvips/mosaicing/global_balance.c:1944 +#, fuzzy +msgid "Integer output" +msgstr "detaillierte Ausgabe" -#: libvips/foreign/fits.c:240 -msgid "dimensions above 3 must be size 1" -msgstr "Dimensionen größer drei müssen die Größe eins haben" +#: libvips/mosaicing/im_avgdxdy.c:65 +msgid "no points to average" +msgstr "keine Punkte zum Mitteln" -#: libvips/foreign/fits.c:256 -#, c-format -msgid "bad number of axis %d" -msgstr "falsche Achsenanzahl %d" +#: libvips/mosaicing/im_clinear.c:138 +#, fuzzy +msgid "vips_invmat failed" +msgstr "»im_invmat« fehlgeschlagen" -#: libvips/foreign/fits.c:272 -#, c-format -msgid "unsupported bitpix %d\n" -msgstr "nicht unterstützte »bitpix« %d\n" +#: libvips/mosaicing/im_lrcalcon.c:206 +msgid "overlap too small for your search size" +msgstr "Überlappen zu schmal für Ihre Suchgröße" -#: libvips/foreign/fits.c:576 libvips/iofuncs/vips.c:171 +#: libvips/mosaicing/im_lrcalcon.c:245 #, c-format -msgid "unable to write to \"%s\"" -msgstr "auf »%s« kann nicht geschrieben werden" +msgid "found %d tie-points, need at least %d" +msgstr "es wurden %d Verbindungspunkte gefunden, mindestens %d sind nötig" -#: libvips/foreign/fits.c:637 -#, c-format -msgid "unsupported BandFmt %d\n" -msgstr "nicht unterstütztes BandFmt %d\n" +#: libvips/mosaicing/im_lrcalcon.c:290 +msgid "not 1-band uchar image" +msgstr "kein »uchar«-Bild mit einem Band" -#: libvips/foreign/csvsave.c:112 -msgid "save image to csv file" -msgstr "Bild in CSV-Datei speichern" +#: libvips/mosaicing/im_tbcalcon.c:119 +msgid "overlap too small" +msgstr "Überlappen zu schmal" -#: libvips/foreign/csvsave.c:128 libvips/foreign/csvload.c:160 -msgid "Separator" -msgstr "Trenner" +#: libvips/mosaicing/lrmerge.c:786 +msgid "mwidth must be -1 or >= 0" +msgstr "»mwidth« muss -1 oder >= 0 sein" -#: libvips/foreign/csvsave.c:129 -msgid "Separator characters" -msgstr "Trennzeichen" +#: libvips/mosaicing/lrmerge.c:818 +msgid "no overlap" +msgstr "kein Überlappen" -#: libvips/foreign/ppm.c:109 -msgid "bad int" -msgstr "falsche Ganzzahl" +#: libvips/mosaicing/lrmerge.c:888 libvips/mosaicing/tbmerge.c:693 +msgid "unknown coding type" +msgstr "unbekannter Kodierungstyp" -#: libvips/foreign/ppm.c:121 -msgid "bad float" -msgstr "falsche Fließkommazahl" +#: libvips/mosaicing/lrmerge.c:906 libvips/mosaicing/tbmerge.c:711 +msgid "too much overlap" +msgstr "zu viel Überlappung" -#: libvips/foreign/ppm.c:172 -msgid "bad magic number" -msgstr "falsche magische Zahl" +#: libvips/mosaicing/lrmosaic.c:122 libvips/mosaicing/tbmosaic.c:93 +msgid "bad area parameters" +msgstr "falsche Bereichsparameter" -#: libvips/foreign/ppm.c:222 -msgid "not whitespace before start of binary data" -msgstr "kein Leerraum vor dem Start der binären Daten" +#: libvips/mosaicing/lrmosaic.c:143 libvips/mosaicing/tbmosaic.c:114 +msgid "overlap too small for search" +msgstr "Überlappen zu klein für Suche" -#: libvips/foreign/ppm.c:599 libvips/foreign/ppm.c:611 -msgid "write error ... disc full?" -msgstr "Schreibfehler … Platte voll?" +#: libvips/mosaicing/lrmosaic.c:171 libvips/mosaicing/tbmosaic.c:142 +msgid "unknown Coding type" +msgstr "unbekannter Kodierungstyp" -#: libvips/foreign/ppm.c:716 -msgid "binary >8 bit images must be float" -msgstr "binäre Bilder >8 Bit müssen aus Fließkommazahlen bestehen" +#: libvips/mosaicing/match.c:192 +#, fuzzy +msgid "first-order match of two images" +msgstr "zwei Bilder subtrahieren" -#: libvips/foreign/vips2tiff.c:270 -#, c-format -msgid "unable to open \"%s\" for output" -msgstr "»%s« kann nicht zur Ausgabe geöffnet werden" +#: libvips/mosaicing/match.c:197 libvips/mosaicing/merge.c:123 +#: libvips/mosaicing/mosaic1.c:499 libvips/mosaicing/mosaic.c:180 +#, fuzzy +msgid "Reference image" +msgstr "Zeilensprungbild" -#: libvips/foreign/vips2tiff.c:692 -msgid "layer buffer exhausted -- try making TIFF output tiles smaller" +#: libvips/mosaicing/match.c:202 libvips/mosaicing/merge.c:128 +#: libvips/mosaicing/mosaic1.c:504 libvips/mosaicing/mosaic.c:185 +msgid "Secondary" msgstr "" -"Ebenenpuffer aufgebraucht – versuchen Sie die TIFF-Ausgabekacheln zu " -"verkleinern" -#: libvips/foreign/vips2tiff.c:922 -msgid "TIFF write tile failed" -msgstr "Schreiben des TIFF-Bildes fehlgeschlagen" +#: libvips/mosaicing/match.c:203 libvips/mosaicing/merge.c:129 +#: libvips/mosaicing/mosaic1.c:505 libvips/mosaicing/mosaic.c:186 +#, fuzzy +msgid "Secondary image" +msgstr "zweites Eingabebild" -#: libvips/foreign/vips2tiff.c:998 -msgid "internal error #9876345" -msgstr "interner Fehler #9876345" +#: libvips/mosaicing/match.c:214 libvips/mosaicing/mosaic1.c:523 +msgid "xr1" +msgstr "" -#: libvips/foreign/vips2tiff.c:1251 -msgid "tile size not a multiple of 16" -msgstr "Bildgröße kein Vielfaches von 16" +#: libvips/mosaicing/match.c:215 libvips/mosaicing/match.c:222 +#: libvips/mosaicing/mosaic1.c:524 libvips/mosaicing/mosaic1.c:531 +msgid "Position of first reference tie-point" +msgstr "" -#: libvips/foreign/vips2tiff.c:1257 -msgid "can't have strip pyramid -- enabling tiling" +#: libvips/mosaicing/match.c:221 libvips/mosaicing/mosaic1.c:530 +msgid "yr1" msgstr "" -"nicht ummantelte Pyramide nicht möglich – Zerteilung wird eingeschaltet" -#: libvips/foreign/vips2tiff.c:1268 -msgid "can only pyramid LABQ and non-complex images" +#: libvips/mosaicing/match.c:228 libvips/mosaicing/mosaic1.c:537 +msgid "xs1" msgstr "" -"nur LABQ und nicht-komplexe Bilder können pyramidenartig verwendet werden" -#: libvips/foreign/vips2tiff.c:1463 -msgid "unsigned 8-bit int, 16-bit int, and 32-bit float only" -msgstr "nur vorzeichenlose 8-Bit-Ganzzahl und 32-Bit-Fließkommazahl" +#: libvips/mosaicing/match.c:229 libvips/mosaicing/match.c:236 +#: libvips/mosaicing/mosaic1.c:538 libvips/mosaicing/mosaic1.c:545 +msgid "Position of first secondary tie-point" +msgstr "" -#: libvips/foreign/vips2tiff.c:1470 -msgid "1 to 5 bands only" -msgstr "nur 1 bis 5 Bänder" +#: libvips/mosaicing/match.c:235 libvips/mosaicing/mosaic1.c:544 +msgid "ys1" +msgstr "" -#: libvips/foreign/radiance.c:885 -# http://radsite.lbl.gov/radiance/refer/Notes/picture_format.html -msgid "error reading radiance header" -msgstr "Fehler beim Lesen der Radiance-Kopfzeilen" +#: libvips/mosaicing/match.c:242 libvips/mosaicing/mosaic1.c:551 +msgid "xr2" +msgstr "" -#: libvips/foreign/csvload.c:121 -msgid "load csv from file" -msgstr "CSV aus Datei laden" +#: libvips/mosaicing/match.c:243 libvips/mosaicing/match.c:250 +#: libvips/mosaicing/mosaic1.c:552 libvips/mosaicing/mosaic1.c:559 +msgid "Position of second reference tie-point" +msgstr "" -#: libvips/foreign/csvload.c:139 -msgid "Skip" -msgstr "überspringen" +#: libvips/mosaicing/match.c:249 libvips/mosaicing/mosaic1.c:558 +msgid "yr2" +msgstr "" -#: libvips/foreign/csvload.c:140 -msgid "Skip this many lines at the start of the file" -msgstr "so viele Zeilen ab dem Dateianfang überspringen" +#: libvips/mosaicing/match.c:256 libvips/mosaicing/mosaic1.c:565 +msgid "xs2" +msgstr "" -#: libvips/foreign/csvload.c:146 -msgid "Lines" -msgstr "Zeilen" +#: libvips/mosaicing/match.c:257 libvips/mosaicing/match.c:264 +#: libvips/mosaicing/mosaic1.c:566 libvips/mosaicing/mosaic1.c:573 +msgid "Position of second secondary tie-point" +msgstr "" -#: libvips/foreign/csvload.c:147 -msgid "Read this many lines from the file" -msgstr "so viele Zeilen aus der Datei lesen" +#: libvips/mosaicing/match.c:263 libvips/mosaicing/mosaic1.c:572 +msgid "ys2" +msgstr "" -#: libvips/foreign/csvload.c:153 -msgid "Whitespace" -msgstr "Leerraum" +#: libvips/mosaicing/match.c:270 libvips/mosaicing/mosaic1.c:579 +#: libvips/mosaicing/mosaic.c:232 +#, fuzzy +msgid "hwindow" +msgstr "Windows-Fehler" -#: libvips/foreign/csvload.c:154 -msgid "Set of whitespace characters" -msgstr "Satz von Leerraumzeichen" +#: libvips/mosaicing/match.c:271 libvips/mosaicing/mosaic1.c:580 +#: libvips/mosaicing/mosaic.c:233 +msgid "Half window size" +msgstr "" -#: libvips/foreign/csvload.c:161 -msgid "Set of separator characters" -msgstr "Satz von Trennzeichen" +#: libvips/mosaicing/match.c:277 libvips/mosaicing/mosaic1.c:586 +#: libvips/mosaicing/mosaic.c:239 +msgid "harea" +msgstr "" -#: libvips/foreign/pngsave.c:95 -msgid "save png" -msgstr "PNG speichern" +#: libvips/mosaicing/match.c:278 libvips/mosaicing/mosaic1.c:587 +#: libvips/mosaicing/mosaic.c:240 +#, fuzzy +msgid "Half area size" +msgstr "falsche Bildgröße" -#: libvips/foreign/pngsave.c:104 -msgid "Compression factor" -msgstr "Komprimierungsfaktor" +#: libvips/mosaicing/match.c:284 libvips/mosaicing/mosaic1.c:593 +msgid "Search" +msgstr "" -#: libvips/foreign/pngsave.c:110 -msgid "Interlace" +#: libvips/mosaicing/match.c:285 libvips/mosaicing/mosaic1.c:594 +msgid "Search to improve tie-points" +msgstr "" + +#: libvips/mosaicing/match.c:291 libvips/mosaicing/mosaic1.c:600 +#: libvips/resample/affine.c:651 libvips/resample/mapim.c:561 +#: libvips/resample/quadratic.c:351 libvips/resample/resize.c:376 +#: libvips/resample/similarity.c:127 +#, fuzzy +msgid "Interpolate" msgstr "Zeilensprung" -#: libvips/foreign/pngsave.c:111 -msgid "Interlace image" -msgstr "Zeilensprungbild" +#: libvips/mosaicing/match.c:292 libvips/mosaicing/mosaic1.c:601 +#: libvips/resample/affine.c:652 libvips/resample/mapim.c:562 +#: libvips/resample/resize.c:377 libvips/resample/similarity.c:128 +msgid "Interpolate pixels with this" +msgstr "" -#: libvips/foreign/pngsave.c:162 -msgid "save image to png file" -msgstr "Bild in PNG-Datei speichern" +#: libvips/mosaicing/matrixinvert.c:312 libvips/mosaicing/matrixinvert.c:328 +#: libvips/mosaicing/matrixinvert.c:353 libvips/resample/transform.c:60 +msgid "singular or near-singular matrix" +msgstr "" -#: libvips/foreign/pngsave.c:224 -msgid "save image to png buffer" -msgstr "Bild in den PNG-Puffer speichern" +#: libvips/mosaicing/matrixinvert.c:406 +msgid "non-square matrix" +msgstr "" -#: libvips/foreign/foreign.c:384 -msgid "load and save image files" -msgstr "Bilddateien laden und speichern" +#: libvips/mosaicing/matrixinvert.c:439 +#, fuzzy +msgid "invert an matrix" +msgstr "ein Bild invertieren" -#: libvips/foreign/foreign.c:525 libvips/mosaicing/im_remosaic.c:76 -#, c-format -msgid "file \"%s\" not found" -msgstr "Datei »%s« nicht gefunden" +#: libvips/mosaicing/matrixinvert.c:444 +msgid "An square matrix" +msgstr "" -#: libvips/foreign/foreign.c:534 libvips/foreign/foreign.c:1022 -#, c-format -msgid "\"%s\" is not a known file format" -msgstr "»%s« ist kein bekanntes Dateiformat" +#: libvips/mosaicing/matrixinvert.c:450 +#, fuzzy +msgid "Output matrix" +msgstr "Ausgabebild" -#: libvips/foreign/foreign.c:740 -msgid "images do not match" -msgstr "Bilder passen nicht zusammen" +#: libvips/mosaicing/merge.c:116 +#, fuzzy +msgid "merge two images" +msgstr "zwei Bilder hinzufügen" -#: libvips/foreign/foreign.c:894 -msgid "file loaders" -msgstr "Dateilader" +#: libvips/mosaicing/merge.c:141 +#, fuzzy +msgid "Horizontal or vertical merge" +msgstr "horizontaler Versatz vom Ursprung" -#: libvips/foreign/foreign.c:903 -msgid "Flags" -msgstr "Schalter" +#: libvips/mosaicing/merge.c:147 +#, fuzzy +msgid "dx" +msgstr "x" -#: libvips/foreign/foreign.c:904 -msgid "Flags for this file" -msgstr "Schalter für diese Datei" +#: libvips/mosaicing/merge.c:148 +msgid "Horizontal displacement from sec to ref" +msgstr "" -#: libvips/foreign/foreign.c:910 -msgid "Disc" -msgstr "Platte" +#: libvips/mosaicing/merge.c:154 +#, fuzzy +msgid "dy" +msgstr "y" -#: libvips/foreign/foreign.c:911 -msgid "Open to disc" -msgstr "offen zur Platte" +#: libvips/mosaicing/merge.c:155 +msgid "Vertical displacement from sec to ref" +msgstr "" -#: libvips/foreign/foreign.c:917 -msgid "Sequential" -msgstr "sequenziell" +#: libvips/mosaicing/merge.c:161 libvips/mosaicing/mosaic1.c:606 +#: libvips/mosaicing/mosaic.c:246 +#, fuzzy +msgid "Max blend" +msgstr "Mischung" -#: libvips/foreign/foreign.c:918 -msgid "Sequential read only" -msgstr "sequenziell nur mit Lesezugriff" +#: libvips/mosaicing/merge.c:162 libvips/mosaicing/mosaic1.c:607 +#: libvips/mosaicing/mosaic.c:247 +#, fuzzy +msgid "Maximum blend size" +msgstr "Maximalwert des Bildes" -#: libvips/foreign/foreign.c:1370 -msgid "file savers" -msgstr "Dateispeicherer" +#: libvips/mosaicing/mosaic1.c:494 +#, fuzzy +msgid "first-order mosaic of two images" +msgstr "zwei Bilder subtrahieren" -#: libvips/foreign/foreign.c:1380 -msgid "Image to save" -msgstr "zu speicherndes Bild" +#: libvips/mosaicing/mosaic1.c:517 libvips/mosaicing/mosaic.c:198 +#, fuzzy +msgid "Horizontal or vertical mosaic" +msgstr "horizontale Position des Maximums" -#: libvips/freq_filt/im_freq_mask.c:108 -msgid "mask sizes power of 2 only" -msgstr "Maskengröße nur Potenzen von 2" +#: libvips/mosaicing/mosaic1.c:613 libvips/mosaicing/mosaic.c:253 +#, fuzzy +msgid "Search band" +msgstr "falsche Bänder" -#: libvips/freq_filt/im_freq_mask.c:155 -msgid "unimplemented mask type" -msgstr "nicht implementierter Maskentyp" +#: libvips/mosaicing/mosaic1.c:614 libvips/mosaicing/mosaic.c:254 +msgid "Band to search for features on" +msgstr "" -#: libvips/freq_filt/fmaskcir.c:158 libvips/freq_filt/fmaskcir.c:303 -#: libvips/freq_filt/fmaskcir.c:394 libvips/freq_filt/fmaskcir.c:476 -#: libvips/freq_filt/fmaskcir.c:556 -msgid "bad sizes" -msgstr "falsche Größen" +#: libvips/mosaicing/mosaic.c:175 +#, fuzzy +msgid "mosaic two images" +msgstr "zwei Bilder subtrahieren" -#: libvips/freq_filt/fmaskcir.c:172 libvips/freq_filt/fmaskcir.c:228 -#: libvips/freq_filt/fmaskcir.c:242 libvips/freq_filt/fmaskcir.c:317 -#: libvips/freq_filt/fmaskcir.c:321 libvips/freq_filt/fmaskcir.c:408 -#: libvips/freq_filt/fmaskcir.c:412 libvips/freq_filt/fmaskcir.c:570 -#: libvips/freq_filt/fmaskcir.c:574 libvips/freq_filt/fmask4th.c:120 -#: libvips/freq_filt/fmask4th.c:129 libvips/freq_filt/fmask4th.c:163 -#: libvips/freq_filt/fmask4th.c:172 libvips/freq_filt/fmask4th.c:205 -#: libvips/freq_filt/fmask4th.c:214 libvips/freq_filt/fmask4th.c:252 -#: libvips/freq_filt/fmask4th.c:261 libvips/freq_filt/fmask4th.c:292 -#: libvips/freq_filt/fmask4th.c:301 libvips/freq_filt/fmask4th.c:333 -#: libvips/freq_filt/fmask4th.c:342 libvips/freq_filt/fmask4th.c:373 -#: libvips/freq_filt/fmask4th.c:387 libvips/freq_filt/fmask4th.c:423 -#: libvips/freq_filt/fmask4th.c:437 libvips/freq_filt/fmask4th.c:473 -#: libvips/freq_filt/fmask4th.c:487 libvips/freq_filt/fmask4th.c:527 -#: libvips/freq_filt/fmask4th.c:541 libvips/freq_filt/fmask4th.c:578 -#: libvips/freq_filt/fmask4th.c:592 libvips/freq_filt/fmask4th.c:629 -#: libvips/freq_filt/fmask4th.c:643 libvips/freq_filt/fmask4th.c:697 -msgid "bad args" -msgstr "falsche Argumente" - -#: libvips/freq_filt/fmaskcir.c:490 -msgid "bad args (f)" -msgstr "falsche Argumente (f)" - -#: libvips/freq_filt/fmaskcir.c:494 -msgid "bad args (ac)" -msgstr "falsche Argumente (ac)" - -#: libvips/freq_filt/fmaskcir.c:655 libvips/freq_filt/fmask4th.c:791 -msgid "unimplemented mask" -msgstr "nicht implementierte Maske" +#: libvips/mosaicing/mosaic.c:204 +msgid "xref" +msgstr "" -#: libvips/freq_filt/im_fractsurf.c:72 -msgid "dimension should be in (2,3)" -msgstr "Dimension sollte in (2,3) liegen" +#: libvips/mosaicing/mosaic.c:205 libvips/mosaicing/mosaic.c:212 +msgid "Position of reference tie-point" +msgstr "" -#: libvips/freq_filt/im_invfft.c:105 libvips/freq_filt/im_invfftr.c:124 -#: libvips/freq_filt/im_fwfft.c:125 libvips/freq_filt/im_fwfft.c:241 -msgid "unable to create transform plan" -msgstr "Umwandlungsplan kann nicht erstellt werden" +#: libvips/mosaicing/mosaic.c:211 +msgid "yref" +msgstr "" -#: libvips/freq_filt/im_invfft.c:130 libvips/freq_filt/im_invfftr.c:145 -#: libvips/freq_filt/im_fwfft.c:301 -msgid "vips configured without FFT support" -msgstr "VIPS wurde ohne FFT-Unterstützung konfiguriert" +#: libvips/mosaicing/mosaic.c:218 +msgid "xsec" +msgstr "" -#: libvips/histograms_lut/im_stdif.c:186 -#: libvips/histograms_lut/im_lhisteq.c:159 -msgid "window too large" -msgstr "Fenster zu groß" +#: libvips/mosaicing/mosaic.c:219 libvips/mosaicing/mosaic.c:226 +msgid "Position of secondary tie-point" +msgstr "" -#: libvips/histograms_lut/im_stdif.c:191 -#: libvips/histograms_lut/im_lhisteq.c:164 -msgid "window too small" -msgstr "Fenster zu klein" +#: libvips/mosaicing/mosaic.c:225 +msgid "ysec" +msgstr "" -#: libvips/histograms_lut/im_histnD.c:227 -#, c-format -msgid " bins out of range [1,%d]" -msgstr " »bins« außerhalb des Bereichs [1,%d]" +#: libvips/mosaicing/mosaic.c:260 libvips/mosaicing/mosaic.c:267 +msgid "Integer offset" +msgstr "" -#: libvips/histograms_lut/im_identity.c:139 libvips/other/im_grey.c:101 -#: libvips/other/im_make_xy.c:95 -msgid "bad size" -msgstr "falsche Größe" +#: libvips/mosaicing/mosaic.c:261 libvips/mosaicing/mosaic.c:268 +msgid "Detected integer offset" +msgstr "" -#: libvips/histograms_lut/im_buildlut.c:120 -msgid "x value not an int" -msgstr "x-Wert keine Ganzzahl" +#: libvips/mosaicing/mosaic.c:275 +msgid "Detected scale" +msgstr "" -#: libvips/histograms_lut/im_buildlut.c:133 -msgid "x range too small" -msgstr "x-Bereich zu klein" +#: libvips/mosaicing/mosaic.c:282 +msgid "Detected rotation" +msgstr "" -#: libvips/histograms_lut/im_buildlut.c:278 -msgid "bad input matrix size" -msgstr "falsche Eingabematrix-Größe" +#: libvips/mosaicing/mosaic.c:288 libvips/mosaicing/mosaic.c:295 +msgid "First-order displacement" +msgstr "" -#: libvips/histograms_lut/tone.c:194 -msgid "bad in_max, out_max parameters" -msgstr "falsche »in_max«-, »out_max«-Parameter" +#: libvips/mosaicing/mosaic.c:289 libvips/mosaicing/mosaic.c:296 +msgid "Detected first-order displacement" +msgstr "" -#: libvips/histograms_lut/tone.c:199 -msgid "bad Lb, Lw parameters" -msgstr "falsche »Lb«-, »Lw«-Parameter" +#: libvips/mosaicing/remosaic.c:89 +#, c-format +msgid "file \"%s\" not found" +msgstr "Datei »%s« nicht gefunden" -#: libvips/histograms_lut/tone.c:204 -msgid "Ps not in range [0.0,1.0]" -msgstr "»Ps« nicht im Bereich [0.0,1.0]" +#: libvips/mosaicing/remosaic.c:117 +#, c-format +msgid "substitute image \"%s\" is not the same size as \"%s\"" +msgstr "Bild zum Ersetzen »%s« hat nicht die gleiche Größe wie »%s«" -#: libvips/histograms_lut/tone.c:209 -msgid "Pm not in range [0.0,1.0]" -msgstr "»Pm« nicht im Bereich [0.0,1.0]" +#: libvips/mosaicing/remosaic.c:160 +#, fuzzy +msgid "rebuild an mosaiced image" +msgstr "Bilddateien laden und speichern" -#: libvips/histograms_lut/tone.c:214 -msgid "Ph not in range [0.0,1.0]" -msgstr "»Ph« nicht im Bereich [0.0,1.0]" +#: libvips/mosaicing/remosaic.c:176 +msgid "old_str" +msgstr "" -#: libvips/histograms_lut/tone.c:219 -msgid "S not in range [-30,+30]" -msgstr "»S« nicht im Bereich [-30,+30]" +#: libvips/mosaicing/remosaic.c:177 +msgid "Search for this string" +msgstr "" -#: libvips/histograms_lut/tone.c:224 -msgid "M not in range [-30,+30]" -msgstr "»M« nicht im Bereich [-30,+30]" +#: libvips/mosaicing/remosaic.c:183 +msgid "new_str" +msgstr "" -#: libvips/histograms_lut/tone.c:229 -msgid "H not in range [-30,+30]" -msgstr "»H« nicht im Bereich [-30,+30]" +#: libvips/mosaicing/remosaic.c:184 +msgid "And swap for this string" +msgstr "" -#: libvips/histograms_lut/im_invertlut.c:132 -msgid "element out of range [0,1]" -msgstr "Element außerhalb des Bereichs [0,1]" +#: libvips/resample/affine.c:516 +msgid "output coordinates out of range" +msgstr "Ausgabekoordinaten außerhalb des Bereichs" -#: libvips/histograms_lut/im_invertlut.c:287 -msgid "bad input matrix" -msgstr "falsche Eingabematrix" +#: libvips/resample/affine.c:640 +#, fuzzy +msgid "affine transform of an image" +msgstr "Band aus einem Bild extrahieren" -#: libvips/histograms_lut/im_invertlut.c:292 -msgid "bad lut_size" -msgstr "falsche »lut_size«" +#: libvips/resample/affine.c:644 +msgid "Matrix" +msgstr "" -#: libvips/histograms_lut/im_maplut.c:97 -#, c-format -msgid "%d overflows detected" -msgstr "%d Überläufe entdeckt" +#: libvips/resample/affine.c:645 +msgid "Transformation matrix" +msgstr "" -#: libvips/inplace/im_draw_line.c:389 -msgid "mask image not 1 band 8 bit uncoded" -msgstr "Maskenbild nicht 8-Bit-kodiert mit einem Band" +#: libvips/resample/affine.c:657 +#, fuzzy +msgid "Output rect" +msgstr "Ausgabe" -#: libvips/inplace/im_draw_line.c:395 -msgid "ink image does not match in image" -msgstr "»ink«-Bild passt nicht in das Bild" +#: libvips/resample/affine.c:658 +msgid "Area of output to generate" +msgstr "" -#: libvips/inplace/im_draw_line.c:399 -msgid "ink image not 1x1 pixels" -msgstr "»ink«-Bild nicht 1x1 Bildpunkte" +#: libvips/resample/affine.c:664 libvips/resample/affine.c:671 +#: libvips/resample/similarity.c:140 libvips/resample/similarity.c:147 +#, fuzzy +msgid "Output offset" +msgstr "Ausgabewert" -#: libvips/iofuncs/sink.c:105 -#, c-format -msgid "stop function failed for image \"%s\"" -msgstr "»stop«-Funktion für Bild »%s« fehlgeschlagen" +#: libvips/resample/affine.c:665 libvips/resample/similarity.c:141 +msgid "Horizontal output displacement" +msgstr "" -#: libvips/iofuncs/sink.c:142 -#, c-format -msgid "start function failed for image \"%s\"" -msgstr "»start«-Funktion für Bild »%s« fehlgeschlagen" +#: libvips/resample/affine.c:672 libvips/resample/similarity.c:148 +msgid "Vertical output displacement" +msgstr "" -#: libvips/iofuncs/sink.c:175 -msgid "per-thread state for sink" -msgstr "Status pro Thread für »sink«" +#: libvips/resample/affine.c:678 libvips/resample/affine.c:685 +#: libvips/resample/resize.c:360 libvips/resample/resize.c:367 +#: libvips/resample/similarity.c:154 libvips/resample/similarity.c:161 +#, fuzzy +msgid "Input offset" +msgstr "Xoffset" -#: libvips/iofuncs/memory.c:295 libvips/iofuncs/memory.c:298 -#, c-format -msgid "out of memory --- size == %dMB" -msgstr "Hauptspeicher reicht nicht aus – Größe == %dMB" +#: libvips/resample/affine.c:679 libvips/resample/resize.c:361 +#: libvips/resample/similarity.c:155 +msgid "Horizontal input displacement" +msgstr "" -#: libvips/iofuncs/vips.c:286 -#, c-format -msgid "\"%s\" is not a VIPS image" -msgstr "»%s« ist kein VIPS-Bild" +#: libvips/resample/affine.c:686 libvips/resample/resize.c:368 +#: libvips/resample/similarity.c:162 +msgid "Vertical input displacement" +msgstr "" -#: libvips/iofuncs/vips.c:374 -msgid "unable to read history" -msgstr "Verlauf kann nicht gelesen werden" +#: libvips/resample/bicubic.cpp:629 +#, fuzzy +msgid "bicubic interpolation (Catmull-Rom)" +msgstr "doppelt kubische Interpolation (Catmull-Rom)" -#: libvips/iofuncs/vips.c:407 -msgid "more than a 10 megabytes of XML? sufferin' succotash!" -msgstr "mehr als 10 Megabyte XML? Leidende Succotash!" +#: libvips/resample/interpolate.c:185 +msgid "VIPS interpolators" +msgstr "VIPS-Interpolatoren" -#: libvips/iofuncs/vips.c:455 -msgid "incorrect namespace in XML" -msgstr "falscher Namensraum in XML" +#: libvips/resample/interpolate.c:361 +#, fuzzy +msgid "nearest-neighbour interpolation" +msgstr "Nächste-Nachbar-Interpolation" -#: libvips/iofuncs/vips.c:579 -msgid "error transforming from save format" -msgstr "Fehler beim Umwandeln vom gespeicherten Format" +#: libvips/resample/interpolate.c:579 +#, fuzzy +msgid "bilinear interpolation" +msgstr "Bilineare Interpolation" -#: libvips/iofuncs/vips.c:680 -#, c-format -msgid "unable to set property \"%s\" to value \"%s\"." -msgstr "Eigenschaft »%s« kann nicht auf Wert »%s« gesetzt werden." +#: libvips/resample/lbb.cpp:872 +#, fuzzy +msgid "reduced halo bicubic" +msgstr "doppelt kubische Halo-Reduzierung" -#: libvips/iofuncs/vips.c:728 -msgid "error transforming to save format" -msgstr "Fehler beim Umwandeln in das zu speichernde Format" +#: libvips/resample/mapim.c:551 +#, fuzzy +msgid "resample with a map image" +msgstr "ein Bild nachmachen" -#: libvips/iofuncs/vips.c:776 libvips/iofuncs/vips.c:973 -#: libvips/iofuncs/window.c:237 -msgid "file has been truncated" -msgstr "Datei wurde gekürzt" +#: libvips/resample/mapim.c:556 +msgid "Index pixels with this" +msgstr "" -#: libvips/iofuncs/vips.c:890 libvips/iofuncs/vips.c:899 -#: libvips/iofuncs/vips.c:922 -msgid "xml save error" -msgstr "XML-Fehler beim Speichern" +#: libvips/resample/nohalo.cpp:1551 +#, fuzzy +msgid "edge sharpening resampler with halo reduction" +msgstr "neues Kantenschärfungsmuster mit Halo-Reduzierung" -#: libvips/iofuncs/vips.c:959 -#, c-format -msgid "unable to read header for \"%s\"" -msgstr "Kopfdaten für »%s« können nicht gelesen werden" +#: libvips/resample/quadratic.c:269 +msgid "coefficient matrix must have width 2" +msgstr "" -#: libvips/iofuncs/vips.c:972 libvips/iofuncs/window.c:236 -#, c-format -msgid "unable to read data for \"%s\", %s" -msgstr "Daten für »%s« können nicht gelesen werden, %s" +#: libvips/resample/quadratic.c:291 +msgid "coefficient matrix must have height 1, 3, 4 or 6" +msgstr "" -#: libvips/iofuncs/vips.c:984 -#, c-format -msgid "error reading XML: %s" -msgstr "Fehler beim Lesen von XML: %s" +#: libvips/resample/quadratic.c:341 +msgid "resample an image with a quadratic transform" +msgstr "" -#: libvips/iofuncs/generate.c:606 -msgid "demand hint not set" -msgstr "Hinweisanfrage nicht gesetzt" +#: libvips/resample/quadratic.c:345 +msgid "Coeff" +msgstr "" -#: libvips/iofuncs/generate.c:625 libvips/iofuncs/generate.c:650 -msgid "generate() called twice" -msgstr "generate() zweimal aufgerufen" +#: libvips/resample/quadratic.c:346 +msgid "Coefficient matrix" +msgstr "" -#: libvips/iofuncs/generate.c:682 libvips/iofuncs/image.c:1873 -#, c-format -msgid "unable to output to a %s image" -msgstr "es kann nicht zu einem %s-Bild ausgegeben werden" +#: libvips/resample/quadratic.c:352 +msgid "Interpolate values with this" +msgstr "" -#: libvips/iofuncs/region.c:212 -#, c-format -msgid "start function failed for image %s" -msgstr "Startfunktion für Bild %s fehlgeschlagen" +#: libvips/resample/reduce.c:199 +#, fuzzy +msgid "reduce an image" +msgstr "ein Bild nachmachen" -#: libvips/iofuncs/region.c:528 libvips/iofuncs/region.c:598 -#: libvips/iofuncs/region.c:745 libvips/iofuncs/region.c:1241 -msgid "valid clipped to nothing" -msgstr "gültig an nichts angeklammert" +#: libvips/resample/reduce.c:205 libvips/resample/reduceh.cpp:586 +#: libvips/resample/shrink.c:149 libvips/resample/shrinkh.c:353 +#, fuzzy +msgid "Hshrink" +msgstr "verkleinern" -#: libvips/iofuncs/region.c:642 -msgid "bad image type" -msgstr "falscher Bildtyp" +#: libvips/resample/reduce.c:206 libvips/resample/reduce.c:236 +#: libvips/resample/reduceh.cpp:587 libvips/resample/reduceh.cpp:610 +#: libvips/resample/shrink.c:150 libvips/resample/shrink.c:166 +#: libvips/resample/shrinkh.c:354 libvips/resample/shrinkh.c:370 +#, fuzzy +msgid "Horizontal shrink factor" +msgstr "falscher Schrumpffaktor %d" -#: libvips/iofuncs/region.c:687 -msgid "no pixel data on attached image" -msgstr "keine Bildpunktdaten in angehängtem Bild" +#: libvips/resample/reduce.c:212 libvips/resample/reducev.cpp:1070 +#: libvips/resample/shrink.c:142 libvips/resample/shrinkv.c:427 +#, fuzzy +msgid "Vshrink" +msgstr "verkleinern" -#: libvips/iofuncs/region.c:693 -msgid "images do not match in pixel size" -msgstr "Bilder passen in der Bildpunktgröße nicht zusammen" +#: libvips/resample/reduce.c:213 libvips/resample/reduce.c:243 +#: libvips/resample/reducev.cpp:1071 libvips/resample/reducev.cpp:1094 +#: libvips/resample/shrink.c:143 libvips/resample/shrink.c:173 +#: libvips/resample/shrinkv.c:428 libvips/resample/shrinkv.c:444 +#, fuzzy +msgid "Vertical shrink factor" +msgstr "falscher Schrumpffaktor %d" -#: libvips/iofuncs/region.c:726 libvips/iofuncs/region.c:1223 -msgid "dest too small" -msgstr "Ziel zu klein" +#: libvips/resample/reduce.c:219 libvips/resample/reduceh.cpp:593 +#: libvips/resample/reducev.cpp:1077 libvips/resample/resize.c:343 +msgid "Kernel" +msgstr "" -#: libvips/iofuncs/region.c:813 -msgid "bad position" -msgstr "falsche Position" +#: libvips/resample/reduce.c:220 libvips/resample/reduceh.cpp:594 +#: libvips/resample/reducev.cpp:1078 libvips/resample/resize.c:344 +msgid "Resampling kernel" +msgstr "" -#: libvips/iofuncs/region.c:1102 libvips/iofuncs/region.c:1294 -#, c-format -msgid "unable to input from a %s image" -msgstr "Eingabe von einem %s-Bild nicht möglich" +#: libvips/resample/reduce.c:226 libvips/resample/reduceh.cpp:600 +#: libvips/resample/reducev.cpp:1084 libvips/resample/resize.c:350 +msgid "Gap" +msgstr "" -#: libvips/iofuncs/region.c:1126 -msgid "incomplete header" -msgstr "unvollständige Kopfzeilen" +#: libvips/resample/reduce.c:227 libvips/resample/reduceh.cpp:601 +#: libvips/resample/reducev.cpp:1085 libvips/resample/resize.c:351 +msgid "Reducing gap" +msgstr "" + +#: libvips/resample/reduce.c:235 libvips/resample/reduceh.cpp:609 +#: libvips/resample/shrink.c:165 libvips/resample/shrinkh.c:369 +#, fuzzy +msgid "Xshrink" +msgstr "verkleinern" -#: libvips/iofuncs/region.c:1197 -msgid "inappropriate region type" -msgstr "Ungeeigneter Regionstyp" +#: libvips/resample/reduce.c:242 libvips/resample/reducev.cpp:1093 +#: libvips/resample/shrink.c:172 libvips/resample/shrinkv.c:443 +#, fuzzy +msgid "Yshrink" +msgstr "verkleinern" -#: libvips/iofuncs/init.c:366 -msgid "evaluate with N concurrent threads" -msgstr "mit N gleichzeitigen Threads auswerten" +#: libvips/resample/reduce.c:251 libvips/resample/reduceh.cpp:618 +#: libvips/resample/reducev.cpp:1102 libvips/resample/resize.c:384 +msgid "Centre" +msgstr "" -#: libvips/iofuncs/init.c:369 -msgid "set tile width to N (DEBUG)" -msgstr "Bildbreite auf N setzen (DEBUG)" +#: libvips/resample/reduce.c:252 libvips/resample/reduceh.cpp:619 +#: libvips/resample/reducev.cpp:1103 libvips/resample/resize.c:385 +msgid "Use centre sampling convention" +msgstr "" -#: libvips/iofuncs/init.c:372 -msgid "set tile height to N (DEBUG)" -msgstr "Bildhöhe auf N setzen (DEBUG)" +#: libvips/resample/reduceh.cpp:414 libvips/resample/reducev.cpp:848 +#, fuzzy +msgid "reduce factor should be >= 1.0" +msgstr "Schrumpffaktoren sollten >=1 sein" -#: libvips/iofuncs/init.c:375 -msgid "set thinstrip height to N (DEBUG)" -msgstr "»thinstrip«-Höhe auf N setzen (DEBUG)" +#: libvips/resample/reduceh.cpp:437 libvips/resample/reducev.cpp:870 +#, fuzzy +msgid "reduce gap should be >= 1.0" +msgstr "Schrumpffaktoren sollten >=1 sein" -#: libvips/iofuncs/init.c:378 -msgid "set fatstrip height to N (DEBUG)" -msgstr "»fatstrip«-Höhe auf N setzen (DEBUG)" +#: libvips/resample/reduceh.cpp:467 libvips/resample/reducev.cpp:900 +#, fuzzy +msgid "reduce factor too large" +msgstr "Zoomfaktoren zu groß" -#: libvips/iofuncs/init.c:381 -msgid "show progress feedback" -msgstr "Fortschrittsrückmeldung anzeigen" +#: libvips/resample/reduceh.cpp:580 libvips/resample/shrinkh.c:347 +#, fuzzy +msgid "shrink an image horizontally" +msgstr "horizontal so oft wiederholen" -#: libvips/iofuncs/init.c:384 -msgid "leak-check on exit" -msgstr "Lückenprüfung beim Beenden" +#: libvips/resample/reducev.cpp:1064 libvips/resample/shrinkv.c:421 +#, fuzzy +msgid "shrink an image vertically" +msgstr "vertikal so oft wiederholen" -#: libvips/iofuncs/init.c:387 -msgid "images larger than N are decompressed to disc" -msgstr "Bilder, die größer als N sind, werden auf die Platte dekomprimiert" +#: libvips/resample/resample.c:136 +#, fuzzy +msgid "resample operations" +msgstr "arithmetische Transaktionen" -#: libvips/iofuncs/init.c:390 -msgid "disable vectorised versions of operations" -msgstr "vektorgesteuerte Versionen von Transaktionen deaktivieren" +#: libvips/resample/resize.c:323 +#, fuzzy +msgid "resize an image" +msgstr "ein Bild nachmachen" -#: libvips/iofuncs/init.c:393 -msgid "cache at most N operations" -msgstr "höchstens N Transaktionen zwischenspeichern" +#: libvips/resample/resize.c:329 +#, fuzzy +msgid "Scale factor" +msgstr "Q-Faktor" -#: libvips/iofuncs/init.c:396 -msgid "cache at most N bytes in memory" -msgstr "höchstens N Byte zwischenspeichern" +#: libvips/resample/resize.c:330 +msgid "Scale image by this factor" +msgstr "" -#: libvips/iofuncs/init.c:399 -msgid "allow at most N open files" -msgstr "höchstens N offene Dateien erlauben" +#: libvips/resample/resize.c:336 +#, fuzzy +msgid "Vertical scale factor" +msgstr "vertikaler Versatz vom Ursprung" -#: libvips/iofuncs/init.c:402 -msgid "trace operation cache" -msgstr "Transaktionszwischenspeicher aufzeichnen" +#: libvips/resample/resize.c:337 +msgid "Vertical scale image by this factor" +msgstr "" -#: libvips/iofuncs/init.c:405 -msgid "dump operation cache on exit" -msgstr "Transaktionszwischenspeicher beim Beenden ausgeben" +#: libvips/resample/shrink.c:133 +#, fuzzy +msgid "shrink an image" +msgstr "ein Bild invertieren" -#: libvips/iofuncs/init.c:428 -msgid "VIPS Options" -msgstr "VIPS-Optionen" +#: libvips/resample/shrink.c:156 libvips/resample/shrinkh.c:360 +#: libvips/resample/shrinkv.c:434 +msgid "Ceil" +msgstr "" -#: libvips/iofuncs/init.c:428 -msgid "Show VIPS options" -msgstr "VIPS-Optionen anzeigen" +#: libvips/resample/shrink.c:157 libvips/resample/shrinkh.c:361 +#: libvips/resample/shrinkv.c:435 +#, fuzzy +msgid "Round-up output dimensions" +msgstr "falsche Abmessungen" -#: libvips/iofuncs/image.c:293 -msgid "unable to close fd" -msgstr "»fd« kann nicht geschlossen werden" +#: libvips/resample/shrinkh.c:283 libvips/resample/shrinkv.c:327 +msgid "shrink factors should be >= 1" +msgstr "Schrumpffaktoren sollten >=1 sein" -#: libvips/iofuncs/image.c:373 -#, c-format -msgid "%dx%d %s, %d band, %s" -msgid_plural "%dx%d %s, %d bands, %s" -msgstr[0] "%dx%d %s, %d Band, %s" -msgstr[1] "%dx%d %s, %d Bänder, %s" +#: libvips/resample/similarity.c:123 +msgid "base similarity transform" +msgstr "" -#: libvips/iofuncs/image.c:403 -#, c-format -msgid " %s, %d band, %s" -msgid_plural " %s, %d bands, %s" -msgstr[0] " %s, %d band, %s" -msgstr[1] " %s, %d Bänder, %s" +#: libvips/resample/similarity.c:197 +msgid "similarity transform of an image" +msgstr "" -#: libvips/iofuncs/image.c:529 -#, c-format -msgid "%s %s: %d threads, %d x %d tiles, groups of %d scanlines" -msgstr "%s %s: %d Threads, %d x %d Kacheln, Gruppen von %d Scan-Zeilen" +#: libvips/resample/similarity.c:201 +msgid "Scale by this factor" +msgstr "" -#: libvips/iofuncs/image.c:542 -#, c-format -msgid "%s %s: %d%% complete" -msgstr "%s %s: %d%% komplett" +#: libvips/resample/similarity.c:208 libvips/resample/similarity.c:277 +msgid "Rotate clockwise by this many degrees" +msgstr "" -#. Spaces at end help to erase the %complete message we overwrite. -#. -#: libvips/iofuncs/image.c:559 -#, c-format -msgid "%s %s: done in %ds \n" -msgstr "%s %s: Erledigt in %ds \n" +#: libvips/resample/similarity.c:273 +#, fuzzy +msgid "rotate an image by a number of degrees" +msgstr "Tangens des Bildes (Winkel in Grad)" -#: libvips/iofuncs/image.c:738 -#, c-format -msgid "unable to open \"%s\", file too short" -msgstr "»%s« kann nicht geöffnet werden, Datei zu klein" +#: libvips/resample/thumbnail.c:959 +#, fuzzy +msgid "thumbnail generation" +msgstr "- Miniaturansichten-Generator" -#: libvips/iofuncs/image.c:748 -#, c-format -msgid "%s is longer than expected" -msgstr "%s ist länger als erwartet" +#: libvips/resample/thumbnail.c:974 +#, fuzzy +msgid "Target width" +msgstr "Kachelbreite" -#: libvips/iofuncs/image.c:765 -#, c-format -msgid "bad mode \"%s\"" -msgstr "falscher Modus »%s«" +#: libvips/resample/thumbnail.c:975 +msgid "Size to this width" +msgstr "" -#: libvips/iofuncs/image.c:820 -msgid "image class" -msgstr "Bildklasse" +#: libvips/resample/thumbnail.c:981 +#, fuzzy +msgid "Target height" +msgstr "Kachelhöhe" -#: libvips/iofuncs/image.c:916 -msgid "Image filename" -msgstr "Bilddateiname" +#: libvips/resample/thumbnail.c:982 +#, fuzzy +msgid "Size to this height" +msgstr "Kachelhöhe" -#: libvips/iofuncs/image.c:922 -msgid "Mode" -msgstr "Modus" +#: libvips/resample/thumbnail.c:989 +msgid "Only upsize, only downsize, or both" +msgstr "" -#: libvips/iofuncs/image.c:923 -msgid "Open mode" -msgstr "Öffnen-Modus" +#: libvips/resample/thumbnail.c:995 +msgid "No rotate" +msgstr "" -#: libvips/iofuncs/image.c:929 -msgid "Kill" -msgstr "töten" +#: libvips/resample/thumbnail.c:996 +msgid "Don't use orientation tags to rotate image upright" +msgstr "" -#: libvips/iofuncs/image.c:930 -msgid "Block evaluation on this image" -msgstr "Blockauswertung dieses Bildes" +#: libvips/resample/thumbnail.c:1002 +msgid "Crop" +msgstr "" -#: libvips/iofuncs/image.c:936 -msgid "Demand style" -msgstr "Nachfragestil" +#: libvips/resample/thumbnail.c:1003 +msgid "Reduce to fill target rectangle, then crop" +msgstr "" -#: libvips/iofuncs/image.c:937 -msgid "Preferred demand style for this image" -msgstr "für dieses Bild bevorzugter Nachfragestil" +#: libvips/resample/thumbnail.c:1009 +#, fuzzy +msgid "Linear" +msgstr "Zeilen" -#: libvips/iofuncs/image.c:950 -msgid "Foreign buffer" -msgstr "Fremdpuffer" +#: libvips/resample/thumbnail.c:1010 +msgid "Reduce in linear light" +msgstr "" -#: libvips/iofuncs/image.c:951 -msgid "Pointer to foreign pixels" -msgstr "Puffer für fremde Bildpunkte" +#: libvips/resample/thumbnail.c:1016 +#, fuzzy +msgid "Import profile" +msgstr "Profil" -#: libvips/iofuncs/image.c:1215 -#, c-format -msgid "killed for image \"%s\"" -msgstr "für Bild »%s« abgeschossen" +#: libvips/resample/thumbnail.c:1017 +msgid "Fallback import profile" +msgstr "" -#: libvips/iofuncs/image.c:1815 -msgid "bad image descriptor" -msgstr "falscher Bild-Deskriptor" +#: libvips/resample/thumbnail.c:1023 +#, fuzzy +msgid "Export profile" +msgstr "Profil" -#: libvips/iofuncs/image.c:1917 -#, c-format -msgid "auto-rewind for %s failed" -msgstr "automatischer Rücklauf für %s fehlgeschlagen" +#: libvips/resample/thumbnail.c:1024 +msgid "Fallback export profile" +msgstr "" -#: libvips/iofuncs/image.c:1973 libvips/iofuncs/image.c:2168 -#: libvips/iofuncs/image.c:2185 -msgid "no image data" -msgstr "keine Bilddaten" +#: libvips/resample/thumbnail.c:1050 +#, fuzzy +msgid "Auto rotate" +msgstr "Winkel zum Drehen eines Bildes" -#: libvips/iofuncs/image.c:2041 libvips/iofuncs/image.c:2208 -msgid "image not readable" -msgstr "Bild nicht lesbar" +#: libvips/resample/thumbnail.c:1051 +msgid "Use orientation tags to rotate image upright" +msgstr "" -#: libvips/iofuncs/image.c:2062 libvips/iofuncs/image.c:2238 -#: libvips/iofuncs/image.c:2247 -msgid "image already written" -msgstr "Bild bereits geschrieben" +# http://www.dateiendung.com/format/mat +#: libvips/resample/thumbnail.c:1192 +#, fuzzy +msgid "generate thumbnail from file" +msgstr "Mat aus Datei laden" -#: libvips/iofuncs/image.c:2086 libvips/iofuncs/image.c:2259 -msgid "image not writeable" -msgstr "Bild nicht schreibbar" +#: libvips/resample/thumbnail.c:1199 +#, fuzzy +msgid "Filename to read from" +msgstr "Name der Datei, aus der geladen werden soll" -#: libvips/iofuncs/image.c:2132 -msgid "bad file type" -msgstr "falscher Dateityp" +#: libvips/resample/thumbnail.c:1439 +msgid "generate thumbnail from buffer" +msgstr "" -#: libvips/iofuncs/sinkscreen.c:185 -msgid "per-thread state for render" -msgstr "Status pro Thread für »render«" +#: libvips/resample/thumbnail.c:1452 libvips/resample/thumbnail.c:1665 +#, fuzzy +msgid "Extra options" +msgstr "unäre Transaktionen" -#: libvips/iofuncs/sinkscreen.c:537 libvips/iofuncs/sinkdisc.c:236 -#: libvips/iofuncs/threadpool.c:606 -msgid "unable to create thread" -msgstr "Thread kann nicht erstellt werden" +#: libvips/resample/thumbnail.c:1453 libvips/resample/thumbnail.c:1666 +msgid "Options that are passed on to the underlying loader" +msgstr "" -#: libvips/iofuncs/mapfile.c:130 libvips/iofuncs/mapfile.c:297 -msgid "unable to CreateFileMapping" -msgstr "»CreateFileMapping« nicht möglich" +#: libvips/resample/thumbnail.c:1652 +msgid "generate thumbnail from source" +msgstr "" -#: libvips/iofuncs/mapfile.c:138 libvips/iofuncs/mapfile.c:309 -msgid "unable to MapViewOfFile" -msgstr "»MapViewOfFile« nicht möglich" +#: libvips/resample/thumbnail.c:1776 +#, fuzzy +msgid "generate thumbnail from image" +msgstr "Band aus einem Bild extrahieren" -#: libvips/iofuncs/mapfile.c:178 -msgid "unable to mmap" -msgstr "»mmap« nicht möglich" +#: libvips/resample/vsqbs.cpp:378 +msgid "B-Splines with antialiasing smoothing" +msgstr "B-Splines mit Kantenglättung" -#: libvips/iofuncs/mapfile.c:179 +#: tools/vips.c:166 #, c-format -msgid "" -"map failed (%s), running very low on system resources, expect a crash soon" +msgid "'%s' is not the name of a vips class" msgstr "" -"»map« fehlgeschlagen (%s), die Systemressourcen werden knapp, ein Absturz " -"steht bevor" -#: libvips/iofuncs/mapfile.c:196 libvips/iofuncs/mapfile.c:303 -msgid "unable to UnmapViewOfFile" -msgstr "»UnmapViewOfFile« nicht möglich" +#: tools/vips.c:282 +#, fuzzy, c-format +msgid "'%s' is not the name of a vips operation" +msgstr "genannte VIPS-Transaktion ausführen" -#: libvips/iofuncs/mapfile.c:202 -msgid "unable to munmap file" -msgstr "»munmap« der Datei nicht möglich" +#: tools/vips.c:355 +#, c-format +msgid "no package or function \"%s\"" +msgstr "kein Paket oder Funktion »%s«" -#: libvips/iofuncs/mapfile.c:224 -msgid "file is less than 64 bytes" -msgstr "Datei ist weniger als 64 Byte groß" +#: tools/vips.c:584 +#, fuzzy +msgid "execute vips operation OPER" +msgstr "genannte VIPS-Transaktion ausführen" -#: libvips/iofuncs/mapfile.c:229 libvips/iofuncs/mapfile.c:263 -msgid "unable to get file status" -msgstr "Dateistatus kann nicht abgefragt werden" +#: tools/vips.c:627 +#, fuzzy +msgid "Operation help" +msgstr "Transaktion" -#: libvips/iofuncs/mapfile.c:235 -msgid "not a regular file" -msgstr "keine reguläre Datei" +#: tools/vips.c:706 +msgid "[ACTION] [OPTIONS] [PARAMETERS] - VIPS driver program" +msgstr "[AKTION] [OPTIONEN] [PARAMETER] - VIPS-Treiberprogramm" -#: libvips/iofuncs/mapfile.c:269 -msgid "unable to read data" -msgstr "Daten können nicht gelesen werden" +#: tools/vips.c:916 +#, c-format +msgid "unknown action \"%s\"" +msgstr "unbekannte Aktion »%s«" -#: libvips/iofuncs/mapfile.c:329 +#: tools/vipsedit.c:129 #, c-format -msgid "unable to mmap: \"%s\" - %s" -msgstr "»mmap« nicht möglich: \"%s\" - %s" +msgid "'%s' is not a positive integer" +msgstr "»%s« ist keine positive Ganzzahl" + +#: tools/vipsedit.c:142 +msgid "unable to start VIPS" +msgstr "VIPS kann nicht gestartet werden" + +#: tools/vipsedit.c:165 +#, fuzzy +msgid "vipsedit - edit vips file header" +msgstr "»vipsfile« - »vipsfile«-Kopfzeilen bearbeiten" -#: libvips/iofuncs/mapfile.c:339 +#: tools/vipsedit.c:193 +#, fuzzy, c-format +msgid "usage: %s [OPTION...] vips-file\n" +msgstr "Aufruf: %s [OPTION …] vipsfile\n" + +#: tools/vipsedit.c:200 #, c-format -msgid "unable to mmap \"%s\" to same address" -msgstr "»mmap %s« zur gleichen Adresse nicht möglich" +msgid "could not open image %s" +msgstr "Bild %s konnte nicht geöffnet werden" -#: libvips/iofuncs/base64.c:170 -msgid "too little data" -msgstr "zu wenige Daten" +#: tools/vipsedit.c:206 +#, c-format +msgid "could not read VIPS header for %s" +msgstr "VIPS-Kopfzeilen für %s konnten nicht gelesen werden" -#: libvips/iofuncs/object.c:148 +#: tools/vipsedit.c:216 #, c-format -msgid "parameter %s not set" -msgstr "Parameter %s nicht gesetzt" +msgid "bad endian-ness %s, should be 'big' or 'little'" +msgstr "falsche Byte-Reihenfolge %s, sollte »big« oder »little« sein" -#: libvips/iofuncs/object.c:505 +#: tools/vipsedit.c:230 #, c-format -msgid "no property named `%s'" -msgstr "keine Eigenschaft namens »%s«" +msgid "bad format %s" +msgstr "falsches Format %s" -#: libvips/iofuncs/object.c:513 +#: tools/vipsedit.c:244 #, c-format -msgid "no vips argument named `%s'" -msgstr "kein VIPS-Argument namens »%s«" +msgid "bad interpretation %s" +msgstr "falsche Interpretation »%s« " -#: libvips/iofuncs/object.c:520 +#: tools/vipsedit.c:254 #, c-format -msgid "argument `%s' has no instance" -msgstr "Argument »%s« hat keine Instanz" +msgid "bad coding %s" +msgstr "falsche Kodierung %s" -#: libvips/iofuncs/object.c:1248 libvips/iofuncs/operation.c:287 -#: libvips/resample/interpolate.c:615 +#: tools/vipsedit.c:268 #, c-format -msgid "class \"%s\" not found" -msgstr "Klasse »%s« nicht gefunden" +msgid "could not seek on %s" +msgstr "auf %s konnte nicht gesucht werden" -#: libvips/iofuncs/object.c:1297 -msgid "base class" -msgstr "Basisklasse" +#: tools/vipsedit.c:271 +#, c-format +msgid "could not write to %s" +msgstr "auf %s konnte nicht geschrieben werden" -#: libvips/iofuncs/object.c:1311 -msgid "Nickname" -msgstr "Nickname" +#: tools/vipsedit.c:278 +msgid "could not get ext data" +msgstr "zusätzliche Daten konnten nicht abgefragt werden" -#: libvips/iofuncs/object.c:1312 -msgid "Class nickname" -msgstr "Klassen-Nickname" +#: tools/vipsedit.c:287 +msgid "could not set extension" +msgstr "Erweiterung konnte nicht gesetzt werden" -#: libvips/iofuncs/object.c:1318 -msgid "Description" -msgstr "Beschreibung" +#: tools/vipsheader.c:221 +msgid "- print image header" +msgstr "- Bild-Kopfzeilen ausgeben" -#: libvips/iofuncs/object.c:1319 -msgid "Class description" -msgstr "Klassenbeschreibung" +#: tools/vipsthumbnail.c:447 +#, fuzzy +msgid "bad geometry spec" +msgstr "falsche Gittergeometrie" -#: libvips/iofuncs/object.c:1509 -#, c-format -msgid "enum '%s' has no member '%s'" -msgstr "Aufzählung »%s« hat keinen Bestandteil »%s«" +#: tools/vipsthumbnail.c:516 +msgid "- thumbnail generator" +msgstr "- Miniaturansichten-Generator" -#: libvips/iofuncs/object.c:1769 -#, c-format -msgid "unable to set '%s'" -msgstr "»%s« kann nicht gesetzt werden" +#~ msgid "coords outside image" +#~ msgstr "Koordinaten außerhalb des Bildes" -#: libvips/iofuncs/object.c:1777 -msgid "not , or ) after parameter" -msgstr "kein »,« oder »)« nach Parameter" +#~ msgid "absolute value" +#~ msgstr "absoluter Wert" -#: libvips/iofuncs/object.c:1784 -msgid "extra tokens after ')'" -msgstr "keine zusätzlichen Token nach »)«" +#~ msgid "average value of image" +#~ msgstr "Durchschnittswert des Bildes" -#. File length unit. -#. -#: libvips/iofuncs/buf.c:520 -msgid "bytes" -msgstr "Byte" - -#. Kilo byte unit. -#. -#: libvips/iofuncs/buf.c:524 -msgid "KB" -msgstr "KB" - -#. Mega byte unit. -#. -#: libvips/iofuncs/buf.c:528 -msgid "MB" -msgstr "MB" - -#. Giga byte unit. -#. -#: libvips/iofuncs/buf.c:532 -msgid "GB" -msgstr "GB" +# im_exptra() transforms element x of input to +# pow(e, x) in output. +#~ msgid "10^pel of image" +#~ msgstr "10^pel des Bildes" -#. Tera byte unit. -#. -#: libvips/iofuncs/buf.c:536 -msgid "TB" -msgstr "TB" +#~ msgid "e^pel of image" +#~ msgstr "e^pel des Bildes" -#: libvips/iofuncs/util.c:639 -msgid "unable to get file stats" -msgstr "Dateistatus kann nicht abgefragt werden" +#~ msgid "x^pel of image" +#~ msgstr "x^pel des Bildes" -#: libvips/iofuncs/util.c:656 libvips/iofuncs/sinkdisc.c:262 -msgid "write failed" -msgstr "Schreiben fehlgeschlagen" +#~ msgid "[x,y,z]^pel of image" +#~ msgstr "[x,y,z]^pel des Bildes" -#: libvips/iofuncs/util.c:720 -#, c-format -msgid "unable to open file \"%s\" for reading" -msgstr "Datei »%s« kann nicht zum Lesen geöffnet werden" +#~ msgid "photographic negative" +#~ msgstr "Fotonegativ" -#: libvips/iofuncs/util.c:742 -#, c-format -msgid "unable to open file \"%s\" for writing" -msgstr "Datei »%s« kann nicht zum Schreiben geöffnet werden" +#~ msgid "calculate a*in + b = outfile" +#~ msgstr "Berechnen von a*in + b = Ausgabedatei" -#: libvips/iofuncs/util.c:767 -#, c-format -msgid "\"%s\" too long" -msgstr "»%s« zu lang" +#~ msgid "vectors not equal length" +#~ msgstr "Vektoren ungleicher Länge" -#: libvips/iofuncs/util.c:784 -msgid "out of memory" -msgstr "Hauptspeicher reicht nicht aus" +#~ msgid "calculate a*in + b -> out, a and b vectors" +#~ msgstr "Berechnen von a*in + b -> out, a und b Vektoren" -#: libvips/iofuncs/util.c:810 -#, c-format -msgid "error reading from file \"%s\"" -msgstr "Fehler beim Lesen von Datei »%s«" +#~ msgid "log10 of image" +#~ msgstr "log10 des Bildes" + +#~ msgid "atan of image (result in degrees)" +#~ msgstr "Arkustangens des Bildes (Ergebnis in Grad)" + +#~ msgid "cos of image (angles in degrees)" +#~ msgstr "Kosinus des Bildes (Winkel in Grad)" + +#~ msgid "acos of image (result in degrees)" +#~ msgstr "Arkuskosinus des Bildes (Ergebnis in Grad)" + +# hinter diesem String folgt ein Flag. +#~ msgid "round to smallest integer value not less than" +#~ msgstr "auf kleinsten ganzzahligen Wert runden, nicht weniger als" + +# hinter diesem String folgt ein Flag. +#~ msgid "round to largest integer value not greater than" +#~ msgstr "auf größten ganzzahligen Wert runden, nicht größer als" + +# hinter diesem String folgt ein Flag. +#~ msgid "round to nearest integer value" +#~ msgstr "auf nächsten ganzzahligen Wert runden" + +#~ msgid "sin of image (angles in degrees)" +#~ msgstr "Sinus des Bildes (Winkel in Grad)" + +#~ msgid "average image bands" +#~ msgstr "durchschnittliche Bildbänder" + +#~ msgid "unit vector in direction of value" +#~ msgstr "Einheitsvektor in Richtung des Wertes" + +#~ msgid "asin of image (result in degrees)" +#~ msgstr "Arkussinus des Bildes (Ergebnis in Grad)" + +#~ msgid "position of maximum value of image, averaging in case of draw" +#~ msgstr "" +#~ "Position des Maximalwerts des Bildes, durchschnittlich im Fall des " +#~ "Zeichnens" + +#~ msgid "position and value of n maxima of image" +#~ msgstr "Position und Wert von n Maxima des Bildes" + +#~ msgid "position and value of n minima of image" +#~ msgstr "Position und Wert von n Minima des Bildes" + +#~ msgid "measure averages of a grid of patches" +#~ msgstr "Durchschnittsmaße eine Gitters aus Flickstücken" + +#~ msgid "remainder after integer division by a constant" +#~ msgstr "Rest nach Ganzzahldivision durch eine Konstante" + +#~ msgid "remainder after integer division by a vector of constants" +#~ msgstr "Rest nach Ganzzahldivision durch einen Vektor von Konstanten" -#: libvips/iofuncs/util.c:857 -#, c-format -msgid "write error (%zd out of %zd blocks written) ... disc full?" -msgstr "Schreibfehler (%zd aus %zd Blöcken geschrieben) … Platte voll?" +#~ msgid "pel^x of image" +#~ msgstr "pel^x des Bildes" -#: libvips/iofuncs/util.c:1106 libvips/iofuncs/util.c:1113 -msgid "unable to truncate" -msgstr "kann nicht gekürzt werden" +#~ msgid "pel^[x,y,z] of image" +#~ msgstr "pel^[x,y,z] des Bildes" -#: libvips/iofuncs/util.c:1297 -msgid "unexpected end of string" -msgstr "Unerwartetes Ende der Zeichenkette" +#~ msgid "many image statistics in one pass" +#~ msgstr "viele Bildstatistiken in einem Durchgang" -#: libvips/iofuncs/util.c:1315 -#, c-format -msgid "expected %s, saw %s" -msgstr "%s erwartet, %s gesehen" +#~ msgid "pixelwise linear regression" +#~ msgstr "bildpunktweise lineare Regression" -#: libvips/iofuncs/util.c:1485 -#, c-format -msgid "unable to make temporary file %s" -msgstr "temporäre Datei %s kann nicht erstellt werden" +#~ msgid "phase of cross power spectrum of two complex images" +#~ msgstr "Phase des Kreuzleistungsspektrums zweier komplexer Bilder" -#: libvips/iofuncs/operation.c:97 -msgid "input" -msgstr "Eingabe" +#~ msgid "single band images only" +#~ msgstr "nur Einzelbandbilder" -#: libvips/iofuncs/operation.c:97 -msgid "output" -msgstr "Ausgabe" +#~ msgid "uncoded images only" +#~ msgstr "nur unkodierte Bilder" -#: libvips/iofuncs/operation.c:246 -msgid "operations" -msgstr "Transaktionen" +#~ msgid "pow( left, right)" +#~ msgstr "pow( links, rechts)" -#: libvips/iofuncs/operation.c:273 -msgid "usage:" -msgstr "Aufruf:" +#~ msgid "pow( @in, @c )" +#~ msgstr "pow( @in, @c )" -#: libvips/iofuncs/operation.c:699 #, c-format -msgid "unknown argument '%s'" -msgstr "unbekanntes Argument »%s«" +#~ msgid "" +#~ "intent %d (%s) not supported by profile \"%s\"; falling back to default " +#~ "intent (usually PERCEPTUAL)" +#~ msgstr "" +#~ "Ziel-%d (%s) nicht von Profil »%s« unterstützt; Rückfall auf " +#~ "Standardabsicht (normalerweise WAHRNEHMUNG)" -#: libvips/iofuncs/operation.c:810 -msgid "too few arguments" -msgstr "zu wenige Argumente" +#~ msgid "CMYK input profile needs a 4 band input image" +#~ msgstr "CMYK-Eingabeprofil benötigt ein Eingabebild mit vier Bändern" -#: libvips/iofuncs/operation.c:931 -msgid "too many arguments" -msgstr "zu viele Argumente" +#~ msgid "RGB input profile needs a 3 band input image" +#~ msgstr "RGB-Eingabeprofil benötigt ein Eingabebild mit drei Bändern" -#: libvips/iofuncs/header.c:210 -#, c-format -msgid "unknown band format %d" -msgstr "unbekanntes Bandformat %d" +#~ msgid "uchar or ushort input only" +#~ msgstr "nur »uchar« oder »ushort«-Eingabe" -#: libvips/iofuncs/header.c:781 #, c-format -msgid "field \"%s\" not found" -msgstr "Feld »%s« nicht gefunden" +#~ msgid "" +#~ "intent %d (%s) not supported by profile; falling back to default intent " +#~ "(usually PERCEPTUAL)" +#~ msgstr "" +#~ "Ziel-%d (%s) nicht vom Profil unterstützt; Rückfall auf Standardabsicht " +#~ "(normalerweise WAHRNEHMUNG)" -#: libvips/iofuncs/header.c:949 -#, c-format -msgid "field \"%s\" is of type %s, not %s" -msgstr "Feld »%s« ist vom Typ %s, nicht %s" +#~ msgid "CMYK profile needs a 4 band input image" +#~ msgstr "CMYK-Profil benötigt ein Eingabebild mit vier Bändern" -#: libvips/iofuncs/sinkmemory.c:108 -msgid "per-thread state for sinkmemory" -msgstr "Status pro Thread für »sinkmemory«" +#~ msgid "RGB profile needs a 3 band input image" +#~ msgstr "RGB-Profil benötigt ein Eingabebild mit drei Bändern" -#: libvips/iofuncs/sinkdisc.c:121 -msgid "per-thread state for sinkdisc" -msgstr "Status pro Thread für »sinkdisc«" +#~ msgid "lcms library not linked to this VIPS" +#~ msgstr "gegen die »lcms«-Bibliothek wird in diesem VIPS nicht verlinkt" -#: libvips/iofuncs/error.c:210 -msgid "windows error" -msgstr "Windows-Fehler" +#~ msgid "lmcs library not linked to this VIPS" +#~ msgstr "gegen die »lmcs«-Bibliothek wird in diesem VIPS nicht verlinkt" -#: libvips/iofuncs/error.c:219 -msgid "unix error" -msgstr "Unix-Fehler" +#~ msgid "out of range [0,255]" +#~ msgstr "außerhalb des Bereichs [0,255]" -#: libvips/iofuncs/error.c:304 libvips/iofuncs/error.c:305 -#: libvips/iofuncs/error.c:354 libvips/iofuncs/error.c:355 -#, c-format -msgid "%s: " -msgstr "%s: " +#~ msgid "bad display type" +#~ msgstr "falsche Anzeigetyp" -#: libvips/iofuncs/error.c:304 -msgid "vips diagnostic" -msgstr "Vips-Diagnose" +#~ msgid "display unknown" +#~ msgstr "Anzeige unbekannt" -#: libvips/iofuncs/error.c:354 -msgid "vips warning" -msgstr "Vips-Warnung" +#~ msgid "input not 3-band uncoded char" +#~ msgstr "Eingabe ist kein unkodiertes Zeichen mit drei Bändern" -#: libvips/iofuncs/error.c:438 -msgid "image must be uncoded" -msgstr "Bild muss unkodiert sein" +#~ msgid "3-band uncoded float only" +#~ msgstr "nur unkodierte Fließkommazahlen mit drei Bändern" -#: libvips/iofuncs/error.c:466 -msgid "image coding must be NONE or LABQ" -msgstr "Bildkodierung muss NONE oder LABQ sein" +#~ msgid "bad greyscale mask size" +#~ msgstr "falsche Grauskala-Maskengröße" -#: libvips/iofuncs/error.c:494 -msgid "unknown image coding" -msgstr "unbekannte Bildkodierung" +#, c-format +#~ msgid "bad greyscale mask value, row %d" +#~ msgstr "falscher Grauskala-Maskenwert, Reihe %d" -#: libvips/iofuncs/error.c:520 -msgid "Radiance coding only" -msgstr "Nur Radiance-Kodierung" +#, c-format +#~ msgid "%d underflows and %d overflows detected" +#~ msgstr "%d Unter- und %d Überläufe entdeckt" -#: libvips/iofuncs/error.c:546 -msgid "LABQ coding only" -msgstr "Nur LABQ-Kodierung" +#~ msgid "pangoft2 support disabled" +#~ msgstr "Pangoft2-Unterstützung deaktiviert" -#: libvips/iofuncs/error.c:570 -msgid "image must one band" -msgstr "Bild muss ein Band haben" +#~ msgid "zoom factors should be >= 0" +#~ msgstr "Zoomfaktoren sollten >=0 sein" -#: libvips/iofuncs/error.c:595 -#, c-format -msgid "image must have %d bands" -msgstr "Bild muss %d Bänder haben" +#~ msgid "vectors not same length" +#~ msgstr "Vektoren ungleicher Länge" -#: libvips/iofuncs/error.c:620 -msgid "image must have one or three bands" -msgstr "Bild muss ein oder drei Bänder haben" +#~ msgid "direction" +#~ msgstr "Richtung" -#: libvips/iofuncs/error.c:648 -msgid "images must have the same number of bands, or one must be single-band" -msgstr "" -"Bilder müssen die gleiche Anzahl Bänder haben oder eines muss ein Band haben" +#~ msgid "bad arguments" +#~ msgstr "falsche Argumente" -#: libvips/iofuncs/error.c:675 -#, c-format -msgid "image must have 1 or %d bands" -msgstr "Bild muss ein oder %d Bänder haben" +#~ msgid "image does not have that many bands" +#~ msgstr "Bild hat nicht so viele Bänder" -#: libvips/iofuncs/error.c:699 -msgid "image must be non-complex" -msgstr "Bild muss nicht-komplex sein" +#~ msgid "factors should both be >= 1" +#~ msgstr "beide Faktoren sollten >=1 sein" -#: libvips/iofuncs/error.c:723 -msgid "image must be complex" -msgstr "Bild muss komplex sein" +#~ msgid "parameters would result in zero size output image" +#~ msgstr "Parameter würden zu einem Ausgabebild der Größe Null führen" -#: libvips/iofuncs/error.c:749 #, c-format -msgid "image must be %s" -msgstr "Bild muss %s sein" +#~ msgid "%d overflows and %d underflows detected" +#~ msgstr "%d Über- und %d Unterläufe entdeckt" -#: libvips/iofuncs/error.c:774 -msgid "image must be integer" -msgstr "Bild muss ganzzahlig sein" +#~ msgid "expect 1xN or Nx1 input mask" +#~ msgstr "1xN- oder Nx1-Eingabemaske wird erwartet" -#: libvips/iofuncs/error.c:799 -msgid "image must be unsigned integer" -msgstr "Bild muss aus vorzeichenlosen Ganzzahlen bestehen" +# ref und in sind Objekte +#~ msgid "ref not smaller than or equal to in" +#~ msgstr "»ref« nicht kleiner oder gleich »in«" -#: libvips/iofuncs/error.c:827 -msgid "image must be 8- or 16-bit integer, signed or unsigned" -msgstr "" -"Bild muss aus 8- oder 16-Bit Ganzzahlen mit oder ohne Vorzeichen bestehen" +#~ msgid "end of file while skipping start" +#~ msgstr "Dateiende während des Überspringens des Startes" -#: libvips/iofuncs/error.c:854 -msgid "image must be 8- or 16-bit unsigned integer" -msgstr "Bild muss aus 8- oder 16-Bit vorzeichenlosen Ganzzahlen bestehen" +#, c-format +#~ msgid "unexpected EOF, line %d col %d" +#~ msgstr "unerwartetes Dateiende, Zeile %d, Spalte %d" -#: libvips/iofuncs/error.c:880 -msgid "image must be 8- or 16-bit unsigned integer, or float" -msgstr "" -"Bild muss aus 8- oder 16-Bit vorzeichenlosen Ganzzahlen oder " -"Fließkommazahlen bestehen" +#, c-format +#~ msgid "unexpected EOL, line %d col %d" +#~ msgstr "unerwartetes Zeilenende, Zeile %d, Spalte %d" -#: libvips/iofuncs/error.c:908 -msgid "image must be unsigned int or float" -msgstr "" -"Bild muss aus 8- oder 16-Bit vorzeichenlosen Ganz- oder Fließkommazahlen " -"bestehen" +#, c-format +#~ msgid "required field %d=%d, not %d" +#~ msgstr "benötigtes Feld %d=%d, nicht %d" -#: libvips/iofuncs/error.c:933 -msgid "images must match in size" -msgstr "Bilder müssen in der Größe passen" +#~ msgid "4 or 5 bands CMYK TIFF only" +#~ msgstr "nur CMYK-TIFF mit vier oder fünf Bändern" -#: libvips/iofuncs/error.c:959 -msgid "images must have the same number of bands" -msgstr "Bilder müssen die gleiche Anzahl Bänder haben" +#, c-format +#~ msgid "" +#~ "no resolution information for TIFF image \"%s\" -- defaulting to 1 pixel " +#~ "per mm" +#~ msgstr "" +#~ "Keine Auflösungsinformationen für TIFF-Bild »%s« – Standard auf 1 " +#~ "Bildpunkt pro mm" -#: libvips/iofuncs/error.c:1013 -msgid "images must have the same band format" -msgstr "Bilder müssen das gleiche Bandformat haben" +#, c-format +#~ msgid "unsupported sample format %d for lab image" +#~ msgstr "nicht unterstütztes Musterformat %d für LAB-Bild" -#: libvips/iofuncs/error.c:1039 -msgid "images must have the same coding" -msgstr "Bilder müssen die gleiche Kodierung haben" +#, c-format +#~ msgid "unsupported depth %d for LAB image" +#~ msgstr "nicht unterstützte Tiefe %d für LAB-Bild" -#: libvips/iofuncs/error.c:1064 #, c-format -msgid "vector must have 1 or %d elements" -msgstr "Vektor muss 1 oder %d Elemente haben" +#~ msgid "unsupported sample format %d for greyscale image" +#~ msgstr "nicht unterstütztes Musterformat %d für Graustufenbild" -#: libvips/iofuncs/error.c:1089 -msgid "histograms must have width or height 1" -msgstr "Histogramme müssen eine Breite oder Höhe von eins haben" +#, c-format +#~ msgid "unsupported depth %d for greyscale image" +#~ msgstr "nicht unterstützte Tiefe %d für Graustufenbild" -#: libvips/iofuncs/error.c:1094 -msgid "histograms must have not have more than 65536 elements" -msgstr "Histogramm dürfen nicht mehr als 65536 Elemente haben" +#, c-format +#~ msgid "unsupported sample format %d for rgb image" +#~ msgstr "nicht unterstütztes Musterformat %d für RGB-Bild" -#: libvips/iofuncs/error.c:1123 libvips/iofuncs/error.c:1151 -msgid "nonsense mask parameters" -msgstr "unsinnige Maskenparameter" +#, c-format +#~ msgid "unsupported depth %d for RGB image" +#~ msgstr "nicht unterstützte Tiefe %d für RGB-Bild" -#: libvips/iofuncs/error.c:1176 -msgid "mask must be 1D" -msgstr "Maske muss 1D sein" +#~ msgid "error writing output" +#~ msgstr "Fehler beim Schreiben der Ausgabe" -#: libvips/iofuncs/threadpool.c:217 -#, c-format -msgid "threads clipped to %d" -msgstr "Threads an %d angeheftet" +#~ msgid "File descriptor" +#~ msgstr "Datei-Deskriptor" -#: libvips/iofuncs/threadpool.c:281 -msgid "per-thread state for vipsthreadpool" -msgstr "Status pro Thread für »vipsthreadpool«" +#~ msgid "error setting JPEG resolution" +#~ msgstr "Fehler beim Setzen der JPEG-Auflösung" -#: libvips/morphology/im_profile.c:104 -msgid "dir not 0 or 1" -msgstr "»dir« nicht 0 oder 1" +#, c-format +#~ msgid "" +#~ "unable to ping file \"%s\"\n" +#~ "libMagick error: %s %s" +#~ msgstr "" +#~ "Datei »%s« kann nicht angepingt werden\n" +#~ "libMagick-Fehler: %s %s" -#: libvips/morphology/morphology.c:311 #, c-format -msgid "bad mask element (%d should be 0, 128 or 255)" -msgstr "falsches Maskenelement (%d sollte 0, 128 oder 255 sein)" +#~ msgid "unable to write \"%s\"" +#~ msgstr "»%s« kann nicht geschrieben werden" -#: libvips/morphology/im_zerox.c:141 -msgid "flag not -1 or 1" -msgstr "Schalter nicht -1 oder 1" +#~ msgid "error reading resolution" +#~ msgstr "Fehler beim Lesen der Auflösung" -#: libvips/morphology/im_zerox.c:145 -msgid "image too narrow" -msgstr "Bild zu schmal" +#~ msgid "bad int" +#~ msgstr "falsche Ganzzahl" -#: libvips/morphology/im_cntlines.c:81 -msgid "flag should be 0 (horizontal) or 1 (vertical)" -msgstr "Schalter sollte 0 (horizontal) oder 1 (vertikal) sein" +#~ msgid "bad float" +#~ msgstr "falsche Fließkommazahl" -#: libvips/morphology/im_rank.c:365 -msgid "image too small for window" -msgstr "Bild zu klein für Fenster" +#~ msgid "not whitespace before start of binary data" +#~ msgstr "kein Leerraum vor dem Start der binären Daten" -#: libvips/morphology/im_rank_image.c:303 -msgid "zero input images!" -msgstr "null Eingabebilder" +#~ msgid "write error ... disc full?" +#~ msgstr "Schreibfehler … Platte voll?" -#: libvips/morphology/im_rank_image.c:308 -#, c-format -msgid "index should be in range 0 - %d" -msgstr "Index sollte im Bereich 0 - %d liegen" +#~ msgid "binary >8 bit images must be float" +#~ msgstr "binäre Bilder >8 Bit müssen aus Fließkommazahlen bestehen" -#: libvips/mosaicing/im_lrmerge.c:213 libvips/mosaicing/im_lrmerge.c:262 -#: libvips/mosaicing/im_lrmerge.c:603 libvips/mosaicing/im_tbmerge.c:163 -#: libvips/mosaicing/im_tbmerge.c:217 libvips/mosaicing/im_tbmerge.c:535 -msgid "internal error" -msgstr "interner Fehler" +#~ msgid "layer buffer exhausted -- try making TIFF output tiles smaller" +#~ msgstr "" +#~ "Ebenenpuffer aufgebraucht – versuchen Sie die TIFF-Ausgabekacheln zu " +#~ "verkleinern" -#: libvips/mosaicing/im_lrmerge.c:703 -msgid "mwidth must be -1 or >= 0" -msgstr "»mwidth« muss -1 oder >= 0 sein" +#~ msgid "internal error #9876345" +#~ msgstr "interner Fehler #9876345" -#: libvips/mosaicing/im_lrmerge.c:732 -msgid "no overlap" -msgstr "kein Überlappen" +#~ msgid "can't have strip pyramid -- enabling tiling" +#~ msgstr "" +#~ "nicht ummantelte Pyramide nicht möglich – Zerteilung wird eingeschaltet" -#: libvips/mosaicing/im_lrmerge.c:803 libvips/mosaicing/im_tbmerge.c:634 -#: libvips/resample/im_affine.c:469 -msgid "unknown coding type" -msgstr "unbekannter Kodierungstyp" +#~ msgid "unsigned 8-bit int, 16-bit int, and 32-bit float only" +#~ msgstr "nur vorzeichenlose 8-Bit-Ganzzahl und 32-Bit-Fließkommazahl" -#: libvips/mosaicing/im_lrmerge.c:820 libvips/mosaicing/im_tbmerge.c:652 -msgid "too much overlap" -msgstr "zu viel Überlappung" +#~ msgid "1 to 5 bands only" +#~ msgstr "nur 1 bis 5 Bänder" -#: libvips/mosaicing/im_remosaic.c:104 -#, c-format -msgid "substitute image \"%s\" is not the same size as \"%s\"" -msgstr "Bild zum Ersetzen »%s« hat nicht die gleiche Größe wie »%s«" +#~ msgid "images do not match" +#~ msgstr "Bilder passen nicht zusammen" -#: libvips/mosaicing/im_tbmosaic.c:89 libvips/mosaicing/im_lrmosaic.c:113 -msgid "bad area parameters" -msgstr "falsche Bereichsparameter" +#~ msgid "mask sizes power of 2 only" +#~ msgstr "Maskengröße nur Potenzen von 2" -#: libvips/mosaicing/im_tbmosaic.c:110 libvips/mosaicing/im_lrmosaic.c:134 -msgid "overlap too small for search" -msgstr "Überlappen zu klein für Suche" +#~ msgid "unimplemented mask type" +#~ msgstr "nicht implementierter Maskentyp" -#: libvips/mosaicing/im_tbmosaic.c:143 libvips/mosaicing/im_lrmosaic.c:167 -msgid "unknown Coding type" -msgstr "unbekannter Kodierungstyp" +#~ msgid "bad args" +#~ msgstr "falsche Argumente" -#: libvips/mosaicing/im_chkpair.c:200 -msgid "inputs incompatible" -msgstr "Eingaben inkompatibel" +#~ msgid "bad args (f)" +#~ msgstr "falsche Argumente (f)" -#: libvips/mosaicing/im_chkpair.c:204 libvips/mosaicing/im_tbcalcon.c:102 -msgid "help!" -msgstr "Hilfe!" +#~ msgid "bad args (ac)" +#~ msgstr "falsche Argumente (ac)" -#: libvips/mosaicing/im_tbcalcon.c:116 -msgid "overlap too small" -msgstr "Überlappen zu schmal" +#~ msgid "dimension should be in (2,3)" +#~ msgstr "Dimension sollte in (2,3) liegen" -#: libvips/mosaicing/global_balance.c:145 -msgid "no matching '>'" -msgstr "kein passendes »>«" +#~ msgid "window too small" +#~ msgstr "Fenster zu klein" -#: libvips/mosaicing/global_balance.c:154 -msgid "too many items" -msgstr "zu viele Elemente" +#~ msgid "bad input matrix size" +#~ msgstr "falsche Eingabematrix-Größe" -# Propogate a transform down a tree. If dirty is set, we've been here before, -# so there is a doubling up of this node. If this is a leaf, then we have the -# same leaf twice (which, in fact, we can cope with); if this is a node, we -# have circularity. -#: libvips/mosaicing/global_balance.c:448 -msgid "circularity detected" -msgstr "Zirkularität entdeckt" +#~ msgid "bad in_max, out_max parameters" +#~ msgstr "falsche »in_max«-, »out_max«-Parameter" -#: libvips/mosaicing/global_balance.c:482 -#: libvips/mosaicing/global_balance.c:538 -#, c-format -msgid "image \"%s\" used twice as output" -msgstr "Bild »%s« zweimal als Ausgabe benutzt" +#~ msgid "bad Lb, Lw parameters" +#~ msgstr "falsche »Lb«-, »Lw«-Parameter" -#: libvips/mosaicing/global_balance.c:587 -msgid "bad number of args in join line" -msgstr "falsche Anzahl von Argumenten in »join«-Zeile" +#~ msgid "Ps not in range [0.0,1.0]" +#~ msgstr "»Ps« nicht im Bereich [0.0,1.0]" -#: libvips/mosaicing/global_balance.c:629 -msgid "bad number of args in join1 line" -msgstr "falsche Anzahl von Argumenten in »join1«-Zeile" +#~ msgid "Pm not in range [0.0,1.0]" +#~ msgstr "»Pm« nicht im Bereich [0.0,1.0]" -#: libvips/mosaicing/global_balance.c:665 -msgid "bad number of args in copy line" -msgstr "falsche Anzahl von Argumenten in »copy«-Zeile" +#~ msgid "Ph not in range [0.0,1.0]" +#~ msgstr "»Ph« nicht im Bereich [0.0,1.0]" -#: libvips/mosaicing/global_balance.c:723 -msgid "" -"mosaic root not found in desc file\n" -"is this really a mosaiced image?" -msgstr "" -"Mosaik-Wurzel nicht in Beschreibungsdatei gefunden\n" -"ist das wirklich ein Bild?" +#~ msgid "S not in range [-30,+30]" +#~ msgstr "»S« nicht im Bereich [-30,+30]" -#: libvips/mosaicing/global_balance.c:734 -msgid "more than one root" -msgstr "mehr als eine Wurzel" +#~ msgid "M not in range [-30,+30]" +#~ msgstr "»M« nicht im Bereich [-30,+30]" -#: libvips/mosaicing/im_avgdxdy.c:64 -msgid "no points to average" -msgstr "keine Punkte zum Mitteln" +#~ msgid "H not in range [-30,+30]" +#~ msgstr "»H« nicht im Bereich [-30,+30]" -#: libvips/mosaicing/im_lrcalcon.c:203 -msgid "overlap too small for your search size" -msgstr "Überlappen zu schmal für Ihre Suchgröße" +#~ msgid "bad lut_size" +#~ msgstr "falsche »lut_size«" + +#~ msgid "mask image not 1 band 8 bit uncoded" +#~ msgstr "Maskenbild nicht 8-Bit-kodiert mit einem Band" -#: libvips/mosaicing/im_lrcalcon.c:242 #, c-format -msgid "found %d tie-points, need at least %d" -msgstr "es wurden %d Verbindungspunkte gefunden, mindestens %d sind nötig" +#~ msgid "unable to set property \"%s\" to value \"%s\"." +#~ msgstr "Eigenschaft »%s« kann nicht auf Wert »%s« gesetzt werden." -#: libvips/mosaicing/im_lrcalcon.c:287 -msgid "not 1-band uchar image" -msgstr "kein »uchar«-Bild mit einem Band" +#, c-format +#~ msgid "start function failed for image %s" +#~ msgstr "Startfunktion für Bild %s fehlgeschlagen" -#: libvips/mosaicing/im_clinear.c:136 -msgid "im_invmat failed" -msgstr "»im_invmat« fehlgeschlagen" +#~ msgid "evaluate with N concurrent threads" +#~ msgstr "mit N gleichzeitigen Threads auswerten" -#: libvips/other/im_zone.c:80 -msgid "size must be even and positive" -msgstr "Größe muss gerade und positiv sein" +#~ msgid "set tile width to N (DEBUG)" +#~ msgstr "Bildbreite auf N setzen (DEBUG)" -#: libvips/other/im_sines.c:88 -msgid "wrong sizes" -msgstr "falsche Größen" +#~ msgid "set tile height to N (DEBUG)" +#~ msgstr "Bildhöhe auf N setzen (DEBUG)" -#: libvips/other/im_sines.c:101 -msgid "calloc failed" -msgstr "»calloc« fehlgeschlagen" +#~ msgid "set thinstrip height to N (DEBUG)" +#~ msgstr "»thinstrip«-Höhe auf N setzen (DEBUG)" -#: libvips/other/im_eye.c:83 -msgid "factor should be in [1,0)" -msgstr "Faktor sollte in [0,1) liegen" +#~ msgid "set fatstrip height to N (DEBUG)" +#~ msgstr "»fatstrip«-Höhe auf N setzen (DEBUG)" -#: libvips/resample/im_affine.c:410 -msgid "output coordinates out of range" -msgstr "Ausgabekoordinaten außerhalb des Bereichs" +#~ msgid "show progress feedback" +#~ msgstr "Fortschrittsrückmeldung anzeigen" -#: libvips/resample/im_shrink.c:346 -msgid "shrink factors should be >= 1" -msgstr "Schrumpffaktoren sollten >=1 sein" +#~ msgid "leak-check on exit" +#~ msgstr "Lückenprüfung beim Beenden" -#: libvips/resample/interpolate.c:180 -msgid "VIPS interpolators" -msgstr "VIPS-Interpolatoren" +#~ msgid "images larger than N are decompressed to disc" +#~ msgstr "Bilder, die größer als N sind, werden auf die Platte dekomprimiert" -#: libvips/resample/interpolate.c:361 -msgid "Nearest-neighbour interpolation" -msgstr "Nächste-Nachbar-Interpolation" +#~ msgid "disable vectorised versions of operations" +#~ msgstr "vektorgesteuerte Versionen von Transaktionen deaktivieren" -#: libvips/resample/interpolate.c:532 -msgid "Bilinear interpolation" -msgstr "Bilineare Interpolation" +#~ msgid "cache at most N operations" +#~ msgstr "höchstens N Transaktionen zwischenspeichern" -#: libvips/resample/im_rightshift_size.c:120 -msgid "shift by zero: falling back to im_copy" -msgstr "verschieben um Null: Rückfall auf »im_copy«" +#~ msgid "cache at most N bytes in memory" +#~ msgstr "höchstens N Byte zwischenspeichern" -#: libvips/resample/im_rightshift_size.c:124 -msgid "would result in zero size output image" -msgstr "würde in einem Ausgabebild der Größe Null resultieren" +#~ msgid "allow at most N open files" +#~ msgstr "höchstens N offene Dateien erlauben" -#: libvips/resample/im_rightshift_size.c:132 -msgid "image and band_fmt must match in sign" -msgstr "Bild und Band-Fmt müssen im Kennzeichen zusammenpassen" +#~ msgid "trace operation cache" +#~ msgstr "Transaktionszwischenspeicher aufzeichnen" -#: libvips/video/im_video_test.c:51 -msgid "error requested" -msgstr "Fehler abgefragt" +#~ msgid "dump operation cache on exit" +#~ msgstr "Transaktionszwischenspeicher beim Beenden ausgeben" -#: libvips/video/im_video_v4l1.c:241 -msgid "no file descriptor" -msgstr "kein Datei-Deskriptor" +#~ msgid "VIPS Options" +#~ msgstr "VIPS-Optionen" -#: libvips/video/im_video_v4l1.c:246 -#, c-format -msgid "ioctl(0x%x) failed: %s" -msgstr "ioctl(0x%x) fehlgeschlagen: %s" +#~ msgid "Show VIPS options" +#~ msgstr "VIPS-Optionen anzeigen" -#: libvips/video/im_video_v4l1.c:295 #, c-format -msgid "cannot open video device \"%s\"" -msgstr "Videogerät »%s« kann nicht geöffnet werden" - -#: libvips/video/im_video_v4l1.c:303 -msgid "cannot get video capability" -msgstr "Videofähigkeit kann nicht abgefragt werden" +#~ msgid "%dx%d %s, %d band, %s" +#~ msgid_plural "%dx%d %s, %d bands, %s" +#~ msgstr[0] "%dx%d %s, %d Band, %s" +#~ msgstr[1] "%dx%d %s, %d Bänder, %s" -#: libvips/video/im_video_v4l1.c:312 -msgid "card cannot capture to memory" -msgstr "Karte kann nicht in Speicher digitalisiert werden" - -#: libvips/video/im_video_v4l1.c:458 -msgid "unable to map memory" -msgstr "Speicher kann nicht abgebildet werden" +#, c-format +#~ msgid " %s, %d band, %s" +#~ msgid_plural " %s, %d bands, %s" +#~ msgstr[0] " %s, %d band, %s" +#~ msgstr[1] " %s, %d Bänder, %s" -#: libvips/video/im_video_v4l1.c:470 #, c-format -msgid "channel not between 0 and %d" -msgstr "Kanal nicht zwischen 0 und %d" +#~ msgid "" +#~ "map failed (%s), running very low on system resources, expect a crash soon" +#~ msgstr "" +#~ "»map« fehlgeschlagen (%s), die Systemressourcen werden knapp, ein Absturz " +#~ "steht bevor" -#: libvips/video/im_video_v4l1.c:698 -msgid "compiled without im_video_v4l1 support" -msgstr "ohne »im_video_v4l1«-Unterstützung kompiliert" +#~ msgid "too little data" +#~ msgstr "zu wenige Daten" -#: tools/edvips.c:82 -msgid "tag file as big or little-endian" -msgstr "Kennzeichendatei als Big- oder Little-Endian" +#~ msgid "bytes" +#~ msgstr "Byte" -#: tools/edvips.c:84 -msgid "set width to N pixels" -msgstr "Breite auf N Bildpunkte setzen" +#~ msgid "KB" +#~ msgstr "KB" -#: tools/edvips.c:86 -msgid "set height to N pixels" -msgstr "Höhe auf N Bildpunkte setzen" +#~ msgid "MB" +#~ msgstr "MB" -#: tools/edvips.c:88 -msgid "set Bands to N" -msgstr "Bänder auf N setzen" +#~ msgid "TB" +#~ msgstr "TB" -#: tools/edvips.c:90 -msgid "set BandFmt to F (eg. uchar, float)" -msgstr "»BandFmt« auf F setzen (z.B. uchar, float)" +#, c-format +#~ msgid "unable to make temporary file %s" +#~ msgstr "temporäre Datei %s kann nicht erstellt werden" -#: tools/edvips.c:92 -msgid "set interpretation to I (eg. xyz)" -msgstr "Interpretation aif I setzen (z.B. xyz)" +#~ msgid "usage:" +#~ msgstr "Aufruf:" -#: tools/edvips.c:94 -msgid "set Coding to C (eg. labq)" -msgstr "Kodierung auf C setzen (z.B. labq)" +#, c-format +#~ msgid "%s: " +#~ msgstr "%s: " -#: tools/edvips.c:96 -msgid "set Xres to R pixels/mm" -msgstr "»Xres« auf R Bildpunkte/mm setzen" +#~ msgid "vips diagnostic" +#~ msgstr "Vips-Diagnose" -#: tools/edvips.c:98 -msgid "set Yres to R pixels/mm" -msgstr "»Yres« auf R Bildpunkte/mm setzen" +#~ msgid "vips warning" +#~ msgstr "Vips-Warnung" -#: tools/edvips.c:100 -msgid "set Xoffset to N pixels" -msgstr "»Xoffset« auf N Bildpunkte setzen" +#~ msgid "nonsense mask parameters" +#~ msgstr "unsinnige Maskenparameter" -#: tools/edvips.c:102 -msgid "set Yoffset to N pixels" -msgstr "»Yoffset« auf N Bildpunkte setzen" +#~ msgid "mask must be 1D" +#~ msgstr "Maske muss 1D sein" -#: tools/edvips.c:104 -msgid "replace extension block with stdin" -msgstr "Erweiterungsblock mit STDIN ersetzen" +#~ msgid "dir not 0 or 1" +#~ msgstr "»dir« nicht 0 oder 1" -#: tools/edvips.c:106 -msgid "set Xsize to N (deprecated, use width)" -msgstr "»Xsize« auf N setzen (missbilligt, benutzen Sie »width«)" +#~ msgid "flag should be 0 (horizontal) or 1 (vertical)" +#~ msgstr "Schalter sollte 0 (horizontal) oder 1 (vertikal) sein" -#: tools/edvips.c:108 -msgid "set Ysize to N (deprecated, use height)" -msgstr "»Ysize« auf N setzen (missbilligt, benutzen Sie »height«)" +#~ msgid "image too small for window" +#~ msgstr "Bild zu klein für Fenster" -#: tools/edvips.c:110 -msgid "set Type to T (deprecated, use interpretation)" -msgstr "Typ auf N setzen (missbilligt, benutzen Sie »interpretation«" +#~ msgid "zero input images!" +#~ msgstr "null Eingabebilder" -#: tools/edvips.c:121 #, c-format -msgid "'%s' is not a positive integer" -msgstr "»%s« ist keine positive Ganzzahl" +#~ msgid "index should be in range 0 - %d" +#~ msgstr "Index sollte im Bereich 0 - %d liegen" -#: tools/edvips.c:133 -msgid "unable to start VIPS" -msgstr "VIPS kann nicht gestartet werden" +#~ msgid "size must be even and positive" +#~ msgstr "Größe muss gerade und positiv sein" -#: tools/edvips.c:138 -msgid "vipsfile - edit vipsfile header" -msgstr "»vipsfile« - »vipsfile«-Kopfzeilen bearbeiten" +#~ msgid "wrong sizes" +#~ msgstr "falsche Größen" -#: tools/edvips.c:150 -#, c-format -msgid "usage: %s [OPTION...] vipsfile\n" -msgstr "Aufruf: %s [OPTION …] vipsfile\n" +#~ msgid "calloc failed" +#~ msgstr "»calloc« fehlgeschlagen" -#: tools/edvips.c:157 -#, c-format -msgid "could not open image %s" -msgstr "Bild %s konnte nicht geöffnet werden" +#~ msgid "factor should be in [1,0)" +#~ msgstr "Faktor sollte in [0,1) liegen" -#: tools/edvips.c:160 -#, c-format -msgid "could not read VIPS header for %s" -msgstr "VIPS-Kopfzeilen für %s konnten nicht gelesen werden" +#~ msgid "shift by zero: falling back to im_copy" +#~ msgstr "verschieben um Null: Rückfall auf »im_copy«" -#: tools/edvips.c:169 -#, c-format -msgid "bad endian-ness %s, should be 'big' or 'little'" -msgstr "falsche Byte-Reihenfolge %s, sollte »big« oder »little« sein" +#~ msgid "would result in zero size output image" +#~ msgstr "würde in einem Ausgabebild der Größe Null resultieren" -#: tools/edvips.c:182 -#, c-format -msgid "bad format %s" -msgstr "falsches Format %s" +#~ msgid "image and band_fmt must match in sign" +#~ msgstr "Bild und Band-Fmt müssen im Kennzeichen zusammenpassen" -#: tools/edvips.c:190 #, c-format -msgid "bad interpretation %s" -msgstr "falsche Interpretation »%s« " +#~ msgid "ioctl(0x%x) failed: %s" +#~ msgstr "ioctl(0x%x) fehlgeschlagen: %s" -#: tools/edvips.c:198 #, c-format -msgid "bad coding %s" -msgstr "falsche Kodierung %s" +#~ msgid "cannot open video device \"%s\"" +#~ msgstr "Videogerät »%s« kann nicht geöffnet werden" -#: tools/edvips.c:211 -#, c-format -msgid "could not seek on %s" -msgstr "auf %s konnte nicht gesucht werden" +#~ msgid "cannot get video capability" +#~ msgstr "Videofähigkeit kann nicht abgefragt werden" + +#~ msgid "card cannot capture to memory" +#~ msgstr "Karte kann nicht in Speicher digitalisiert werden" + +#~ msgid "unable to map memory" +#~ msgstr "Speicher kann nicht abgebildet werden" -#: tools/edvips.c:214 #, c-format -msgid "could not write to %s" -msgstr "auf %s konnte nicht geschrieben werden" +#~ msgid "channel not between 0 and %d" +#~ msgstr "Kanal nicht zwischen 0 und %d" -#: tools/edvips.c:221 -msgid "could not get ext data" -msgstr "zusätzliche Daten konnten nicht abgefragt werden" +#~ msgid "compiled without im_video_v4l1 support" +#~ msgstr "ohne »im_video_v4l1«-Unterstützung kompiliert" -#: tools/edvips.c:230 -msgid "could not set extension" -msgstr "Erweiterung konnte nicht gesetzt werden" +#~ msgid "tag file as big or little-endian" +#~ msgstr "Kennzeichendatei als Big- oder Little-Endian" -#: tools/find_mosaic.c:112 tools/find_mosaic.c:122 tools/find_mosaic.c:144 -#: tools/find_mosaic.c:154 tools/find_mosaic.c:163 tools/find_mosaic.c:184 -#: tools/find_mosaic.c:194 tools/find_mosaic.c:203 tools/mergeup.c:238 -#: tools/mergeup.c:248 tools/mergeup.c:270 tools/mergeup.c:280 -#: tools/mergeup.c:289 tools/mergeup.c:310 tools/mergeup.c:320 -#: tools/mergeup.c:329 -#, c-format -msgid "bad file name format '%s'" -msgstr "falsches Dateinamensformat »%s«" +#~ msgid "set width to N pixels" +#~ msgstr "Breite auf N Bildpunkte setzen" -#: tools/header.c:85 -msgid "show all fields" -msgstr "alle Felder anzeigen" +#~ msgid "set height to N pixels" +#~ msgstr "Höhe auf N Bildpunkte setzen" -#: tools/header.c:87 -msgid "" -"print value of FIELD (\"getext\" reads extension block, \"Hist\" reads image " -"history)" -msgstr "" -"Wert von FELD ausgeben (»getext« liest Erweiterungsblock, »Hist« liest " -"Bildchronik)" +#~ msgid "set BandFmt to F (eg. uchar, float)" +#~ msgstr "»BandFmt« auf F setzen (z.B. uchar, float)" -#: tools/header.c:210 -msgid "- print image header" -msgstr "- Bild-Kopfzeilen ausgeben" +#~ msgid "set interpretation to I (eg. xyz)" +#~ msgstr "Interpretation aif I setzen (z.B. xyz)" -#: tools/mergeup.c:381 -msgid "allocation failure in mergeup" -msgstr "Reservierung in »mergeup« gescheitert" +#~ msgid "set Coding to C (eg. labq)" +#~ msgstr "Kodierung auf C setzen (z.B. labq)" -#: tools/mergeup.c:391 -msgid "Need more than one image" -msgstr "Mehr als ein Bild benötigt" +#~ msgid "set Xres to R pixels/mm" +#~ msgstr "»Xres« auf R Bildpunkte/mm setzen" -#: tools/vips.c:101 -msgid "load PLUGIN" -msgstr "ERWEITERUNG laden" +#~ msgid "set Yres to R pixels/mm" +#~ msgstr "»Yres« auf R Bildpunkte/mm setzen" -#: tools/vips.c:102 -msgid "PLUGIN" -msgstr "ERWEITERUNG" +#~ msgid "set Xoffset to N pixels" +#~ msgstr "»Xoffset« auf N Bildpunkte setzen" -#: tools/vips.c:104 -msgid "print version" -msgstr "Version ausgeben" +#~ msgid "set Yoffset to N pixels" +#~ msgstr "»Yoffset« auf N Bildpunkte setzen" -#: tools/vips.c:147 -#, c-format -msgid "no package or function \"%s\"" -msgstr "kein Paket oder Funktion »%s«" +#~ msgid "replace extension block with stdin" +#~ msgstr "Erweiterungsblock mit STDIN ersetzen" -#: tools/vips.c:917 -msgid "list classes|packages|all|package-name|operation-name" -msgstr "classes|packages|all|package-name|operation-name aufführen" +#~ msgid "set Xsize to N (deprecated, use width)" +#~ msgstr "»Xsize« auf N setzen (missbilligt, benutzen Sie »width«)" -#: tools/vips.c:919 -msgid "generate headers for C++ binding" -msgstr "Header für C++-Anbindung erzeugen" +#~ msgid "set Ysize to N (deprecated, use height)" +#~ msgstr "»Ysize« auf N setzen (missbilligt, benutzen Sie »height«)" -#: tools/vips.c:921 -msgid "generate bodies for C++ binding" -msgstr "Rumpfdaten für C++-Anbindung erzeugen" +#~ msgid "set Type to T (deprecated, use interpretation)" +#~ msgstr "Typ auf N setzen (missbilligt, benutzen Sie »interpretation«" -#: tools/vips.c:923 -msgid "generate links for vips/bin" -msgstr "Verweise für VIPS/Bin erzeugen" +#, c-format +#~ msgid "bad file name format '%s'" +#~ msgstr "falsches Dateinamensformat »%s«" -#: tools/vips.c:1043 -msgid "[ACTION] [OPTIONS] [PARAMETERS] - VIPS driver program" -msgstr "[AKTION] [OPTIONEN] [PARAMETER] - VIPS-Treiberprogramm" +#~ msgid "show all fields" +#~ msgstr "alle Felder anzeigen" -#: tools/vips.c:1111 -msgid "possible actions:\n" -msgstr "mögliche Aktionen:\n" +#~ msgid "" +#~ "print value of FIELD (\"getext\" reads extension block, \"Hist\" reads " +#~ "image history)" +#~ msgstr "" +#~ "Wert von FELD ausgeben (»getext« liest Erweiterungsblock, »Hist« liest " +#~ "Bildchronik)" -#: tools/vips.c:1116 -msgid "execute named vips operation" -msgstr "genannte VIPS-Transaktion ausführen" +#~ msgid "allocation failure in mergeup" +#~ msgstr "Reservierung in »mergeup« gescheitert" -#: tools/vips.c:1118 -#, c-format -msgid "unknown action \"%s\"" -msgstr "unbekannte Aktion »%s«" +#~ msgid "Need more than one image" +#~ msgstr "Mehr als ein Bild benötigt" -#: tools/vipsthumbnail.c:54 -msgid "set thumbnail size to SIZE" -msgstr "Miniaturansicht auf GRÖẞE setzen" +#~ msgid "load PLUGIN" +#~ msgstr "ERWEITERUNG laden" -#: tools/vipsthumbnail.c:55 -msgid "SIZE" -msgstr "GRÖẞE" +#~ msgid "PLUGIN" +#~ msgstr "ERWEITERUNG" -#: tools/vipsthumbnail.c:57 -msgid "set output to FORMAT" -msgstr "Ausgabe auf FORMAT setzen" +#~ msgid "list classes|packages|all|package-name|operation-name" +#~ msgstr "classes|packages|all|package-name|operation-name aufführen" -#: tools/vipsthumbnail.c:58 -msgid "FORMAT" -msgstr "FORMAT" +#~ msgid "generate headers for C++ binding" +#~ msgstr "Header für C++-Anbindung erzeugen" -#: tools/vipsthumbnail.c:60 -msgid "resample with INTERPOLATOR" -msgstr "neues Muster mit INTERPOLATOR erstellen" +#~ msgid "generate bodies for C++ binding" +#~ msgstr "Rumpfdaten für C++-Anbindung erzeugen" -#: tools/vipsthumbnail.c:61 -msgid "INTERPOLATOR" -msgstr "INTERPOLATOR" +#~ msgid "generate links for vips/bin" +#~ msgstr "Verweise für VIPS/Bin erzeugen" -#: tools/vipsthumbnail.c:63 -msgid "don't sharpen thumbnail" -msgstr "Miniaturansicht nicht schärfen" +#~ msgid "possible actions:\n" +#~ msgstr "mögliche Aktionen:\n" -#: tools/vipsthumbnail.c:65 -msgid "export with PROFILE" -msgstr "mit PROFIL exportieren" +#~ msgid "SIZE" +#~ msgstr "GRÖẞE" -#: tools/vipsthumbnail.c:66 tools/vipsthumbnail.c:69 -msgid "PROFILE" -msgstr "PROFIL" +#~ msgid "set output to FORMAT" +#~ msgstr "Ausgabe auf FORMAT setzen" -#: tools/vipsthumbnail.c:68 -msgid "import untagged images with PROFILE" -msgstr "nicht gekennzeichnetes Bild mit PROFIL importieren" +#~ msgid "FORMAT" +#~ msgstr "FORMAT" -#: tools/vipsthumbnail.c:71 -msgid "don't delete profile from exported image" -msgstr "Profil aus exportiertem Bild nicht löschen" +#~ msgid "resample with INTERPOLATOR" +#~ msgstr "neues Muster mit INTERPOLATOR erstellen" -#: tools/vipsthumbnail.c:73 -msgid "verbose output" -msgstr "detaillierte Ausgabe" +#~ msgid "INTERPOLATOR" +#~ msgstr "INTERPOLATOR" -#: tools/vipsthumbnail.c:412 -msgid "- thumbnail generator" -msgstr "- Miniaturansichten-Generator" +#~ msgid "don't sharpen thumbnail" +#~ msgstr "Miniaturansicht nicht schärfen" -#: libvips/resample/bicubic.cpp:430 -msgid "Bicubic interpolation (Catmull-Rom)" -msgstr "doppelt kubische Interpolation (Catmull-Rom)" +#~ msgid "export with PROFILE" +#~ msgstr "mit PROFIL exportieren" -#: libvips/resample/nohalo.cpp:1577 -msgid "Edge sharpening resampler with halo reduction" -msgstr "neues Kantenschärfungsmuster mit Halo-Reduzierung" +#~ msgid "PROFILE" +#~ msgstr "PROFIL" -#: libvips/resample/vsqbs.cpp:400 -msgid "B-Splines with antialiasing smoothing" -msgstr "B-Splines mit Kantenglättung" +#~ msgid "import untagged images with PROFILE" +#~ msgstr "nicht gekennzeichnetes Bild mit PROFIL importieren" -#: libvips/resample/lbb.cpp:861 -msgid "Reduced halo bicubic" -msgstr "doppelt kubische Halo-Reduzierung" +#~ msgid "don't delete profile from exported image" +#~ msgstr "Profil aus exportiertem Bild nicht löschen" diff --git a/po/en_GB.po b/po/en_GB.po index 8a779a3d34..854155d0ed 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -1,6262 +1,7547 @@ # en_GB for vips - # Copyright (C) 2017 # This file is distributed under the same license as the vips package. # John Cupitt , 2017. # -#, fuzzy - msgid "" msgstr "" -"Project-Id-Version: vips 8.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-02-22 13:13+0000\n" -"PO-Revision-Date: \n" +"POT-Creation-Date: 2025-01-30 14:51+0000\n" "Last-Translator: John Cupitt \n" -"Language-Team: \n" "Language: en_GB\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../libvips/arithmetic/min.c:431 -msgid "find image minimum" +#: libvips/arithmetic/abs.c:200 +msgid "absolute value of an image" +msgstr "" + +#: libvips/arithmetic/add.c:178 +msgid "add two images" +msgstr "" + +#: libvips/arithmetic/arithmetic.c:392 +#, c-format +msgid "not one band or %d bands" +msgstr "" + +#: libvips/arithmetic/arithmetic.c:397 libvips/foreign/spngsave.c:423 +msgid "bad bands" +msgstr "" + +#: libvips/arithmetic/arithmetic.c:725 +msgid "arithmetic operations" msgstr "" -#: ../libvips/arithmetic/min.c:439 ../libvips/arithmetic/stats.c:420 -#: ../libvips/arithmetic/deviate.c:221 ../libvips/arithmetic/max.c:438 -#: ../libvips/arithmetic/hist_find_ndim.c:298 -#: ../libvips/arithmetic/measure.c:210 ../libvips/arithmetic/hist_find.c:450 -#: ../libvips/arithmetic/hough.c:185 ../libvips/arithmetic/arithmetic.c:639 -#: ../libvips/arithmetic/avg.c:214 -#: ../libvips/arithmetic/hist_find_indexed.c:391 ../libvips/colour/colour.c:427 -#: ../libvips/colour/sRGB2scRGB.c:249 ../libvips/colour/scRGB2BW.c:243 -#: ../libvips/colour/scRGB2sRGB.c:271 ../libvips/colour/colourspace.c:592 -#: ../libvips/conversion/conversion.c:200 -#: ../libvips/convolution/convolution.c:135 -#: ../libvips/convolution/gaussblur.c:125 ../libvips/convolution/sharpen.c:319 -#: ../libvips/convolution/correlation.c:163 ../libvips/create/create.c:101 -#: ../libvips/foreign/foreign.c:984 ../libvips/freqfilt/freqfilt.c:104 -#: ../libvips/histogram/hist_equal.c:114 ../libvips/histogram/stdif.c:300 -#: ../libvips/histogram/histogram.c:232 ../libvips/histogram/hist_entropy.c:119 -#: ../libvips/histogram/hist_norm.c:147 ../libvips/histogram/hist_plot.c:348 -#: ../libvips/histogram/hist_local.c:364 ../libvips/histogram/maplut.c:700 -#: ../libvips/iofuncs/system.c:284 ../libvips/morphology/morph.c:143 -#: ../libvips/morphology/rank.c:413 ../libvips/mosaicing/merge.c:121 -#: ../libvips/mosaicing/im_remosaic.c:170 -#: ../libvips/mosaicing/global_balance.c:1777 ../libvips/mosaicing/mosaic.c:192 -#: ../libvips/mosaicing/match.c:216 ../libvips/mosaicing/mosaic1.c:501 -#: ../libvips/resample/resample.c:138 ../libvips/resample/thumbnail.c:520 +#: libvips/arithmetic/arithmetic.c:731 libvips/arithmetic/avg.c:235 +#: libvips/arithmetic/deviate.c:237 libvips/arithmetic/hist_find.c:431 +#: libvips/arithmetic/hist_find_indexed.c:475 +#: libvips/arithmetic/hist_find_ndim.c:313 libvips/arithmetic/hough.c:179 +#: libvips/arithmetic/max.c:452 libvips/arithmetic/measure.c:201 +#: libvips/arithmetic/min.c:452 libvips/arithmetic/stats.c:442 +#: libvips/colour/CMYK2XYZ.c:126 libvips/colour/colour.c:415 +#: libvips/colour/colourspace.c:563 libvips/colour/scRGB2BW.c:243 +#: libvips/colour/scRGB2sRGB.c:276 libvips/colour/scRGB2XYZ.c:197 +#: libvips/colour/sRGB2scRGB.c:294 libvips/colour/XYZ2CMYK.c:125 +#: libvips/colour/XYZ2scRGB.c:206 libvips/conversion/conversion.c:346 +#: libvips/conversion/switch.c:202 libvips/convolution/canny.c:448 +#: libvips/convolution/convolution.c:134 libvips/convolution/correlation.c:162 +#: libvips/convolution/edge.c:223 libvips/convolution/gaussblur.c:138 +#: libvips/convolution/sharpen.c:328 libvips/create/create.c:124 +#: libvips/foreign/foreign.c:1215 libvips/freqfilt/freqfilt.c:104 +#: libvips/histogram/case.c:252 libvips/histogram/hist_entropy.c:117 +#: libvips/histogram/hist_equal.c:120 libvips/histogram/hist_local.c:367 +#: libvips/histogram/hist_norm.c:147 libvips/histogram/histogram.c:232 +#: libvips/histogram/hist_plot.c:339 libvips/histogram/maplut.c:750 +#: libvips/histogram/stdif.c:300 libvips/iofuncs/system.c:284 +#: libvips/morphology/morph.c:959 libvips/morphology/rank.c:564 +#: libvips/mosaicing/global_balance.c:1930 libvips/mosaicing/match.c:208 +#: libvips/mosaicing/matrixinvert.c:449 libvips/mosaicing/merge.c:134 +#: libvips/mosaicing/mosaic1.c:510 libvips/mosaicing/mosaic.c:191 +#: libvips/mosaicing/remosaic.c:170 libvips/resample/resample.c:146 +#: libvips/resample/thumbnail.c:968 msgid "Output" msgstr "" -#: ../libvips/arithmetic/min.c:440 ../libvips/arithmetic/deviate.c:222 -#: ../libvips/arithmetic/max.c:439 ../libvips/arithmetic/avg.c:215 -#: ../libvips/histogram/hist_entropy.c:120 +#: libvips/arithmetic/arithmetic.c:732 libvips/arithmetic/hough.c:180 +#: libvips/colour/CMYK2XYZ.c:127 libvips/colour/colour.c:416 +#: libvips/colour/colourspace.c:564 libvips/colour/scRGB2BW.c:244 +#: libvips/colour/scRGB2sRGB.c:277 libvips/colour/scRGB2XYZ.c:198 +#: libvips/colour/sRGB2scRGB.c:295 libvips/colour/XYZ2CMYK.c:126 +#: libvips/colour/XYZ2scRGB.c:207 libvips/conversion/conversion.c:347 +#: libvips/conversion/switch.c:203 libvips/convolution/canny.c:449 +#: libvips/convolution/convolution.c:135 libvips/convolution/correlation.c:163 +#: libvips/convolution/edge.c:224 libvips/convolution/gaussblur.c:139 +#: libvips/convolution/sharpen.c:329 libvips/create/create.c:125 +#: libvips/foreign/foreign.c:1216 libvips/freqfilt/freqfilt.c:105 +#: libvips/histogram/case.c:253 libvips/histogram/hist_equal.c:121 +#: libvips/histogram/hist_local.c:368 libvips/histogram/hist_norm.c:148 +#: libvips/histogram/histogram.c:233 libvips/histogram/hist_plot.c:340 +#: libvips/histogram/maplut.c:751 libvips/histogram/stdif.c:301 +#: libvips/iofuncs/system.c:285 libvips/morphology/morph.c:960 +#: libvips/morphology/rank.c:565 libvips/mosaicing/global_balance.c:1931 +#: libvips/mosaicing/match.c:209 libvips/mosaicing/merge.c:135 +#: libvips/mosaicing/mosaic1.c:511 libvips/mosaicing/mosaic.c:192 +#: libvips/mosaicing/remosaic.c:171 libvips/resample/resample.c:147 +#: libvips/resample/thumbnail.c:969 +msgid "Output image" +msgstr "" + +#: libvips/arithmetic/avg.c:227 +msgid "find image average" +msgstr "" + +#: libvips/arithmetic/avg.c:236 libvips/arithmetic/deviate.c:238 +#: libvips/arithmetic/max.c:453 libvips/arithmetic/min.c:453 +#: libvips/histogram/hist_entropy.c:118 msgid "Output value" msgstr "" -#: ../libvips/arithmetic/min.c:446 ../libvips/arithmetic/max.c:445 -#: ../libvips/arithmetic/getpoint.c:153 ../libvips/conversion/embed.c:569 -#: ../libvips/conversion/wrap.c:125 ../libvips/draw/draw_image.c:265 -#: ../libvips/draw/draw_mask.c:329 ../libvips/draw/draw_flood.c:552 -msgid "x" +#: libvips/arithmetic/binary.c:89 +msgid "binary operations" msgstr "" -#: ../libvips/arithmetic/min.c:447 -msgid "Horizontal position of minimum" +#: libvips/arithmetic/binary.c:96 libvips/arithmetic/find_trim.c:216 +#: libvips/arithmetic/measure.c:221 libvips/colour/colour.c:684 +#: libvips/conversion/extract.c:200 libvips/draw/draw_flood.c:593 +#: libvips/draw/draw_rect.c:173 libvips/draw/draw_smudge.c:215 +msgid "Left" msgstr "" -#: ../libvips/arithmetic/min.c:453 ../libvips/arithmetic/max.c:452 -#: ../libvips/arithmetic/getpoint.c:160 ../libvips/conversion/embed.c:576 -#: ../libvips/conversion/wrap.c:132 ../libvips/draw/draw_image.c:272 -#: ../libvips/draw/draw_mask.c:336 ../libvips/draw/draw_flood.c:559 -msgid "y" +#: libvips/arithmetic/binary.c:97 +msgid "Left-hand image argument" msgstr "" -#: ../libvips/arithmetic/min.c:454 -msgid "Vertical position of minimum" +#: libvips/arithmetic/binary.c:102 libvips/colour/colour.c:690 +msgid "Right" msgstr "" -#: ../libvips/arithmetic/min.c:460 ../libvips/arithmetic/max.c:459 -#: ../libvips/create/invertlut.c:295 ../libvips/create/identity.c:158 -msgid "Size" +#: libvips/arithmetic/binary.c:103 +msgid "Right-hand image argument" msgstr "" -#: ../libvips/arithmetic/min.c:461 -msgid "Number of minimum values to find" +#: libvips/arithmetic/boolean.c:269 +msgid "boolean operation on two images" msgstr "" -#: ../libvips/arithmetic/min.c:467 ../libvips/arithmetic/max.c:466 -#: ../libvips/arithmetic/getpoint.c:146 -msgid "Output array" +#: libvips/arithmetic/boolean.c:277 libvips/arithmetic/boolean.c:577 +#: libvips/arithmetic/complex.c:258 libvips/arithmetic/complex.c:538 +#: libvips/arithmetic/complex.c:771 libvips/arithmetic/math2.c:241 +#: libvips/arithmetic/math2.c:471 libvips/arithmetic/math.c:261 +#: libvips/arithmetic/relational.c:246 libvips/arithmetic/relational.c:611 +#: libvips/conversion/bandbool.c:238 tools/vips.c:627 +msgid "Operation" msgstr "" -#: ../libvips/arithmetic/min.c:468 ../libvips/arithmetic/max.c:467 -#: ../libvips/arithmetic/getpoint.c:147 -msgid "Array of output values" +#: libvips/arithmetic/boolean.c:278 libvips/arithmetic/boolean.c:578 +#: libvips/conversion/bandbool.c:239 +msgid "Boolean to perform" msgstr "" -#: ../libvips/arithmetic/min.c:474 ../libvips/arithmetic/max.c:473 -msgid "x array" +#: libvips/arithmetic/boolean.c:569 +msgid "boolean operations against a constant" msgstr "" -#: ../libvips/arithmetic/min.c:475 ../libvips/arithmetic/max.c:474 -msgid "Array of horizontal positions" +#: libvips/arithmetic/clamp.c:155 +msgid "clamp values of an image" msgstr "" -#: ../libvips/arithmetic/min.c:481 ../libvips/arithmetic/max.c:480 -msgid "y array" +#: libvips/arithmetic/clamp.c:162 +msgid "Min" msgstr "" -#: ../libvips/arithmetic/min.c:482 ../libvips/arithmetic/max.c:481 -msgid "Array of vertical positions" +#: libvips/arithmetic/clamp.c:163 +msgid "Minimum value" msgstr "" -#: ../libvips/arithmetic/sum.c:141 -msgid "sum an array of images" +#: libvips/arithmetic/clamp.c:169 +msgid "Max" msgstr "" -#: ../libvips/arithmetic/stats.c:412 ../libvips/arithmetic/avg.c:206 -msgid "find image average" +#: libvips/arithmetic/clamp.c:170 +msgid "Maximum value" msgstr "" -#: ../libvips/arithmetic/stats.c:421 ../libvips/arithmetic/measure.c:211 -msgid "Output array of statistics" +#: libvips/arithmetic/complex.c:251 +msgid "perform a complex operation on an image" msgstr "" -#: ../libvips/arithmetic/project.c:322 -msgid "find image projections" +#: libvips/arithmetic/complex.c:259 libvips/arithmetic/complex.c:772 +msgid "Complex to perform" msgstr "" -#: ../libvips/arithmetic/project.c:330 ../libvips/arithmetic/profile.c:300 -msgid "Columns" +#: libvips/arithmetic/complex.c:531 +msgid "complex binary operations on two images" msgstr "" -#: ../libvips/arithmetic/project.c:331 -msgid "Sums of columns" +#: libvips/arithmetic/complex.c:539 +msgid "Binary complex operation to perform" msgstr "" -#: ../libvips/arithmetic/project.c:336 ../libvips/arithmetic/profile.c:306 -msgid "Rows" +#: libvips/arithmetic/complex.c:762 +msgid "get a component from a complex image" msgstr "" -#: ../libvips/arithmetic/project.c:337 -msgid "Sums of rows" +#: libvips/arithmetic/complex.c:978 +msgid "form a complex image from two real images" msgstr "" -#: ../libvips/arithmetic/hough_line.c:135 -msgid "find hough line transform" +#: libvips/arithmetic/deviate.c:229 +msgid "find image standard deviation" msgstr "" -#: ../libvips/arithmetic/hough_line.c:142 ../libvips/arithmetic/measure.c:244 -#: ../libvips/conversion/embed.c:583 ../libvips/conversion/copy.c:284 -#: ../libvips/conversion/extract.c:219 ../libvips/create/xyz.c:193 -#: ../libvips/create/logmat.c:208 ../libvips/create/worley.c:310 -#: ../libvips/create/gaussnoise.c:172 ../libvips/create/perlin.c:297 -#: ../libvips/create/point.c:143 ../libvips/create/fractsurf.c:102 -#: ../libvips/create/text.c:297 ../libvips/create/black.c:129 -#: ../libvips/draw/draw_flood.c:593 ../libvips/foreign/rawload.c:123 -#: ../libvips/histogram/stdif.c:308 ../libvips/histogram/hist_local.c:370 -#: ../libvips/iofuncs/image.c:1130 ../libvips/morphology/rank.c:419 -msgid "Width" +#: libvips/arithmetic/divide.c:210 +msgid "divide two images" msgstr "" -#: ../libvips/arithmetic/hough_line.c:143 -msgid "horizontal size of parameter space" +#: libvips/arithmetic/find_trim.c:183 +msgid "search an image for non-edge areas" +msgstr "" + +#: libvips/arithmetic/find_trim.c:189 libvips/arithmetic/getpoint.c:153 +#: libvips/arithmetic/measure.c:195 libvips/arithmetic/nary.c:87 +#: libvips/arithmetic/statistic.c:167 libvips/arithmetic/unary.c:88 +#: libvips/colour/CMYK2XYZ.c:120 libvips/colour/colour.c:480 +#: libvips/colour/colour.c:573 libvips/colour/colourspace.c:557 +#: libvips/colour/scRGB2BW.c:237 libvips/colour/scRGB2sRGB.c:270 +#: libvips/colour/scRGB2XYZ.c:191 libvips/colour/sRGB2scRGB.c:288 +#: libvips/colour/XYZ2CMYK.c:119 libvips/colour/XYZ2scRGB.c:200 +#: libvips/conversion/addalpha.c:90 libvips/conversion/arrayjoin.c:394 +#: libvips/conversion/autorot.c:207 libvips/conversion/bandbool.c:232 +#: libvips/conversion/bandfold.c:161 libvips/conversion/bandjoin.c:201 +#: libvips/conversion/bandjoin.c:436 libvips/conversion/bandmean.c:212 +#: libvips/conversion/bandrank.c:254 libvips/conversion/bandunfold.c:164 +#: libvips/conversion/byteswap.c:238 libvips/conversion/cache.c:108 +#: libvips/conversion/cast.c:530 libvips/conversion/copy.c:271 +#: libvips/conversion/embed.c:568 libvips/conversion/extract.c:194 +#: libvips/conversion/extract.c:432 libvips/conversion/falsecolour.c:380 +#: libvips/conversion/flatten.c:419 libvips/conversion/flip.c:240 +#: libvips/conversion/gamma.c:142 libvips/conversion/grid.c:199 +#: libvips/conversion/msb.c:247 libvips/conversion/premultiply.c:261 +#: libvips/conversion/recomb.c:224 libvips/conversion/replicate.c:196 +#: libvips/conversion/rot45.c:268 libvips/conversion/rot.c:365 +#: libvips/conversion/scale.c:155 libvips/conversion/sequential.c:243 +#: libvips/conversion/smartcrop.c:433 libvips/conversion/subsample.c:267 +#: libvips/conversion/tilecache.c:398 libvips/conversion/transpose3d.c:167 +#: libvips/conversion/unpremultiply.c:323 libvips/conversion/wrap.c:119 +#: libvips/conversion/zoom.c:373 libvips/convolution/canny.c:442 +#: libvips/convolution/convolution.c:128 libvips/convolution/correlation.c:150 +#: libvips/convolution/edge.c:217 libvips/convolution/gaussblur.c:132 +#: libvips/convolution/sharpen.c:322 libvips/create/buildlut.c:263 +#: libvips/create/invertlut.c:288 libvips/foreign/foreign.c:1894 +#: libvips/freqfilt/freqfilt.c:98 libvips/histogram/hist_entropy.c:111 +#: libvips/histogram/hist_equal.c:114 libvips/histogram/hist_ismonotonic.c:118 +#: libvips/histogram/hist_local.c:361 libvips/histogram/hist_match.c:161 +#: libvips/histogram/hist_norm.c:141 libvips/histogram/hist_plot.c:333 +#: libvips/histogram/hist_unary.c:88 libvips/histogram/maplut.c:744 +#: libvips/histogram/percent.c:109 libvips/histogram/stdif.c:294 +#: libvips/iofuncs/ginputsource.c:274 libvips/iofuncs/sbuf.c:88 +#: libvips/iofuncs/system.c:277 libvips/morphology/morphology.c:121 +#: libvips/mosaicing/global_balance.c:1924 libvips/mosaicing/matrixinvert.c:443 +#: libvips/mosaicing/remosaic.c:164 libvips/resample/resample.c:140 +#: libvips/resample/thumbnail.c:1782 +msgid "Input" msgstr "" -#: ../libvips/arithmetic/hough_line.c:149 ../libvips/arithmetic/measure.c:251 -#: ../libvips/conversion/embed.c:590 ../libvips/conversion/copy.c:291 -#: ../libvips/conversion/extract.c:226 ../libvips/create/xyz.c:200 -#: ../libvips/create/worley.c:317 ../libvips/create/gaussnoise.c:179 -#: ../libvips/create/perlin.c:304 ../libvips/create/point.c:150 -#: ../libvips/create/fractsurf.c:109 ../libvips/create/black.c:136 -#: ../libvips/draw/draw_flood.c:600 ../libvips/foreign/rawload.c:130 -#: ../libvips/histogram/stdif.c:315 ../libvips/histogram/hist_local.c:377 -#: ../libvips/iofuncs/image.c:1137 ../libvips/morphology/rank.c:426 -msgid "Height" +#: libvips/arithmetic/find_trim.c:190 +msgid "Image to find_trim" msgstr "" -#: ../libvips/arithmetic/hough_line.c:150 -msgid "Vertical size of parameter space" +#: libvips/arithmetic/find_trim.c:195 libvips/histogram/percent.c:122 +msgid "Threshold" msgstr "" -#: ../libvips/arithmetic/binary.c:89 -msgid "binary operations" +#: libvips/arithmetic/find_trim.c:196 +msgid "Object threshold" msgstr "" -#: ../libvips/arithmetic/binary.c:96 ../libvips/arithmetic/measure.c:230 -#: ../libvips/colour/colour.c:699 ../libvips/conversion/extract.c:205 -#: ../libvips/draw/draw_smudge.c:197 ../libvips/draw/draw_flood.c:579 -#: ../libvips/draw/draw_rect.c:173 -msgid "Left" +#: libvips/arithmetic/find_trim.c:202 libvips/conversion/arrayjoin.c:415 +#: libvips/conversion/embed.c:595 libvips/conversion/flatten.c:425 +#: libvips/conversion/insert.c:499 libvips/conversion/join.c:270 +#: libvips/foreign/foreign.c:1908 libvips/foreign/pdfiumload.c:723 +#: libvips/foreign/popplerload.c:573 libvips/resample/affine.c:699 +#: libvips/resample/mapim.c:574 libvips/resample/similarity.c:133 +msgid "Background" msgstr "" -#: ../libvips/arithmetic/binary.c:97 -msgid "Left-hand image argument" +#: libvips/arithmetic/find_trim.c:203 libvips/conversion/embed.c:596 +msgid "Color for background pixels" msgstr "" -#: ../libvips/arithmetic/binary.c:102 ../libvips/colour/colour.c:705 -msgid "Right" +#: libvips/arithmetic/find_trim.c:209 +msgid "Line art mode" msgstr "" -#: ../libvips/arithmetic/binary.c:103 -msgid "Right-hand image argument" +#: libvips/arithmetic/find_trim.c:210 +msgid "Enable line art mode" msgstr "" -#: ../libvips/arithmetic/deviate.c:213 -msgid "find image standard deviation" +#: libvips/arithmetic/find_trim.c:217 +msgid "Left edge of image" msgstr "" -#: ../libvips/arithmetic/max.c:430 -msgid "find image maximum" +#: libvips/arithmetic/find_trim.c:223 libvips/arithmetic/measure.c:228 +#: libvips/conversion/extract.c:207 libvips/draw/draw_flood.c:600 +#: libvips/draw/draw_rect.c:180 libvips/draw/draw_smudge.c:222 +msgid "Top" msgstr "" -#: ../libvips/arithmetic/max.c:446 -msgid "Horizontal position of maximum" +#: libvips/arithmetic/find_trim.c:224 libvips/arithmetic/measure.c:229 +#: libvips/conversion/extract.c:208 +msgid "Top edge of extract area" msgstr "" -#: ../libvips/arithmetic/max.c:453 -msgid "Vertical position of maximum" +#: libvips/arithmetic/find_trim.c:230 libvips/arithmetic/hough_line.c:147 +#: libvips/arithmetic/measure.c:235 libvips/conversion/copy.c:284 +#: libvips/conversion/embed.c:574 libvips/conversion/extract.c:214 +#: libvips/conversion/smartcrop.c:439 libvips/create/black.c:140 +#: libvips/create/fractsurf.c:104 libvips/create/gaussnoise.c:167 +#: libvips/create/logmat.c:208 libvips/create/perlin.c:294 +#: libvips/create/point.c:141 libvips/create/sdf.c:304 +#: libvips/create/text.c:567 libvips/create/worley.c:307 +#: libvips/create/xyz.c:191 libvips/draw/draw_flood.c:607 +#: libvips/draw/draw_rect.c:187 libvips/draw/draw_smudge.c:229 +#: libvips/foreign/rawload.c:146 libvips/histogram/hist_local.c:373 +#: libvips/histogram/stdif.c:308 libvips/iofuncs/image.c:1102 +#: libvips/morphology/rank.c:570 +msgid "Width" msgstr "" -#: ../libvips/arithmetic/max.c:460 -msgid "Number of maximum values to find" +#: libvips/arithmetic/find_trim.c:231 libvips/arithmetic/measure.c:236 +#: libvips/conversion/extract.c:215 libvips/conversion/smartcrop.c:440 +msgid "Width of extract area" msgstr "" -#: ../libvips/arithmetic/statistic.c:161 -msgid "VIPS statistic operations" +#: libvips/arithmetic/find_trim.c:237 libvips/arithmetic/hough_line.c:154 +#: libvips/arithmetic/measure.c:242 libvips/conversion/copy.c:291 +#: libvips/conversion/embed.c:581 libvips/conversion/extract.c:221 +#: libvips/conversion/smartcrop.c:446 libvips/create/black.c:147 +#: libvips/create/fractsurf.c:111 libvips/create/gaussnoise.c:174 +#: libvips/create/perlin.c:301 libvips/create/point.c:148 +#: libvips/create/sdf.c:311 libvips/create/text.c:574 +#: libvips/create/worley.c:314 libvips/create/xyz.c:198 +#: libvips/draw/draw_flood.c:614 libvips/draw/draw_rect.c:194 +#: libvips/draw/draw_smudge.c:236 libvips/foreign/rawload.c:153 +#: libvips/histogram/hist_local.c:380 libvips/histogram/stdif.c:315 +#: libvips/iofuncs/image.c:1109 libvips/morphology/rank.c:577 +msgid "Height" msgstr "" -#: ../libvips/arithmetic/statistic.c:167 ../libvips/arithmetic/nary.c:87 -#: ../libvips/arithmetic/unary.c:88 ../libvips/colour/colour.c:493 -#: ../libvips/colour/colour.c:587 ../libvips/colour/sRGB2scRGB.c:243 -#: ../libvips/colour/scRGB2BW.c:237 ../libvips/colour/scRGB2sRGB.c:265 -#: ../libvips/colour/colourspace.c:586 ../libvips/conversion/embed.c:563 -#: ../libvips/conversion/zoom.c:383 ../libvips/conversion/replicate.c:196 -#: ../libvips/conversion/bandfold.c:160 ../libvips/conversion/wrap.c:119 -#: ../libvips/conversion/arrayjoin.c:304 -#: ../libvips/conversion/unpremultiply.c:268 ../libvips/conversion/flip.c:240 -#: ../libvips/conversion/flatten.c:386 ../libvips/conversion/copy.c:271 -#: ../libvips/conversion/bandjoin.c:176 ../libvips/conversion/bandjoin.c:395 -#: ../libvips/conversion/rot45.c:267 ../libvips/conversion/msb.c:244 -#: ../libvips/conversion/extract.c:199 ../libvips/conversion/extract.c:422 -#: ../libvips/conversion/cast.c:548 ../libvips/conversion/bandunfold.c:163 -#: ../libvips/conversion/tilecache.c:416 ../libvips/conversion/sequential.c:327 -#: ../libvips/conversion/premultiply.c:259 ../libvips/conversion/bandmean.c:198 -#: ../libvips/conversion/byteswap.c:206 ../libvips/conversion/subsample.c:274 -#: ../libvips/conversion/bandbool.c:214 ../libvips/conversion/recomb.c:207 -#: ../libvips/conversion/cache.c:101 ../libvips/conversion/grid.c:199 -#: ../libvips/conversion/scale.c:151 ../libvips/conversion/autorot.c:178 -#: ../libvips/conversion/rot.c:359 ../libvips/conversion/bandrank.c:244 -#: ../libvips/convolution/convolution.c:129 -#: ../libvips/convolution/gaussblur.c:119 ../libvips/convolution/sharpen.c:313 -#: ../libvips/convolution/correlation.c:151 ../libvips/create/invertlut.c:289 -#: ../libvips/create/buildlut.c:261 ../libvips/foreign/foreign.c:1522 -#: ../libvips/histogram/hist_match.c:161 ../libvips/histogram/hist_equal.c:108 -#: ../libvips/histogram/stdif.c:294 ../libvips/histogram/hist_entropy.c:113 -#: ../libvips/histogram/hist_ismonotonic.c:117 -#: ../libvips/histogram/hist_norm.c:141 ../libvips/histogram/hist_plot.c:342 -#: ../libvips/histogram/hist_unary.c:89 ../libvips/histogram/hist_local.c:358 -#: ../libvips/histogram/percent.c:110 ../libvips/histogram/maplut.c:694 -#: ../libvips/iofuncs/system.c:277 ../libvips/morphology/morphology.c:117 -#: ../libvips/mosaicing/im_remosaic.c:164 -#: ../libvips/mosaicing/global_balance.c:1771 -#: ../libvips/resample/resample.c:132 -msgid "Input" +#: libvips/arithmetic/find_trim.c:238 libvips/arithmetic/measure.c:243 +#: libvips/conversion/extract.c:222 libvips/conversion/smartcrop.c:447 +msgid "Height of extract area" msgstr "" -#: ../libvips/arithmetic/statistic.c:168 ../libvips/arithmetic/getpoint.c:141 -#: ../libvips/arithmetic/unary.c:89 ../libvips/colour/colour.c:494 -#: ../libvips/colour/colour.c:588 ../libvips/colour/sRGB2scRGB.c:244 -#: ../libvips/colour/scRGB2BW.c:238 ../libvips/colour/scRGB2sRGB.c:266 -#: ../libvips/colour/colourspace.c:587 ../libvips/conversion/embed.c:564 -#: ../libvips/conversion/zoom.c:384 ../libvips/conversion/replicate.c:197 -#: ../libvips/conversion/bandfold.c:161 ../libvips/conversion/wrap.c:120 -#: ../libvips/conversion/unpremultiply.c:269 ../libvips/conversion/flip.c:241 -#: ../libvips/conversion/flatten.c:387 ../libvips/conversion/copy.c:272 -#: ../libvips/conversion/bandjoin.c:396 ../libvips/conversion/rot45.c:268 -#: ../libvips/conversion/msb.c:245 ../libvips/conversion/extract.c:200 -#: ../libvips/conversion/extract.c:423 ../libvips/conversion/cast.c:549 -#: ../libvips/conversion/bandunfold.c:164 ../libvips/conversion/tilecache.c:417 -#: ../libvips/conversion/sequential.c:328 -#: ../libvips/conversion/premultiply.c:260 -#: ../libvips/conversion/falsecolour.c:382 ../libvips/conversion/byteswap.c:207 -#: ../libvips/conversion/subsample.c:275 ../libvips/conversion/gamma.c:144 -#: ../libvips/conversion/cache.c:102 ../libvips/conversion/grid.c:200 -#: ../libvips/conversion/scale.c:152 ../libvips/conversion/autorot.c:179 -#: ../libvips/conversion/rot.c:360 ../libvips/convolution/gaussblur.c:120 -#: ../libvips/convolution/sharpen.c:314 ../libvips/freqfilt/freqfilt.c:99 -#: ../libvips/histogram/hist_equal.c:109 ../libvips/histogram/stdif.c:295 -#: ../libvips/histogram/hist_norm.c:142 ../libvips/histogram/hist_plot.c:343 -#: ../libvips/histogram/hist_unary.c:90 ../libvips/histogram/hist_local.c:359 -#: ../libvips/histogram/percent.c:111 ../libvips/histogram/maplut.c:695 -#: ../libvips/mosaicing/im_remosaic.c:165 -#: ../libvips/mosaicing/global_balance.c:1772 +#: libvips/arithmetic/getpoint.c:149 +msgid "read a point from an image" +msgstr "" + +#: libvips/arithmetic/getpoint.c:154 libvips/arithmetic/statistic.c:168 +#: libvips/arithmetic/unary.c:89 libvips/colour/CMYK2XYZ.c:121 +#: libvips/colour/colour.c:481 libvips/colour/colour.c:574 +#: libvips/colour/colourspace.c:558 libvips/colour/scRGB2BW.c:238 +#: libvips/colour/scRGB2sRGB.c:271 libvips/colour/scRGB2XYZ.c:192 +#: libvips/colour/sRGB2scRGB.c:289 libvips/colour/XYZ2CMYK.c:120 +#: libvips/colour/XYZ2scRGB.c:201 libvips/conversion/addalpha.c:91 +#: libvips/conversion/autorot.c:208 libvips/conversion/bandfold.c:162 +#: libvips/conversion/bandjoin.c:437 libvips/conversion/bandunfold.c:165 +#: libvips/conversion/byteswap.c:239 libvips/conversion/cache.c:109 +#: libvips/conversion/cast.c:531 libvips/conversion/copy.c:272 +#: libvips/conversion/embed.c:569 libvips/conversion/extract.c:195 +#: libvips/conversion/extract.c:433 libvips/conversion/falsecolour.c:381 +#: libvips/conversion/flatten.c:420 libvips/conversion/flip.c:241 +#: libvips/conversion/gamma.c:143 libvips/conversion/grid.c:200 +#: libvips/conversion/msb.c:248 libvips/conversion/premultiply.c:262 +#: libvips/conversion/replicate.c:197 libvips/conversion/rot45.c:269 +#: libvips/conversion/rot.c:366 libvips/conversion/scale.c:156 +#: libvips/conversion/sequential.c:244 libvips/conversion/smartcrop.c:434 +#: libvips/conversion/subsample.c:268 libvips/conversion/tilecache.c:399 +#: libvips/conversion/transpose3d.c:168 libvips/conversion/unpremultiply.c:324 +#: libvips/conversion/wrap.c:120 libvips/conversion/zoom.c:374 +#: libvips/convolution/canny.c:443 libvips/convolution/edge.c:218 +#: libvips/convolution/gaussblur.c:133 libvips/convolution/sharpen.c:323 +#: libvips/freqfilt/freqfilt.c:99 libvips/histogram/hist_equal.c:115 +#: libvips/histogram/hist_local.c:362 libvips/histogram/hist_norm.c:142 +#: libvips/histogram/hist_plot.c:334 libvips/histogram/hist_unary.c:89 +#: libvips/histogram/maplut.c:745 libvips/histogram/percent.c:110 +#: libvips/histogram/stdif.c:295 libvips/mosaicing/global_balance.c:1925 +#: libvips/mosaicing/remosaic.c:165 msgid "Input image" msgstr "" -#: ../libvips/arithmetic/nary.c:80 -msgid "nary operations" +#: libvips/arithmetic/getpoint.c:159 libvips/arithmetic/max.c:480 +#: libvips/arithmetic/min.c:480 +msgid "Output array" msgstr "" -#: ../libvips/arithmetic/nary.c:88 ../libvips/conversion/arrayjoin.c:305 -#: ../libvips/conversion/bandjoin.c:177 ../libvips/conversion/bandrank.c:245 -#: ../libvips/iofuncs/system.c:278 -msgid "Array of input images" +#: libvips/arithmetic/getpoint.c:160 libvips/arithmetic/max.c:481 +#: libvips/arithmetic/min.c:481 +msgid "Array of output values" msgstr "" -#: ../libvips/arithmetic/invert.c:165 -msgid "invert an image" +#: libvips/arithmetic/getpoint.c:166 libvips/arithmetic/max.c:459 +#: libvips/arithmetic/min.c:459 libvips/conversion/composite.cpp:1733 +#: libvips/conversion/embed.c:656 libvips/conversion/wrap.c:125 +#: libvips/draw/draw_flood.c:566 libvips/draw/draw_image.c:275 +#: libvips/draw/draw_mask.c:338 +msgid "x" msgstr "" -#: ../libvips/arithmetic/remainder.c:174 -msgid "remainder after integer division of two images" +#: libvips/arithmetic/getpoint.c:167 libvips/arithmetic/getpoint.c:174 +msgid "Point to read" msgstr "" -#: ../libvips/arithmetic/remainder.c:324 -msgid "remainder after integer division of an image and a constant" +#: libvips/arithmetic/getpoint.c:173 libvips/arithmetic/max.c:466 +#: libvips/arithmetic/min.c:466 libvips/conversion/composite.cpp:1740 +#: libvips/conversion/embed.c:663 libvips/conversion/wrap.c:132 +#: libvips/draw/draw_flood.c:573 libvips/draw/draw_image.c:282 +#: libvips/draw/draw_mask.c:345 +msgid "y" msgstr "" -#: ../libvips/arithmetic/boolean.c:210 -msgid "boolean operation on two images" +#: libvips/arithmetic/getpoint.c:180 +msgid "unpack_complex" msgstr "" -#: ../libvips/arithmetic/boolean.c:218 ../libvips/arithmetic/boolean.c:521 -#: ../libvips/arithmetic/relational.c:224 -#: ../libvips/arithmetic/relational.c:562 ../libvips/arithmetic/math2.c:205 -#: ../libvips/arithmetic/math2.c:404 ../libvips/arithmetic/complex.c:255 -#: ../libvips/arithmetic/complex.c:548 ../libvips/arithmetic/complex.c:763 -#: ../libvips/arithmetic/math.c:214 ../libvips/conversion/bandbool.c:220 -#: ../tools/vips.c:1070 -msgid "Operation" +#: libvips/arithmetic/getpoint.c:181 +msgid "Complex pixels should be unpacked" msgstr "" -#: ../libvips/arithmetic/boolean.c:219 ../libvips/arithmetic/boolean.c:522 -#: ../libvips/conversion/bandbool.c:221 -msgid "boolean to perform" +#: libvips/arithmetic/hist_find.c:422 +msgid "find image histogram" msgstr "" -#: ../libvips/arithmetic/boolean.c:513 -msgid "boolean operations against a constant" +#: libvips/arithmetic/hist_find.c:432 +#: libvips/arithmetic/hist_find_indexed.c:476 +#: libvips/arithmetic/hist_find_ndim.c:314 +msgid "Output histogram" msgstr "" -#: ../libvips/arithmetic/sign.c:152 -msgid "unit vector of pixel" +#: libvips/arithmetic/hist_find.c:437 libvips/conversion/extract.c:438 +#: libvips/conversion/msb.c:253 libvips/histogram/hist_equal.c:126 +#: libvips/histogram/maplut.c:762 +msgid "Band" +msgstr "" + +#: libvips/arithmetic/hist_find.c:438 +msgid "Find histogram of band" +msgstr "" + +#: libvips/arithmetic/hist_find_indexed.c:461 +msgid "find indexed image histogram" +msgstr "" + +#: libvips/arithmetic/hist_find_indexed.c:469 libvips/conversion/bandrank.c:261 +#: libvips/histogram/case.c:239 libvips/morphology/rank.c:584 +#: libvips/resample/mapim.c:555 +msgid "Index" +msgstr "" + +#: libvips/arithmetic/hist_find_indexed.c:470 libvips/histogram/case.c:240 +msgid "Index image" +msgstr "" + +#: libvips/arithmetic/hist_find_indexed.c:481 libvips/convolution/compass.c:177 +msgid "Combine" +msgstr "" + +#: libvips/arithmetic/hist_find_indexed.c:482 +msgid "Combine bins like this" +msgstr "" + +#: libvips/arithmetic/hist_find_ndim.c:150 +msgid "image is not 1 - 3 bands" msgstr "" -#: ../libvips/arithmetic/hist_find_ndim.c:112 +#: libvips/arithmetic/hist_find_ndim.c:159 #, c-format msgid "bins out of range [1,%d]" msgstr "" -#: ../libvips/arithmetic/hist_find_ndim.c:289 +#: libvips/arithmetic/hist_find_ndim.c:304 msgid "find n-dimensional image histogram" msgstr "" -#: ../libvips/arithmetic/hist_find_ndim.c:299 -#: ../libvips/arithmetic/hist_find.c:451 -#: ../libvips/arithmetic/hist_find_indexed.c:392 -msgid "Output histogram" -msgstr "" - -#: ../libvips/arithmetic/hist_find_ndim.c:304 +#: libvips/arithmetic/hist_find_ndim.c:319 msgid "Bins" msgstr "" -#: ../libvips/arithmetic/hist_find_ndim.c:305 +#: libvips/arithmetic/hist_find_ndim.c:320 msgid "Number of bins in each dimension" msgstr "" -#: ../libvips/arithmetic/multiply.c:173 -msgid "multiply two images" +#: libvips/arithmetic/hough.c:170 +msgid "find hough transform" msgstr "" -#: ../libvips/arithmetic/hough_circle.c:113 +#: libvips/arithmetic/hough_circle.c:115 msgid "parameters out of range" msgstr "" -#: ../libvips/arithmetic/hough_circle.c:233 +#: libvips/arithmetic/hough_circle.c:226 msgid "find hough circle transform" msgstr "" -#: ../libvips/arithmetic/hough_circle.c:240 ../libvips/foreign/pdfload.c:489 -#: ../libvips/foreign/svgload.c:290 ../libvips/mosaicing/mosaic.c:275 -#: ../libvips/resample/similarity.c:171 +#: libvips/arithmetic/hough_circle.c:233 libvips/foreign/pdfiumload.c:716 +#: libvips/foreign/popplerload.c:566 libvips/foreign/svgload.c:724 +#: libvips/foreign/webpload.c:192 libvips/mosaicing/mosaic.c:274 +#: libvips/resample/similarity.c:200 msgid "Scale" msgstr "" -#: ../libvips/arithmetic/hough_circle.c:241 +#: libvips/arithmetic/hough_circle.c:234 msgid "Scale down dimensions by this factor" msgstr "" -#: ../libvips/arithmetic/hough_circle.c:247 +#: libvips/arithmetic/hough_circle.c:240 msgid "Min radius" msgstr "" -#: ../libvips/arithmetic/hough_circle.c:248 +#: libvips/arithmetic/hough_circle.c:241 msgid "Smallest radius to search for" msgstr "" -#: ../libvips/arithmetic/hough_circle.c:254 +#: libvips/arithmetic/hough_circle.c:247 msgid "Max radius" msgstr "" -#: ../libvips/arithmetic/hough_circle.c:255 +#: libvips/arithmetic/hough_circle.c:248 msgid "Largest radius to search for" msgstr "" -#: ../libvips/arithmetic/measure.c:168 -#, c-format -msgid "%s: patch %d x %d, band %d: avg = %g, sdev = %g" +#: libvips/arithmetic/hough_line.c:140 +msgid "find hough line transform" msgstr "" -#: ../libvips/arithmetic/measure.c:200 -msgid "measure a set of patches on a color chart" -msgstr "measure a set of patches on a colour chart" +#: libvips/arithmetic/hough_line.c:148 +msgid "Horizontal size of parameter space" +msgstr "" -#: ../libvips/arithmetic/measure.c:204 ../libvips/arithmetic/getpoint.c:140 -#: ../libvips/conversion/falsecolour.c:381 ../libvips/conversion/gamma.c:143 -#: ../libvips/freqfilt/freqfilt.c:98 -msgid "in" +#: libvips/arithmetic/hough_line.c:155 +msgid "Vertical size of parameter space" msgstr "" -#: ../libvips/arithmetic/measure.c:205 -msgid "Image to measure" +#: libvips/arithmetic/invert.c:178 +msgid "invert an image" msgstr "" -#: ../libvips/arithmetic/measure.c:216 ../libvips/conversion/replicate.c:202 -#: ../libvips/conversion/arrayjoin.c:311 ../libvips/conversion/grid.c:212 -msgid "Across" +#: libvips/arithmetic/linear.c:446 +msgid "calculate (a * in + b)" msgstr "" -#: ../libvips/arithmetic/measure.c:217 -msgid "Number of patches across chart" +#: libvips/arithmetic/linear.c:454 libvips/create/sdf.c:332 +msgid "a" msgstr "" -#: ../libvips/arithmetic/measure.c:223 ../libvips/conversion/replicate.c:209 -#: ../libvips/conversion/grid.c:219 -msgid "Down" +#: libvips/arithmetic/linear.c:455 +msgid "Multiply by this" msgstr "" -#: ../libvips/arithmetic/measure.c:224 -msgid "Number of patches down chart" +#: libvips/arithmetic/linear.c:461 libvips/create/sdf.c:339 +msgid "b" msgstr "" -#: ../libvips/arithmetic/measure.c:231 ../libvips/conversion/extract.c:206 -msgid "Left edge of extract area" +#: libvips/arithmetic/linear.c:462 +msgid "Add this" msgstr "" -#: ../libvips/arithmetic/measure.c:237 ../libvips/conversion/extract.c:212 -#: ../libvips/draw/draw_flood.c:586 -msgid "Top" +#: libvips/arithmetic/linear.c:468 +msgid "uchar" msgstr "" -#: ../libvips/arithmetic/measure.c:238 ../libvips/conversion/extract.c:213 -msgid "Top edge of extract area" +#: libvips/arithmetic/linear.c:469 +msgid "Output should be uchar" msgstr "" -#: ../libvips/arithmetic/measure.c:245 ../libvips/conversion/extract.c:220 -msgid "Width of extract area" +#: libvips/arithmetic/math2.c:233 +msgid "binary math operations" msgstr "" -#: ../libvips/arithmetic/measure.c:252 ../libvips/conversion/extract.c:227 -msgid "Height of extract area" +#: libvips/arithmetic/math2.c:242 libvips/arithmetic/math2.c:472 +#: libvips/arithmetic/math.c:262 +msgid "Math to perform" msgstr "" -#: ../libvips/arithmetic/hist_find.c:441 -msgid "find image histogram" +#: libvips/arithmetic/math2.c:463 +msgid "binary math operations with a constant" msgstr "" -#: ../libvips/arithmetic/hist_find.c:456 ../libvips/conversion/msb.c:250 -#: ../libvips/conversion/extract.c:428 ../libvips/histogram/hist_equal.c:120 -msgid "Band" +#: libvips/arithmetic/math.c:253 +msgid "apply a math operation to an image" msgstr "" -#: ../libvips/arithmetic/hist_find.c:457 -msgid "Find histogram of band" +#: libvips/arithmetic/max.c:444 +msgid "find image maximum" msgstr "" -#: ../libvips/arithmetic/getpoint.c:136 -msgid "read a point from an image" +#: libvips/arithmetic/max.c:460 +msgid "Horizontal position of maximum" msgstr "" -#: ../libvips/arithmetic/getpoint.c:154 ../libvips/arithmetic/getpoint.c:161 -msgid "Point to read" +#: libvips/arithmetic/max.c:467 +msgid "Vertical position of maximum" msgstr "" -#: ../libvips/arithmetic/add.c:172 -msgid "add two images" +#: libvips/arithmetic/max.c:473 libvips/arithmetic/min.c:473 +#: libvips/create/identity.c:157 libvips/create/invertlut.c:294 +#: libvips/resample/thumbnail.c:988 +msgid "Size" msgstr "" -#: ../libvips/arithmetic/divide.c:225 -msgid "divide two images" +#: libvips/arithmetic/max.c:474 +msgid "Number of maximum values to find" msgstr "" -#: ../libvips/arithmetic/relational.c:216 -msgid "relational operation on two images" +#: libvips/arithmetic/max.c:487 libvips/arithmetic/min.c:487 +msgid "x array" msgstr "" -#: ../libvips/arithmetic/relational.c:225 -#: ../libvips/arithmetic/relational.c:563 -msgid "relational to perform" +#: libvips/arithmetic/max.c:488 libvips/arithmetic/min.c:488 +msgid "Array of horizontal positions" msgstr "" -#: ../libvips/arithmetic/relational.c:553 -msgid "relational operations against a constant" +#: libvips/arithmetic/max.c:494 libvips/arithmetic/min.c:494 +msgid "y array" msgstr "" -#: ../libvips/arithmetic/hough.c:176 -msgid "find hough transform" +#: libvips/arithmetic/max.c:495 libvips/arithmetic/min.c:495 +msgid "Array of vertical positions" msgstr "" -#: ../libvips/arithmetic/hough.c:186 ../libvips/arithmetic/arithmetic.c:640 -#: ../libvips/colour/colour.c:428 ../libvips/colour/sRGB2scRGB.c:250 -#: ../libvips/colour/scRGB2BW.c:244 ../libvips/colour/scRGB2sRGB.c:272 -#: ../libvips/colour/colourspace.c:593 ../libvips/conversion/conversion.c:201 -#: ../libvips/convolution/convolution.c:136 -#: ../libvips/convolution/gaussblur.c:126 ../libvips/convolution/sharpen.c:320 -#: ../libvips/convolution/correlation.c:164 ../libvips/create/create.c:102 -#: ../libvips/foreign/foreign.c:985 ../libvips/freqfilt/freqfilt.c:105 -#: ../libvips/histogram/hist_equal.c:115 ../libvips/histogram/stdif.c:301 -#: ../libvips/histogram/histogram.c:233 ../libvips/histogram/hist_norm.c:148 -#: ../libvips/histogram/hist_plot.c:349 ../libvips/histogram/hist_local.c:365 -#: ../libvips/histogram/maplut.c:701 ../libvips/iofuncs/system.c:285 -#: ../libvips/morphology/morph.c:144 ../libvips/morphology/rank.c:414 -#: ../libvips/mosaicing/merge.c:122 ../libvips/mosaicing/im_remosaic.c:171 -#: ../libvips/mosaicing/global_balance.c:1778 ../libvips/mosaicing/mosaic.c:193 -#: ../libvips/mosaicing/match.c:217 ../libvips/mosaicing/mosaic1.c:502 -#: ../libvips/resample/resample.c:139 ../libvips/resample/thumbnail.c:521 -msgid "Output image" +#: libvips/arithmetic/maxpair.c:151 +msgid "maximum of a pair of images" msgstr "" -#: ../libvips/arithmetic/arithmetic.c:378 +#: libvips/arithmetic/measure.c:164 #, c-format -msgid "not one band or %d bands" +msgid "%s: patch %d x %d, band %d: avg = %g, sdev = %g" msgstr "" -#: ../libvips/arithmetic/arithmetic.c:382 -msgid "bad bands" +#: libvips/arithmetic/measure.c:191 +msgid "measure a set of patches on a color chart" +msgstr "measure a set of patches on a colour chart" + +#: libvips/arithmetic/measure.c:196 +msgid "Image to measure" msgstr "" -#: ../libvips/arithmetic/arithmetic.c:572 ../libvips/colour/colour.c:297 -#: ../libvips/conversion/bandary.c:140 ../libvips/conversion/bandrank.c:204 -msgid "too many input images" +#: libvips/arithmetic/measure.c:202 libvips/arithmetic/stats.c:443 +msgid "Output array of statistics" msgstr "" -#: ../libvips/arithmetic/arithmetic.c:633 -msgid "arithmetic operations" +#: libvips/arithmetic/measure.c:207 libvips/conversion/arrayjoin.c:401 +#: libvips/conversion/grid.c:212 libvips/conversion/replicate.c:202 +msgid "Across" msgstr "" -#: ../libvips/arithmetic/abs.c:230 -msgid "absolute value of an image" +#: libvips/arithmetic/measure.c:208 +msgid "Number of patches across chart" msgstr "" -#: ../libvips/arithmetic/linear.c:386 -msgid "calculate (a * in + b)" +#: libvips/arithmetic/measure.c:214 libvips/conversion/grid.c:219 +#: libvips/conversion/replicate.c:209 +msgid "Down" msgstr "" -#: ../libvips/arithmetic/linear.c:394 -msgid "a" +#: libvips/arithmetic/measure.c:215 +msgid "Number of patches down chart" msgstr "" -#: ../libvips/arithmetic/linear.c:395 -msgid "Multiply by this" +#: libvips/arithmetic/measure.c:222 libvips/conversion/extract.c:201 +msgid "Left edge of extract area" msgstr "" -#: ../libvips/arithmetic/linear.c:401 -msgid "b" +#: libvips/arithmetic/min.c:444 +msgid "find image minimum" msgstr "" -#: ../libvips/arithmetic/linear.c:402 -msgid "Add this" +#: libvips/arithmetic/min.c:460 +msgid "Horizontal position of minimum" msgstr "" -#: ../libvips/arithmetic/linear.c:408 -msgid "uchar" +#: libvips/arithmetic/min.c:467 +msgid "Vertical position of minimum" msgstr "" -#: ../libvips/arithmetic/linear.c:409 -msgid "Output should be uchar" +#: libvips/arithmetic/min.c:474 +msgid "Number of minimum values to find" msgstr "" -#: ../libvips/arithmetic/round.c:161 -msgid "perform a round function on an image" +#: libvips/arithmetic/minpair.c:151 +msgid "minimum of a pair of images" msgstr "" -#: ../libvips/arithmetic/round.c:169 -msgid "Round operation" +#: libvips/arithmetic/multiply.c:195 +msgid "multiply two images" msgstr "" -#: ../libvips/arithmetic/round.c:170 -msgid "rounding operation to perform" +#: libvips/arithmetic/nary.c:80 +msgid "nary operations" msgstr "" -#: ../libvips/arithmetic/math2.c:197 -msgid "binary math operations" +#: libvips/arithmetic/nary.c:88 libvips/conversion/arrayjoin.c:395 +#: libvips/conversion/bandjoin.c:202 libvips/conversion/bandrank.c:255 +#: libvips/conversion/composite.cpp:1581 libvips/iofuncs/system.c:278 +msgid "Array of input images" msgstr "" -#: ../libvips/arithmetic/math2.c:206 ../libvips/arithmetic/math2.c:405 -#: ../libvips/arithmetic/math.c:215 -msgid "math to perform" +#: libvips/arithmetic/profile.c:293 +msgid "find image profiles" msgstr "" -#: ../libvips/arithmetic/math2.c:396 -msgid "binary math operations with a constant" +#: libvips/arithmetic/profile.c:301 libvips/arithmetic/project.c:332 +msgid "Columns" msgstr "" -#: ../libvips/arithmetic/unaryconst.c:203 -msgid "unary operations with a constant" +#: libvips/arithmetic/profile.c:302 +msgid "First non-zero pixel in column" msgstr "" -#: ../libvips/arithmetic/unaryconst.c:207 -msgid "c" +#: libvips/arithmetic/profile.c:307 libvips/arithmetic/project.c:338 +msgid "Rows" msgstr "" -#: ../libvips/arithmetic/unaryconst.c:208 -msgid "Array of constants" +#: libvips/arithmetic/profile.c:308 +msgid "First non-zero pixel in row" msgstr "" -#: ../libvips/arithmetic/complex.c:248 -msgid "perform a complex operation on an image" +#: libvips/arithmetic/project.c:324 +msgid "find image projections" msgstr "" -#: ../libvips/arithmetic/complex.c:256 ../libvips/arithmetic/complex.c:764 -msgid "complex to perform" +#: libvips/arithmetic/project.c:333 +msgid "Sums of columns" msgstr "" -#: ../libvips/arithmetic/complex.c:541 -msgid "complex binary operations on two images" +#: libvips/arithmetic/project.c:339 +msgid "Sums of rows" msgstr "" -#: ../libvips/arithmetic/complex.c:549 -msgid "binary complex operation to perform" +#: libvips/arithmetic/relational.c:238 +msgid "relational operation on two images" msgstr "" -#: ../libvips/arithmetic/complex.c:754 -msgid "get a component from a complex image" +#: libvips/arithmetic/relational.c:247 libvips/arithmetic/relational.c:612 +msgid "Relational to perform" msgstr "" -#: ../libvips/arithmetic/complex.c:962 -msgid "form a complex image from two real images" +#: libvips/arithmetic/relational.c:603 +msgid "relational operations against a constant" msgstr "" -#: ../libvips/arithmetic/profile.c:292 -msgid "find image profiles" +#: libvips/arithmetic/remainder.c:192 +msgid "remainder after integer division of two images" msgstr "" -#: ../libvips/arithmetic/profile.c:301 -msgid "First non-zero pixel in column" +#: libvips/arithmetic/remainder.c:353 +msgid "remainder after integer division of an image and a constant" msgstr "" -#: ../libvips/arithmetic/profile.c:307 -msgid "First non-zero pixel in row" +#: libvips/arithmetic/round.c:173 +msgid "perform a round function on an image" msgstr "" -#: ../libvips/arithmetic/unary.c:81 -msgid "unary operations" +#: libvips/arithmetic/round.c:181 +msgid "Round operation" msgstr "" -#: ../libvips/arithmetic/subtract.c:162 -msgid "subtract two images" +#: libvips/arithmetic/round.c:182 +msgid "Rounding operation to perform" msgstr "" -#: ../libvips/arithmetic/hist_find_indexed.c:377 -msgid "find indexed image histogram" +#: libvips/arithmetic/sign.c:174 +msgid "unit vector of pixel" msgstr "" -#: ../libvips/arithmetic/hist_find_indexed.c:385 -#: ../libvips/conversion/bandrank.c:251 ../libvips/resample/mapim.c:412 -msgid "Index" +#: libvips/arithmetic/statistic.c:161 +msgid "VIPS statistic operations" msgstr "" -#: ../libvips/arithmetic/hist_find_indexed.c:386 -msgid "Index image" +#: libvips/arithmetic/stats.c:434 +msgid "find many image stats" msgstr "" -#: ../libvips/arithmetic/math.c:206 -msgid "apply a math operation to an image" +#: libvips/arithmetic/subtract.c:174 +msgid "subtract two images" msgstr "" -#: ../libvips/colour/LabQ2LabS.c:104 -msgid "unpack a LabQ image to short Lab" +#: libvips/arithmetic/sum.c:149 +msgid "sum an array of images" msgstr "" -#: ../libvips/colour/rad2float.c:188 -msgid "unpack Radiance coding to float RGB" +#: libvips/arithmetic/unary.c:81 +msgid "unary operations" msgstr "" -#: ../libvips/colour/XYZ2scRGB.c:105 -msgid "transform XYZ to scRGB" +#: libvips/arithmetic/unaryconst.c:138 +msgid "unary operations with a constant" msgstr "" -#: ../libvips/colour/Lab2LabS.c:80 -msgid "transform float Lab to signed short" +#: libvips/arithmetic/unaryconst.c:142 +msgid "c" msgstr "" -#: ../libvips/colour/LabS2LabQ.c:127 -msgid "transform short Lab to LabQ coding" +#: libvips/arithmetic/unaryconst.c:143 +msgid "Array of constants" msgstr "" -#: ../libvips/colour/float2rad.c:201 -msgid "transform float RGB to Radiance coding" +#: libvips/colour/CMYK2XYZ.c:114 libvips/colour/CMYK2XYZ.c:182 +msgid "transform CMYK to XYZ" msgstr "" -#: ../libvips/colour/scRGB2XYZ.c:90 -msgid "transform scRGB to XYZ" +#: libvips/colour/colour.c:288 +msgid "too many input images" msgstr "" -#: ../libvips/colour/LabQ2Lab.c:124 -msgid "unpack a LabQ image to float Lab" -msgstr "" - -#: ../libvips/colour/HSV2sRGB.c:113 -msgid "transform HSV to sRGB" -msgstr "" - -#: ../libvips/colour/XYZ2Lab.c:222 -msgid "transform XYZ to Lab" -msgstr "" - -#: ../libvips/colour/XYZ2Lab.c:228 ../libvips/colour/Lab2XYZ.c:175 -msgid "Temperature" -msgstr "" - -#: ../libvips/colour/XYZ2Lab.c:229 -msgid "Colour temperature" -msgstr "" - -#: ../libvips/colour/UCS2LCh.c:272 ../libvips/colour/LCh2UCS.c:206 -msgid "transform LCh to CMC" -msgstr "" - -#: ../libvips/colour/dE76.c:113 -msgid "calculate dE76" -msgstr "" - -#: ../libvips/colour/colour.c:421 +#: libvips/colour/colour.c:409 msgid "color operations" msgstr "colour operations" -#: ../libvips/colour/colour.c:489 +#: libvips/colour/colour.c:476 msgid "color space transformations" msgstr "colour space transformations" -#: ../libvips/colour/colour.c:583 +#: libvips/colour/colour.c:569 msgid "change color coding" msgstr "change colour coding" -#: ../libvips/colour/colour.c:695 +#: libvips/colour/colour.c:680 msgid "calculate color difference" msgstr "calculate colour difference" -#: ../libvips/colour/colour.c:700 +#: libvips/colour/colour.c:685 msgid "Left-hand input image" msgstr "" -#: ../libvips/colour/colour.c:706 +#: libvips/colour/colour.c:691 msgid "Right-hand input image" msgstr "" -#: ../libvips/colour/sRGB2HSV.c:134 -msgid "transform sRGB to HSV" +#: libvips/colour/colourspace.c:145 +msgid "too few bands for operation" msgstr "" -#: ../libvips/colour/Lab2LabQ.c:137 -msgid "transform float Lab to LabQ coding" +#: libvips/colour/colourspace.c:519 +#, c-format +msgid "no known route from '%s' to '%s'" msgstr "" -#: ../libvips/colour/sRGB2scRGB.c:237 -msgid "convert an sRGB image to scRGB" -msgstr "" +#: libvips/colour/colourspace.c:551 +msgid "convert to a new colorspace" +msgstr "convert to a new colourspace" -#: ../libvips/colour/dECMC.c:61 -msgid "calculate dECMC" +#: libvips/colour/colourspace.c:569 +msgid "Space" msgstr "" -#: ../libvips/colour/LCh2Lab.c:120 -msgid "transform LCh to Lab" -msgstr "" +#: libvips/colour/colourspace.c:570 +msgid "Destination color space" +msgstr "Destination colour space" -#: ../libvips/colour/Yxy2XYZ.c:93 -msgid "transform Yxy to XYZ" +#: libvips/colour/colourspace.c:576 +msgid "Source space" msgstr "" -#: ../libvips/colour/LabS2Lab.c:78 -msgid "transform signed short Lab to float" -msgstr "" +#: libvips/colour/colourspace.c:577 +msgid "Source color space" +msgstr "Source colour space" -#: ../libvips/colour/LabQ2sRGB.c:514 -msgid "convert a LabQ image to sRGB" +#: libvips/colour/dE00.c:236 +msgid "calculate dE00" msgstr "" -#: ../libvips/colour/scRGB2BW.c:190 ../libvips/colour/icc_transform.c:237 -#: ../libvips/colour/scRGB2sRGB.c:219 -msgid "depth must be 8 or 16" +#: libvips/colour/dE76.c:113 +msgid "calculate dE76" msgstr "" -#: ../libvips/colour/scRGB2BW.c:231 -msgid "convert scRGB to BW" +#: libvips/colour/dECMC.c:61 +msgid "calculate dECMC" msgstr "" -#: ../libvips/colour/scRGB2BW.c:249 ../libvips/colour/icc_transform.c:980 -#: ../libvips/colour/icc_transform.c:1121 ../libvips/colour/scRGB2sRGB.c:277 -#: ../libvips/foreign/dzsave.c:2163 -msgid "Depth" +#: libvips/colour/float2rad.c:206 +msgid "transform float RGB to Radiance coding" msgstr "" -#: ../libvips/colour/scRGB2BW.c:250 ../libvips/colour/icc_transform.c:981 -#: ../libvips/colour/icc_transform.c:1122 ../libvips/colour/scRGB2sRGB.c:278 -msgid "Output device space depth in bits" +#: libvips/colour/HSV2sRGB.c:112 +msgid "transform HSV to sRGB" msgstr "" -#: ../libvips/colour/Lab2LCh.c:149 -msgid "transform Lab to LCh" +#: libvips/colour/icc_transform.c:272 libvips/colour/scRGB2BW.c:190 +#: libvips/colour/scRGB2sRGB.c:224 +msgid "depth must be 8 or 16" msgstr "" -#: ../libvips/colour/icc_transform.c:292 +#: libvips/colour/icc_transform.c:284 #, c-format msgid "unimplemented input color space 0x%x" msgstr "unimplemented input colour space 0x%x" -#: ../libvips/colour/icc_transform.c:357 +#: libvips/colour/icc_transform.c:360 #, c-format msgid "unimplemented output color space 0x%x" msgstr "unimplemented output colour space 0x%x" -#: ../libvips/colour/icc_transform.c:369 +#: libvips/colour/icc_transform.c:437 msgid "no device profile" msgstr "" -#: ../libvips/colour/icc_transform.c:400 -msgid "transform using ICC profiles" -msgstr "" - -#: ../libvips/colour/icc_transform.c:404 -msgid "Intent" +#: libvips/colour/icc_transform.c:612 libvips/colour/icc_transform.c:635 +#: libvips/colour/icc_transform.c:658 libvips/iofuncs/operation.c:442 +msgid "input" msgstr "" -#: ../libvips/colour/icc_transform.c:405 -msgid "Rendering intent" +#: libvips/colour/icc_transform.c:612 libvips/colour/icc_transform.c:635 +#: libvips/colour/icc_transform.c:658 libvips/iofuncs/operation.c:443 +msgid "output" msgstr "" -#: ../libvips/colour/icc_transform.c:411 -msgid "PCS" +#: libvips/colour/icc_transform.c:631 +#, c-format +msgid "" +"fallback to suggested %s intent, as profile does not support %s %s intent" msgstr "" -#: ../libvips/colour/icc_transform.c:412 -msgid "Set Profile Connection Space" +#: libvips/colour/icc_transform.c:656 +#, c-format +msgid "profile does not support %s %s intent" msgstr "" -#: ../libvips/colour/icc_transform.c:455 -#, c-format -msgid "" -"%s: intent %d (%s) not supported by %s profile; falling back to default " -"intent" +#: libvips/colour/icc_transform.c:757 +msgid "unable to load or find any compatible input profile" msgstr "" -#: ../libvips/colour/icc_transform.c:460 ../libvips/iofuncs/operation.c:377 -msgid "input" +#: libvips/colour/icc_transform.c:775 +msgid "transform using ICC profiles" msgstr "" -#: ../libvips/colour/icc_transform.c:460 ../libvips/iofuncs/operation.c:377 -msgid "output" +#: libvips/colour/icc_transform.c:779 libvips/resample/thumbnail.c:1030 +msgid "Intent" msgstr "" -#: ../libvips/colour/icc_transform.c:557 -msgid "corrupt embedded profile" +#: libvips/colour/icc_transform.c:780 libvips/resample/thumbnail.c:1031 +msgid "Rendering intent" msgstr "" -#: ../libvips/colour/icc_transform.c:565 -msgid "embedded profile incompatible with image" +#: libvips/colour/icc_transform.c:786 +msgid "PCS" msgstr "" -#: ../libvips/colour/icc_transform.c:580 ../libvips/colour/icc_transform.c:822 -#: ../libvips/colour/icc_transform.c:1045 -#, c-format -msgid "unable to open profile \"%s\"" +#: libvips/colour/icc_transform.c:787 +msgid "Set Profile Connection Space" msgstr "" -#: ../libvips/colour/icc_transform.c:587 -#, c-format -msgid "profile \"%s\" incompatible with image" +#: libvips/colour/icc_transform.c:793 +msgid "Black point compensation" msgstr "" -#: ../libvips/colour/icc_transform.c:626 ../libvips/colour/icc_transform.c:1037 -msgid "no input profile" +#: libvips/colour/icc_transform.c:794 +msgid "Enable black point compensation" msgstr "" -#: ../libvips/colour/icc_transform.c:736 +#: libvips/colour/icc_transform.c:969 msgid "import from device with ICC profile" msgstr "" -#: ../libvips/colour/icc_transform.c:742 ../libvips/colour/icc_transform.c:1107 +#: libvips/colour/icc_transform.c:975 libvips/colour/icc_transform.c:1258 msgid "Embedded" msgstr "" -#: ../libvips/colour/icc_transform.c:743 ../libvips/colour/icc_transform.c:1108 +#: libvips/colour/icc_transform.c:976 libvips/colour/icc_transform.c:1259 msgid "Use embedded input profile, if available" msgstr "" -#: ../libvips/colour/icc_transform.c:749 ../libvips/colour/icc_transform.c:1114 +#: libvips/colour/icc_transform.c:982 libvips/colour/icc_transform.c:1265 msgid "Input profile" msgstr "" -#: ../libvips/colour/icc_transform.c:750 ../libvips/colour/icc_transform.c:1115 +#: libvips/colour/icc_transform.c:983 libvips/colour/icc_transform.c:1266 msgid "Filename to load input profile from" msgstr "" -#: ../libvips/colour/icc_transform.c:814 -msgid "unable to load embedded profile" -msgstr "" - -#: ../libvips/colour/icc_transform.c:830 +#: libvips/colour/icc_transform.c:1046 libvips/colour/icc_transform.c:1212 msgid "no output profile" msgstr "" -#: ../libvips/colour/icc_transform.c:967 +#: libvips/colour/icc_transform.c:1141 msgid "output to device with ICC profile" msgstr "" -#: ../libvips/colour/icc_transform.c:973 ../libvips/colour/icc_transform.c:1100 +#: libvips/colour/icc_transform.c:1147 libvips/colour/icc_transform.c:1251 msgid "Output profile" msgstr "" -#: ../libvips/colour/icc_transform.c:974 ../libvips/colour/icc_transform.c:1101 +#: libvips/colour/icc_transform.c:1148 libvips/colour/icc_transform.c:1252 msgid "Filename to load output profile from" msgstr "" -#: ../libvips/colour/icc_transform.c:1094 -msgid "transform between devices with ICC profiles" +#: libvips/colour/icc_transform.c:1154 libvips/colour/icc_transform.c:1272 +#: libvips/colour/scRGB2BW.c:249 libvips/colour/scRGB2sRGB.c:282 +#: libvips/foreign/dzsave.c:2364 libvips/foreign/tiffsave.c:378 +msgid "Depth" msgstr "" -#: ../libvips/colour/icc_transform.c:1166 -#: ../libvips/colour/icc_transform.c:1180 -msgid "unable to get media white point" +#: libvips/colour/icc_transform.c:1155 libvips/colour/icc_transform.c:1273 +#: libvips/colour/scRGB2BW.c:250 libvips/colour/scRGB2sRGB.c:283 +msgid "Output device space depth in bits" msgstr "" -#: ../libvips/colour/icc_transform.c:1240 -msgid "libvips configured without lcms support" +#: libvips/colour/icc_transform.c:1245 +msgid "transform between devices with ICC profiles" msgstr "" -#: ../libvips/colour/scRGB2sRGB.c:259 -msgid "convert an scRGB image to sRGB" +#: libvips/colour/icc_transform.c:1321 +msgid "unable to get media white point" msgstr "" -#: ../libvips/colour/dE00.c:235 -msgid "calculate dE00" +#: libvips/colour/icc_transform.c:1416 +msgid "libvips configured without lcms support" msgstr "" -#: ../libvips/colour/Lab2XYZ.c:169 -msgid "transform CIELAB to XYZ" +#: libvips/colour/Lab2LabQ.c:137 +msgid "transform float Lab to LabQ coding" msgstr "" -#: ../libvips/colour/Lab2XYZ.c:176 -msgid "Color temperature" +#: libvips/colour/Lab2LabS.c:82 +msgid "transform float Lab to signed short" msgstr "" -#: ../libvips/colour/XYZ2Yxy.c:92 -msgid "transform XYZ to Yxy" +#: libvips/colour/Lab2LCh.c:132 +msgid "transform Lab to LCh" msgstr "" -#: ../libvips/colour/colourspace.c:145 -msgid "too few bands for operation" +#: libvips/colour/Lab2XYZ.c:177 +msgid "transform CIELAB to XYZ" msgstr "" -#: ../libvips/colour/colourspace.c:548 -#, c-format -msgid "no known route from '%s' to '%s'" +#: libvips/colour/Lab2XYZ.c:183 libvips/colour/XYZ2Lab.c:236 +msgid "Temperature" msgstr "" -#: ../libvips/colour/colourspace.c:580 -msgid "convert to a new colorspace" -msgstr "convert to a new colourspace" - -#: ../libvips/colour/colourspace.c:598 -msgid "Space" +#: libvips/colour/Lab2XYZ.c:184 +msgid "Color temperature" msgstr "" -#: ../libvips/colour/colourspace.c:599 -msgid "Destination color space" -msgstr "Destination colour space" - -#: ../libvips/colour/colourspace.c:605 -msgid "Source space" +#: libvips/colour/LabQ2Lab.c:125 +msgid "unpack a LabQ image to float Lab" msgstr "" -#: ../libvips/colour/colourspace.c:606 -msgid "Source color space" -msgstr "Source colour space" - -#: ../libvips/conversion/conversion.c:196 -msgid "conversion operations" +#: libvips/colour/LabQ2LabS.c:104 +msgid "unpack a LabQ image to short Lab" msgstr "" -#: ../libvips/conversion/embed.c:474 ../libvips/iofuncs/image.c:2818 -msgid "bad dimensions" +#: libvips/colour/LabQ2sRGB.c:549 +msgid "convert a LabQ image to sRGB" msgstr "" -#: ../libvips/conversion/embed.c:557 -msgid "embed an image in a larger image" +#: libvips/colour/LabS2Lab.c:78 +msgid "transform signed short Lab to float" msgstr "" -#: ../libvips/conversion/embed.c:570 ../libvips/conversion/wrap.c:126 -msgid "Left edge of input in output" +#: libvips/colour/LabS2LabQ.c:127 +msgid "transform short Lab to LabQ coding" msgstr "" -#: ../libvips/conversion/embed.c:577 ../libvips/conversion/wrap.c:133 -msgid "Top edge of input in output" +#: libvips/colour/LCh2Lab.c:111 +msgid "transform LCh to Lab" msgstr "" -#: ../libvips/conversion/embed.c:584 ../libvips/conversion/copy.c:285 -#: ../libvips/create/xyz.c:194 ../libvips/create/worley.c:311 -#: ../libvips/create/gaussnoise.c:173 ../libvips/create/perlin.c:298 -#: ../libvips/create/point.c:144 ../libvips/create/fractsurf.c:103 -#: ../libvips/create/black.c:130 ../libvips/foreign/rawload.c:124 -#: ../libvips/iofuncs/image.c:1131 -msgid "Image width in pixels" +#: libvips/colour/LCh2UCS.c:206 libvips/colour/UCS2LCh.c:273 +msgid "transform LCh to CMC" msgstr "" -#: ../libvips/conversion/embed.c:591 ../libvips/conversion/copy.c:292 -#: ../libvips/create/xyz.c:201 ../libvips/create/worley.c:318 -#: ../libvips/create/gaussnoise.c:180 ../libvips/create/perlin.c:305 -#: ../libvips/create/point.c:151 ../libvips/create/fractsurf.c:110 -#: ../libvips/create/black.c:137 ../libvips/foreign/rawload.c:131 -#: ../libvips/iofuncs/image.c:1138 -msgid "Image height in pixels" +#: libvips/colour/profile_load.c:123 +#, c-format +msgid "unable to load profile \"%s\"" msgstr "" -#: ../libvips/conversion/embed.c:597 -msgid "Extend" +#: libvips/colour/profile_load.c:147 +msgid "load named ICC profile" msgstr "" -#: ../libvips/conversion/embed.c:598 -msgid "How to generate the extra pixels" +#: libvips/colour/profile_load.c:151 +msgid "Name" msgstr "" -#: ../libvips/conversion/embed.c:604 ../libvips/conversion/arrayjoin.c:325 -#: ../libvips/conversion/flatten.c:392 ../libvips/conversion/join.c:265 -#: ../libvips/conversion/insert.c:550 ../libvips/foreign/foreign.c:1535 -msgid "Background" +#: libvips/colour/profile_load.c:152 +msgid "Profile name" msgstr "" -#: ../libvips/conversion/embed.c:605 -msgid "Color for background pixels" +#: libvips/colour/profile_load.c:158 libvips/foreign/foreign.c:1922 +msgid "Profile" msgstr "" -#: ../libvips/conversion/zoom.c:333 -msgid "zoom factors too large" +#: libvips/colour/profile_load.c:159 +msgid "Loaded profile" msgstr "" -#: ../libvips/conversion/zoom.c:377 -msgid "zoom an image" +#: libvips/colour/rad2float.c:184 +msgid "unpack Radiance coding to float RGB" msgstr "" -#: ../libvips/conversion/zoom.c:389 ../libvips/conversion/subsample.c:280 -msgid "Xfac" +#: libvips/colour/scRGB2BW.c:231 +msgid "convert scRGB to BW" msgstr "" -#: ../libvips/conversion/zoom.c:390 -msgid "Horizontal zoom factor" +#: libvips/colour/scRGB2sRGB.c:264 +msgid "convert an scRGB image to sRGB" msgstr "" -#: ../libvips/conversion/zoom.c:396 ../libvips/conversion/subsample.c:287 -msgid "Yfac" +#: libvips/colour/scRGB2XYZ.c:185 +msgid "transform scRGB to XYZ" msgstr "" -#: ../libvips/conversion/zoom.c:397 -msgid "Vertical zoom factor" +#: libvips/colour/sRGB2HSV.c:133 +msgid "transform sRGB to HSV" msgstr "" -#: ../libvips/conversion/replicate.c:192 -msgid "replicate an image" +#: libvips/colour/sRGB2scRGB.c:282 +msgid "convert an sRGB image to scRGB" msgstr "" -#: ../libvips/conversion/replicate.c:203 -msgid "Repeat this many times horizontally" +#: libvips/colour/XYZ2CMYK.c:113 libvips/colour/XYZ2CMYK.c:193 +msgid "transform XYZ to CMYK" msgstr "" -#: ../libvips/conversion/replicate.c:210 -msgid "Repeat this many times vertically" +#: libvips/colour/XYZ2Lab.c:230 +msgid "transform XYZ to Lab" msgstr "" -#: ../libvips/conversion/bandfold.c:122 -msgid "@factor must be a factor of image width" +#: libvips/colour/XYZ2Lab.c:237 +msgid "Colour temperature" msgstr "" -#: ../libvips/conversion/bandfold.c:154 -msgid "fold up x axis into bands" +#: libvips/colour/XYZ2scRGB.c:194 +msgid "transform XYZ to scRGB" msgstr "" -#: ../libvips/conversion/bandfold.c:166 ../libvips/conversion/bandunfold.c:169 -#: ../libvips/create/eye.c:103 -msgid "Factor" +#: libvips/colour/XYZ2Yxy.c:98 +msgid "transform XYZ to Yxy" msgstr "" -#: ../libvips/conversion/bandfold.c:167 -msgid "Fold by this factor" +#: libvips/colour/Yxy2XYZ.c:103 +msgid "transform Yxy to XYZ" msgstr "" -#: ../libvips/conversion/wrap.c:115 -msgid "wrap image origin" +#: libvips/conversion/addalpha.c:84 +msgid "append an alpha channel" msgstr "" -#: ../libvips/conversion/arrayjoin.c:298 +#: libvips/conversion/arrayjoin.c:388 msgid "join an array of images" msgstr "" -#: ../libvips/conversion/arrayjoin.c:312 +#: libvips/conversion/arrayjoin.c:402 msgid "Number of images across grid" msgstr "" -#: ../libvips/conversion/arrayjoin.c:318 ../libvips/conversion/join.c:258 +#: libvips/conversion/arrayjoin.c:408 libvips/conversion/join.c:263 msgid "Shim" msgstr "" -#: ../libvips/conversion/arrayjoin.c:319 ../libvips/conversion/join.c:259 +#: libvips/conversion/arrayjoin.c:409 libvips/conversion/join.c:264 msgid "Pixels between images" msgstr "" -#: ../libvips/conversion/arrayjoin.c:326 ../libvips/conversion/join.c:266 +#: libvips/conversion/arrayjoin.c:416 libvips/conversion/join.c:271 msgid "Colour for new pixels" msgstr "" -#: ../libvips/conversion/arrayjoin.c:332 +#: libvips/conversion/arrayjoin.c:422 msgid "Horizontal align" msgstr "" -#: ../libvips/conversion/arrayjoin.c:333 +#: libvips/conversion/arrayjoin.c:423 msgid "Align on the left, centre or right" msgstr "" -#: ../libvips/conversion/arrayjoin.c:339 +#: libvips/conversion/arrayjoin.c:429 msgid "Vertical align" msgstr "" -#: ../libvips/conversion/arrayjoin.c:340 +#: libvips/conversion/arrayjoin.c:430 msgid "Align on the top, centre or bottom" msgstr "" -#: ../libvips/conversion/arrayjoin.c:346 +#: libvips/conversion/arrayjoin.c:436 msgid "Horizontal spacing" msgstr "" -#: ../libvips/conversion/arrayjoin.c:347 +#: libvips/conversion/arrayjoin.c:437 msgid "Horizontal spacing between images" msgstr "" -#: ../libvips/conversion/arrayjoin.c:353 +#: libvips/conversion/arrayjoin.c:443 msgid "Vertical spacing" msgstr "" -#: ../libvips/conversion/arrayjoin.c:354 +#: libvips/conversion/arrayjoin.c:444 msgid "Vertical spacing between images" msgstr "" -#: ../libvips/conversion/unpremultiply.c:262 -msgid "unpremultiply image alpha" +#: libvips/conversion/autorot.c:203 +msgid "autorotate image by exif tag" msgstr "" -#: ../libvips/conversion/unpremultiply.c:274 -#: ../libvips/conversion/flatten.c:399 ../libvips/conversion/premultiply.c:265 -msgid "Maximum alpha" +#: libvips/conversion/autorot.c:213 libvips/conversion/rot45.c:274 +#: libvips/conversion/rot.c:371 libvips/convolution/compass.c:170 +#: libvips/foreign/dzsave.c:2378 libvips/mosaicing/mosaic.c:281 +#: libvips/resample/similarity.c:207 libvips/resample/similarity.c:276 +msgid "Angle" msgstr "" -#: ../libvips/conversion/unpremultiply.c:275 -#: ../libvips/conversion/flatten.c:400 ../libvips/conversion/premultiply.c:266 -msgid "Maximum value of alpha channel" +#: libvips/conversion/autorot.c:214 +msgid "Angle image was rotated by" msgstr "" -#: ../libvips/conversion/flip.c:236 -msgid "flip an image" +#: libvips/conversion/autorot.c:220 +msgid "Flip" msgstr "" -#: ../libvips/conversion/flip.c:246 ../libvips/mosaicing/merge.c:127 -#: ../libvips/mosaicing/mosaic.c:198 ../libvips/mosaicing/mosaic1.c:507 -msgid "Direction" +#: libvips/conversion/autorot.c:221 +msgid "Whether the image was flipped or not" msgstr "" -#: ../libvips/conversion/flip.c:247 -msgid "Direction to flip image" +#: libvips/conversion/bandary.c:211 libvips/conversion/bandary.c:280 +#: libvips/conversion/composite.cpp:1299 +msgid "no input images" msgstr "" -#: ../libvips/conversion/flatten.c:380 -msgid "flatten alpha out of an image" +#: libvips/conversion/bandary.c:257 +msgid "operations on image bands" msgstr "" -#: ../libvips/conversion/flatten.c:393 ../libvips/foreign/foreign.c:1536 -msgid "Background value" +#: libvips/conversion/bandbool.c:75 +#, c-format +msgid "operator %s not supported across image bands" msgstr "" -#: ../libvips/conversion/copy.c:235 -msgid "must not change pel size" +#: libvips/conversion/bandbool.c:225 +msgid "boolean operation across image bands" msgstr "" -#: ../libvips/conversion/copy.c:260 -msgid "copy an image" +#: libvips/conversion/bandbool.c:233 libvips/conversion/bandmean.c:213 +#: libvips/conversion/recomb.c:225 libvips/convolution/convolution.c:129 +#: libvips/convolution/correlation.c:151 libvips/morphology/morphology.c:122 +#: libvips/resample/resample.c:141 libvips/resample/thumbnail.c:1783 +msgid "Input image argument" msgstr "" -#: ../libvips/conversion/copy.c:277 -msgid "Swap" +#: libvips/conversion/bandfold.c:123 +msgid "@factor must be a factor of image width" msgstr "" -#: ../libvips/conversion/copy.c:278 -msgid "Swap bytes in image between little and big-endian" +#: libvips/conversion/bandfold.c:155 +msgid "fold up x axis into bands" msgstr "" -#: ../libvips/conversion/copy.c:298 ../libvips/create/identity.c:144 -#: ../libvips/create/black.c:143 ../libvips/foreign/rawload.c:137 -#: ../libvips/iofuncs/image.c:1144 -msgid "Bands" +#: libvips/conversion/bandfold.c:167 libvips/conversion/bandunfold.c:170 +#: libvips/create/eye.c:108 +msgid "Factor" msgstr "" -#: ../libvips/conversion/copy.c:299 ../libvips/create/black.c:144 -#: ../libvips/foreign/rawload.c:138 ../libvips/iofuncs/image.c:1145 -msgid "Number of bands in image" +#: libvips/conversion/bandfold.c:168 +msgid "Fold by this factor" +msgstr "" + +#: libvips/conversion/bandjoin.c:195 +msgid "bandwise join a set of images" +msgstr "" + +#: libvips/conversion/bandjoin.c:430 +msgid "append a constant band to an image" +msgstr "" + +#: libvips/conversion/bandjoin.c:442 +msgid "Constants" +msgstr "" + +#: libvips/conversion/bandjoin.c:443 +msgid "Array of constants to add" +msgstr "" + +#: libvips/conversion/bandmean.c:206 +msgid "band-wise average" +msgstr "" + +#: libvips/conversion/bandrank.c:248 +msgid "band-wise rank of a set of images" +msgstr "" + +#: libvips/conversion/bandrank.c:262 +msgid "Select this band element from sorted list" +msgstr "" + +#: libvips/conversion/bandunfold.c:126 +msgid "@factor must be a factor of image bands" +msgstr "" + +#: libvips/conversion/bandunfold.c:158 +msgid "unfold image bands into x axis" +msgstr "" + +#: libvips/conversion/bandunfold.c:171 +msgid "Unfold by this factor" +msgstr "" + +#: libvips/conversion/byteswap.c:232 +msgid "byteswap an image" +msgstr "" + +#: libvips/conversion/cache.c:98 libvips/conversion/tilecache.c:392 +msgid "cache an image" +msgstr "" + +#: libvips/conversion/cache.c:114 libvips/conversion/tilecache.c:800 +#: libvips/foreign/dzsave.c:2451 libvips/foreign/jp2ksave.c:971 +#: libvips/foreign/tiffsave.c:287 +msgid "Tile width" +msgstr "" + +#: libvips/conversion/cache.c:115 libvips/conversion/tilecache.c:801 +#: libvips/foreign/dzsave.c:2452 libvips/foreign/jp2ksave.c:972 +#: libvips/foreign/tiffsave.c:288 +msgid "Tile width in pixels" +msgstr "" + +#: libvips/conversion/cache.c:121 libvips/conversion/grid.c:205 +#: libvips/conversion/sequential.c:249 libvips/conversion/tilecache.c:404 +#: libvips/foreign/dzsave.c:2458 libvips/foreign/jp2ksave.c:978 +#: libvips/foreign/tiffsave.c:294 +msgid "Tile height" +msgstr "" + +#: libvips/conversion/cache.c:122 libvips/conversion/sequential.c:250 +#: libvips/conversion/tilecache.c:405 libvips/foreign/dzsave.c:2459 +#: libvips/foreign/jp2ksave.c:979 libvips/foreign/tiffsave.c:295 +msgid "Tile height in pixels" +msgstr "" + +#: libvips/conversion/cache.c:128 libvips/conversion/tilecache.c:807 +msgid "Max tiles" +msgstr "" + +#: libvips/conversion/cache.c:129 libvips/conversion/tilecache.c:808 +msgid "Maximum number of tiles to cache" +msgstr "" + +#: libvips/conversion/cast.c:524 +msgid "cast an image" msgstr "" -#: ../libvips/conversion/copy.c:305 ../libvips/conversion/cast.c:554 -#: ../libvips/iofuncs/image.c:1151 +#: libvips/conversion/cast.c:536 libvips/conversion/copy.c:305 +#: libvips/foreign/ppmsave.c:506 libvips/foreign/rawload.c:174 +#: libvips/foreign/vips2magick.c:482 libvips/iofuncs/image.c:1123 msgid "Format" msgstr "" -#: ../libvips/conversion/copy.c:306 ../libvips/iofuncs/image.c:1152 -msgid "Pixel format in image" +#: libvips/conversion/cast.c:537 +msgid "Format to cast to" msgstr "" -#: ../libvips/conversion/copy.c:312 ../libvips/iofuncs/image.c:1158 -msgid "Coding" +#: libvips/conversion/cast.c:543 +msgid "Shift" msgstr "" -#: ../libvips/conversion/copy.c:313 ../libvips/iofuncs/image.c:1159 -msgid "Pixel coding" +#: libvips/conversion/cast.c:544 +msgid "Shift integer values up and down" msgstr "" -#: ../libvips/conversion/copy.c:319 ../libvips/iofuncs/image.c:1165 -msgid "Interpretation" +#: libvips/conversion/composite.cpp:1304 +#, c-format +msgid "must be 1 or %d blend modes" msgstr "" -#: ../libvips/conversion/copy.c:320 ../libvips/iofuncs/image.c:1166 -msgid "Pixel interpretation" +#: libvips/conversion/composite.cpp:1314 +#, c-format +msgid "blend mode index %d (%d) invalid" +msgstr "" + +#: libvips/conversion/composite.cpp:1413 +msgid "images do not have same numbers of bands" +msgstr "" + +#: libvips/conversion/composite.cpp:1420 +msgid "too many input bands" +msgstr "" + +#: libvips/conversion/composite.cpp:1430 +#, fuzzy +msgid "unsupported compositing space" +msgstr "unsupported colourspace %d" + +#: libvips/conversion/composite.cpp:1478 +msgid "blend images together" +msgstr "" + +#: libvips/conversion/composite.cpp:1484 +msgid "Compositing space" +msgstr "" + +#: libvips/conversion/composite.cpp:1485 +#, fuzzy +msgid "Composite images in this colour space" +msgstr "Destination colour space" + +#: libvips/conversion/composite.cpp:1491 libvips/conversion/smartcrop.c:474 +#: libvips/resample/affine.c:706 libvips/resample/mapim.c:581 +msgid "Premultiplied" +msgstr "" + +#: libvips/conversion/composite.cpp:1492 libvips/resample/affine.c:707 +#: libvips/resample/mapim.c:582 +msgid "Images have premultiplied alpha" +msgstr "" + +#: libvips/conversion/composite.cpp:1540 +#, c-format +msgid "must be %d x coordinates" +msgstr "" + +#: libvips/conversion/composite.cpp:1548 +#, c-format +msgid "must be %d y coordinates" +msgstr "" + +#: libvips/conversion/composite.cpp:1574 +msgid "blend an array of images with an array of blend modes" +msgstr "" + +#: libvips/conversion/composite.cpp:1580 +msgid "Inputs" +msgstr "" + +#: libvips/conversion/composite.cpp:1587 +msgid "Blend modes" +msgstr "" + +#: libvips/conversion/composite.cpp:1588 +msgid "Array of VipsBlendMode to join with" +msgstr "" + +#: libvips/conversion/composite.cpp:1594 +msgid "x coordinates" +msgstr "" + +#: libvips/conversion/composite.cpp:1595 +msgid "Array of x coordinates to join at" +msgstr "" + +#: libvips/conversion/composite.cpp:1601 +msgid "y coordinates" +msgstr "" + +#: libvips/conversion/composite.cpp:1602 +msgid "Array of y coordinates to join at" +msgstr "" + +#: libvips/conversion/composite.cpp:1708 +msgid "blend a pair of images with a blend mode" +msgstr "" + +#: libvips/conversion/composite.cpp:1714 +msgid "Base" +msgstr "" + +#: libvips/conversion/composite.cpp:1715 +#, fuzzy +msgid "Base image" +msgstr "false-colour an image" + +#: libvips/conversion/composite.cpp:1720 +msgid "Overlay" +msgstr "" + +#: libvips/conversion/composite.cpp:1721 +msgid "Overlay image" +msgstr "" + +#: libvips/conversion/composite.cpp:1726 +msgid "Blend mode" +msgstr "" + +#: libvips/conversion/composite.cpp:1727 +msgid "VipsBlendMode to join with" +msgstr "" + +#: libvips/conversion/composite.cpp:1734 +msgid "x position of overlay" +msgstr "" + +#: libvips/conversion/composite.cpp:1741 +msgid "y position of overlay" +msgstr "" + +#: libvips/conversion/conversion.c:342 +msgid "conversion operations" +msgstr "" + +#: libvips/conversion/copy.c:235 +msgid "must not change pel size" +msgstr "" + +#: libvips/conversion/copy.c:260 +msgid "copy an image" +msgstr "" + +#: libvips/conversion/copy.c:277 +msgid "Swap" +msgstr "" + +#: libvips/conversion/copy.c:278 +msgid "Swap bytes in image between little and big-endian" +msgstr "" + +#: libvips/conversion/copy.c:285 libvips/conversion/embed.c:575 +#: libvips/create/black.c:141 libvips/create/fractsurf.c:105 +#: libvips/create/gaussnoise.c:168 libvips/create/perlin.c:295 +#: libvips/create/point.c:142 libvips/create/sdf.c:305 +#: libvips/create/worley.c:308 libvips/create/xyz.c:192 +#: libvips/foreign/rawload.c:147 libvips/iofuncs/image.c:1103 +msgid "Image width in pixels" +msgstr "" + +#: libvips/conversion/copy.c:292 libvips/conversion/embed.c:582 +#: libvips/create/black.c:148 libvips/create/fractsurf.c:112 +#: libvips/create/gaussnoise.c:175 libvips/create/perlin.c:302 +#: libvips/create/point.c:149 libvips/create/sdf.c:312 +#: libvips/create/worley.c:315 libvips/create/xyz.c:199 +#: libvips/foreign/rawload.c:154 libvips/iofuncs/image.c:1110 +msgid "Image height in pixels" +msgstr "" + +#: libvips/conversion/copy.c:298 libvips/create/black.c:154 +#: libvips/create/identity.c:143 libvips/foreign/rawload.c:160 +#: libvips/iofuncs/image.c:1116 +msgid "Bands" +msgstr "" + +#: libvips/conversion/copy.c:299 libvips/create/black.c:155 +#: libvips/foreign/rawload.c:161 libvips/iofuncs/image.c:1117 +msgid "Number of bands in image" +msgstr "" + +#: libvips/conversion/copy.c:306 libvips/foreign/rawload.c:175 +#: libvips/iofuncs/image.c:1124 +msgid "Pixel format in image" +msgstr "" + +#: libvips/conversion/copy.c:312 libvips/iofuncs/image.c:1130 +msgid "Coding" +msgstr "" + +#: libvips/conversion/copy.c:313 libvips/iofuncs/image.c:1131 +msgid "Pixel coding" +msgstr "" + +#: libvips/conversion/copy.c:319 libvips/foreign/rawload.c:181 +#: libvips/iofuncs/image.c:1137 +msgid "Interpretation" +msgstr "" + +#: libvips/conversion/copy.c:320 libvips/foreign/rawload.c:182 +#: libvips/iofuncs/image.c:1138 +msgid "Pixel interpretation" +msgstr "" + +#: libvips/conversion/copy.c:326 libvips/foreign/tiffsave.c:329 +#: libvips/iofuncs/image.c:1144 +msgid "Xres" +msgstr "" + +#: libvips/conversion/copy.c:327 libvips/foreign/tiffsave.c:330 +#: libvips/iofuncs/image.c:1145 +msgid "Horizontal resolution in pixels/mm" +msgstr "" + +#: libvips/conversion/copy.c:333 libvips/foreign/tiffsave.c:336 +#: libvips/iofuncs/image.c:1151 +msgid "Yres" +msgstr "" + +#: libvips/conversion/copy.c:334 libvips/foreign/tiffsave.c:337 +#: libvips/iofuncs/image.c:1152 +msgid "Vertical resolution in pixels/mm" +msgstr "" + +#: libvips/conversion/copy.c:340 libvips/iofuncs/image.c:1158 +msgid "Xoffset" +msgstr "" + +#: libvips/conversion/copy.c:341 libvips/iofuncs/image.c:1159 +msgid "Horizontal offset of origin" +msgstr "" + +#: libvips/conversion/copy.c:347 libvips/iofuncs/image.c:1165 +msgid "Yoffset" +msgstr "" + +#: libvips/conversion/copy.c:348 libvips/iofuncs/image.c:1166 +msgid "Vertical offset of origin" +msgstr "" + +#: libvips/conversion/embed.c:479 libvips/foreign/heifload.c:571 +#: libvips/foreign/svgload.c:502 libvips/iofuncs/image.c:3143 +msgid "bad dimensions" +msgstr "" + +#: libvips/conversion/embed.c:561 libvips/conversion/embed.c:652 +msgid "embed an image in a larger image" +msgstr "" + +#: libvips/conversion/embed.c:588 libvips/resample/affine.c:692 +#: libvips/resample/mapim.c:567 +msgid "Extend" +msgstr "" + +#: libvips/conversion/embed.c:589 libvips/resample/affine.c:693 +#: libvips/resample/mapim.c:568 +msgid "How to generate the extra pixels" +msgstr "" + +#: libvips/conversion/embed.c:657 libvips/conversion/wrap.c:126 +msgid "Left edge of input in output" +msgstr "" + +#: libvips/conversion/embed.c:664 libvips/conversion/wrap.c:133 +msgid "Top edge of input in output" +msgstr "" + +#: libvips/conversion/embed.c:806 +msgid "place an image within a larger image with a certain gravity" +msgstr "" + +#: libvips/conversion/embed.c:811 libvips/conversion/flip.c:246 +#: libvips/conversion/join.c:249 libvips/morphology/countlines.c:146 +#: libvips/mosaicing/merge.c:140 libvips/mosaicing/mosaic1.c:516 +#: libvips/mosaicing/mosaic.c:197 +msgid "Direction" +msgstr "" + +#: libvips/conversion/embed.c:812 +msgid "Direction to place image within width/height" +msgstr "" + +#: libvips/conversion/extract.c:150 libvips/conversion/smartcrop.c:341 +msgid "bad extract area" +msgstr "" + +#: libvips/conversion/extract.c:188 libvips/conversion/smartcrop.c:429 +msgid "extract an area from an image" +msgstr "" + +#: libvips/conversion/extract.c:398 +msgid "bad extract band" +msgstr "" + +#: libvips/conversion/extract.c:426 +msgid "extract band from an image" +msgstr "" + +#: libvips/conversion/extract.c:439 +msgid "Band to extract" +msgstr "" + +#: libvips/conversion/extract.c:445 libvips/foreign/heifload.c:1090 +#: libvips/foreign/jxlload.c:1139 libvips/foreign/magick6load.c:148 +#: libvips/foreign/magick7load.c:389 libvips/foreign/nsgifload.c:627 +#: libvips/foreign/pdfiumload.c:702 libvips/foreign/popplerload.c:552 +#: libvips/foreign/tiffload.c:203 libvips/foreign/webpload.c:185 +msgid "n" +msgstr "" + +#: libvips/conversion/extract.c:446 +msgid "Number of bands to extract" +msgstr "" + +#: libvips/conversion/falsecolour.c:374 +msgid "false-color an image" +msgstr "false-colour an image" + +#: libvips/conversion/flatten.c:413 +msgid "flatten alpha out of an image" +msgstr "" + +#: libvips/conversion/flatten.c:426 libvips/foreign/foreign.c:1909 +#: libvips/resample/affine.c:700 libvips/resample/mapim.c:575 +#: libvips/resample/similarity.c:134 +msgid "Background value" +msgstr "" + +#: libvips/conversion/flatten.c:432 libvips/conversion/premultiply.c:267 +#: libvips/conversion/unpremultiply.c:329 +msgid "Maximum alpha" +msgstr "" + +#: libvips/conversion/flatten.c:433 libvips/conversion/premultiply.c:268 +#: libvips/conversion/unpremultiply.c:330 +msgid "Maximum value of alpha channel" +msgstr "" + +#: libvips/conversion/flip.c:236 +msgid "flip an image" +msgstr "" + +#: libvips/conversion/flip.c:247 +msgid "Direction to flip image" +msgstr "" + +#: libvips/conversion/gamma.c:136 +msgid "gamma an image" +msgstr "" + +#: libvips/conversion/gamma.c:148 libvips/conversion/scale.c:168 +msgid "Exponent" +msgstr "" + +#: libvips/conversion/gamma.c:149 +msgid "Gamma factor" +msgstr "" + +#: libvips/conversion/grid.c:165 +msgid "bad grid geometry" +msgstr "" + +#: libvips/conversion/grid.c:195 +msgid "grid an image" +msgstr "" + +#: libvips/conversion/grid.c:206 +msgid "Chop into tiles this high" +msgstr "" + +#: libvips/conversion/grid.c:213 +msgid "Number of tiles across" +msgstr "" + +#: libvips/conversion/grid.c:220 +msgid "Number of tiles down" +msgstr "" + +#: libvips/conversion/ifthenelse.c:525 +msgid "ifthenelse an image" +msgstr "" + +#: libvips/conversion/ifthenelse.c:529 +msgid "Condition" +msgstr "" + +#: libvips/conversion/ifthenelse.c:530 +msgid "Condition input image" +msgstr "" + +#: libvips/conversion/ifthenelse.c:535 +msgid "Then image" +msgstr "" + +#: libvips/conversion/ifthenelse.c:536 +msgid "Source for TRUE pixels" +msgstr "" + +#: libvips/conversion/ifthenelse.c:541 +msgid "Else image" +msgstr "" + +#: libvips/conversion/ifthenelse.c:542 +msgid "Source for FALSE pixels" +msgstr "" + +#: libvips/conversion/ifthenelse.c:547 +msgid "Blend" +msgstr "" + +#: libvips/conversion/ifthenelse.c:548 +msgid "Blend smoothly between then and else parts" +msgstr "" + +#: libvips/conversion/insert.c:460 +msgid "insert image @sub into @main at @x, @y" +msgstr "" + +#: libvips/conversion/insert.c:466 +msgid "Main" +msgstr "" + +#: libvips/conversion/insert.c:467 +msgid "Main input image" +msgstr "" + +#: libvips/conversion/insert.c:472 libvips/draw/draw_image.c:269 +msgid "Sub-image" +msgstr "" + +#: libvips/conversion/insert.c:473 libvips/draw/draw_image.c:270 +msgid "Sub-image to insert into main image" +msgstr "" + +#: libvips/conversion/insert.c:478 +msgid "X" +msgstr "" + +#: libvips/conversion/insert.c:479 +msgid "Left edge of sub in main" +msgstr "" + +#: libvips/conversion/insert.c:485 +msgid "Y" +msgstr "" + +#: libvips/conversion/insert.c:486 +msgid "Top edge of sub in main" +msgstr "" + +#: libvips/conversion/insert.c:492 libvips/conversion/join.c:256 +msgid "Expand" +msgstr "" + +#: libvips/conversion/insert.c:493 libvips/conversion/join.c:257 +msgid "Expand output to hold all of both inputs" +msgstr "" + +#: libvips/conversion/insert.c:500 +msgid "Color for new pixels" +msgstr "" + +#: libvips/conversion/join.c:231 +msgid "join a pair of images" +msgstr "" + +#: libvips/conversion/join.c:237 +msgid "in1" +msgstr "" + +#: libvips/conversion/join.c:238 +msgid "First input image" +msgstr "" + +#: libvips/conversion/join.c:243 libvips/freqfilt/phasecor.c:111 +msgid "in2" +msgstr "" + +#: libvips/conversion/join.c:244 libvips/freqfilt/phasecor.c:112 +msgid "Second input image" +msgstr "" + +#: libvips/conversion/join.c:250 +msgid "Join left-right or up-down" +msgstr "" + +#: libvips/conversion/join.c:277 libvips/create/text.c:581 +msgid "Align" +msgstr "" + +#: libvips/conversion/join.c:278 +msgid "Align on the low, centre or high coordinate edge" +msgstr "" + +#: libvips/conversion/msb.c:168 +msgid "bad band" +msgstr "" + +#: libvips/conversion/msb.c:241 +msgid "pick most-significant byte from an image" +msgstr "" + +#: libvips/conversion/msb.c:254 +msgid "Band to msb" +msgstr "" + +#: libvips/conversion/premultiply.c:255 +msgid "premultiply image alpha" +msgstr "" + +#: libvips/conversion/recomb.c:183 +msgid "bands in must equal matrix width" +msgstr "" + +#: libvips/conversion/recomb.c:218 +msgid "linear recombination with matrix" +msgstr "" + +#: libvips/conversion/recomb.c:230 +msgid "M" +msgstr "" + +#: libvips/conversion/recomb.c:231 +msgid "Matrix of coefficients" +msgstr "" + +#: libvips/conversion/replicate.c:192 +msgid "replicate an image" +msgstr "" + +#: libvips/conversion/replicate.c:203 +msgid "Repeat this many times horizontally" +msgstr "" + +#: libvips/conversion/replicate.c:210 +msgid "Repeat this many times vertically" +msgstr "" + +#: libvips/conversion/rot45.c:264 libvips/conversion/rot.c:361 +msgid "rotate an image" +msgstr "" + +#: libvips/conversion/rot45.c:275 libvips/conversion/rot.c:372 +msgid "Angle to rotate image" +msgstr "" + +#: libvips/conversion/scale.c:151 +msgid "scale an image to uchar" +msgstr "" + +#: libvips/conversion/scale.c:161 libvips/iofuncs/system.c:311 +msgid "Log" +msgstr "" + +#: libvips/conversion/scale.c:162 +msgid "Log scale" +msgstr "" + +#: libvips/conversion/scale.c:169 +msgid "Exponent for log scale" +msgstr "" + +#: libvips/conversion/sequential.c:239 +msgid "check sequential access" +msgstr "" + +#: libvips/conversion/sequential.c:256 +msgid "Strategy" +msgstr "" + +#: libvips/conversion/sequential.c:257 libvips/conversion/tilecache.c:412 +msgid "Expected access pattern" +msgstr "" + +#: libvips/conversion/sequential.c:263 +msgid "Trace" +msgstr "" + +#: libvips/conversion/sequential.c:264 +msgid "Trace pixel requests" +msgstr "" + +#: libvips/conversion/smartcrop.c:453 +msgid "Interesting" +msgstr "" + +#: libvips/conversion/smartcrop.c:454 +msgid "How to measure interestingness" +msgstr "" + +#: libvips/conversion/smartcrop.c:460 +msgid "Attention x" +msgstr "" + +#: libvips/conversion/smartcrop.c:461 +msgid "Horizontal position of attention centre" +msgstr "" + +#: libvips/conversion/smartcrop.c:467 +msgid "Attention y" +msgstr "" + +#: libvips/conversion/smartcrop.c:468 +msgid "Vertical position of attention centre" +msgstr "" + +#: libvips/conversion/smartcrop.c:475 +msgid "Input image already has premultiplied alpha" +msgstr "" + +#: libvips/conversion/subsample.c:228 libvips/resample/reduceh.cpp:546 +#: libvips/resample/reducev.cpp:1001 libvips/resample/shrinkh.c:316 +#: libvips/resample/shrinkv.c:364 +msgid "image has shrunk to nothing" +msgstr "" + +#: libvips/conversion/subsample.c:259 +msgid "subsample an image" +msgstr "" + +#: libvips/conversion/subsample.c:273 libvips/conversion/zoom.c:379 +msgid "Xfac" +msgstr "" + +#: libvips/conversion/subsample.c:274 +msgid "Horizontal subsample factor" +msgstr "" + +#: libvips/conversion/subsample.c:280 libvips/conversion/zoom.c:386 +msgid "Yfac" +msgstr "" + +#: libvips/conversion/subsample.c:281 +msgid "Vertical subsample factor" +msgstr "" + +#: libvips/conversion/subsample.c:287 +msgid "Point" +msgstr "" + +#: libvips/conversion/subsample.c:288 +msgid "Point sample" +msgstr "" + +#: libvips/conversion/switch.c:129 +msgid "bad number of tests" +msgstr "" + +#: libvips/conversion/switch.c:161 +msgid "test images not 1-band" +msgstr "" + +#: libvips/conversion/switch.c:189 +msgid "find the index of the first non-zero pixel in tests" +msgstr "" + +#: libvips/conversion/switch.c:195 +msgid "Tests" +msgstr "" + +#: libvips/conversion/switch.c:196 +msgid "Table of images to test" +msgstr "" + +#: libvips/conversion/tilecache.c:411 libvips/foreign/foreign.c:1235 +msgid "Access" +msgstr "" + +#: libvips/conversion/tilecache.c:418 +msgid "Threaded" +msgstr "" + +#: libvips/conversion/tilecache.c:419 +msgid "Allow threaded access" +msgstr "" + +#: libvips/conversion/tilecache.c:425 +msgid "Persistent" +msgstr "" + +#: libvips/conversion/tilecache.c:426 +msgid "Keep cache between evaluations" +msgstr "" + +#: libvips/conversion/tilecache.c:708 +#, c-format +msgid "error in tile %d x %d" +msgstr "" + +#: libvips/conversion/tilecache.c:796 +msgid "cache an image as a set of tiles" +msgstr "" + +#: libvips/conversion/tilecache.c:983 +msgid "cache an image as a set of lines" +msgstr "" + +#: libvips/conversion/transpose3d.c:135 +msgid "bad page_height" +msgstr "" + +#: libvips/conversion/transpose3d.c:163 +#, fuzzy +msgid "transpose3d an image" +msgstr "false-colour an image" + +#: libvips/conversion/transpose3d.c:173 libvips/foreign/foreign.c:1915 +msgid "Page height" +msgstr "" + +#: libvips/conversion/transpose3d.c:174 +msgid "Height of each input page" +msgstr "" + +#: libvips/conversion/unpremultiply.c:317 +msgid "unpremultiply image alpha" +msgstr "" + +#: libvips/conversion/unpremultiply.c:336 +msgid "Alpha band" +msgstr "" + +#: libvips/conversion/unpremultiply.c:337 +msgid "Unpremultiply with this alpha" +msgstr "" + +#: libvips/conversion/wrap.c:115 +msgid "wrap image origin" +msgstr "" + +#: libvips/conversion/zoom.c:328 +msgid "zoom factors too large" +msgstr "" + +#: libvips/conversion/zoom.c:367 +msgid "zoom an image" +msgstr "" + +#: libvips/conversion/zoom.c:380 +msgid "Horizontal zoom factor" +msgstr "" + +#: libvips/conversion/zoom.c:387 +msgid "Vertical zoom factor" +msgstr "" + +#: libvips/convolution/canny.c:436 +msgid "Canny edge detector" +msgstr "" + +#: libvips/convolution/canny.c:454 libvips/convolution/gaussblur.c:144 +#: libvips/convolution/sharpen.c:334 libvips/create/gaussmat.c:185 +#: libvips/create/gaussnoise.c:188 +msgid "Sigma" +msgstr "" + +#: libvips/convolution/canny.c:455 libvips/convolution/gaussblur.c:145 +#: libvips/convolution/sharpen.c:335 libvips/create/gaussmat.c:186 +msgid "Sigma of Gaussian" +msgstr "" + +#: libvips/convolution/canny.c:461 libvips/convolution/compass.c:184 +#: libvips/convolution/conv.c:134 libvips/convolution/convsep.c:130 +#: libvips/convolution/gaussblur.c:158 libvips/create/gaussmat.c:213 +#: libvips/create/logmat.c:229 +msgid "Precision" +msgstr "" + +#: libvips/convolution/canny.c:462 libvips/convolution/compass.c:185 +#: libvips/convolution/conv.c:135 libvips/convolution/convsep.c:131 +#: libvips/convolution/gaussblur.c:159 +msgid "Convolve with this precision" +msgstr "" + +#: libvips/convolution/compass.c:159 +msgid "convolve with rotating mask" +msgstr "" + +#: libvips/convolution/compass.c:163 +msgid "Times" +msgstr "" + +#: libvips/convolution/compass.c:164 +msgid "Rotate and convolve this many times" +msgstr "" + +#: libvips/convolution/compass.c:171 +msgid "Rotate mask by this much between convolutions" +msgstr "" + +#: libvips/convolution/compass.c:178 +msgid "Combine convolution results like this" +msgstr "" + +#: libvips/convolution/compass.c:191 libvips/convolution/conva.c:1323 +#: libvips/convolution/convasep.c:918 libvips/convolution/conv.c:141 +#: libvips/convolution/convsep.c:137 +msgid "Layers" +msgstr "" + +#: libvips/convolution/compass.c:192 libvips/convolution/conva.c:1324 +#: libvips/convolution/convasep.c:919 libvips/convolution/conv.c:142 +#: libvips/convolution/convsep.c:138 +msgid "Use this many layers in approximation" +msgstr "" + +#: libvips/convolution/compass.c:198 libvips/convolution/conva.c:1330 +#: libvips/convolution/conv.c:148 libvips/convolution/convsep.c:144 +msgid "Cluster" +msgstr "" + +#: libvips/convolution/compass.c:199 libvips/convolution/conva.c:1331 +#: libvips/convolution/conv.c:149 libvips/convolution/convsep.c:145 +msgid "Cluster lines closer than this in approximation" +msgstr "" + +#: libvips/convolution/conva.c:236 libvips/convolution/conva.c:242 +#: libvips/convolution/conva.c:760 libvips/convolution/convasep.c:151 +msgid "mask too complex" +msgstr "" + +#: libvips/convolution/conva.c:997 libvips/convolution/conva.c:1247 +#: libvips/convolution/convasep.c:840 +msgid "image too small for mask" +msgstr "" + +#: libvips/convolution/conva.c:1319 +msgid "approximate integer convolution" +msgstr "" + +#: libvips/convolution/convasep.c:914 +msgid "approximate separable integer convolution" +msgstr "" + +#: libvips/convolution/conv.c:130 +msgid "convolution operation" +msgstr "" + +#: libvips/convolution/convf.c:374 +msgid "float convolution operation" +msgstr "" + +#: libvips/convolution/convi.c:1245 +msgid "int convolution operation" +msgstr "" + +#: libvips/convolution/convolution.c:119 +msgid "convolution operations" +msgstr "" + +#: libvips/convolution/convolution.c:140 libvips/convolution/correlation.c:156 +#: libvips/draw/draw_mask.c:332 libvips/freqfilt/freqmult.c:130 +#: libvips/morphology/labelregions.c:124 libvips/morphology/morph.c:965 +msgid "Mask" +msgstr "" + +#: libvips/convolution/convolution.c:141 libvips/morphology/morph.c:966 +msgid "Input matrix image" +msgstr "" + +#: libvips/convolution/convsep.c:126 +msgid "separable convolution operation" +msgstr "" + +#: libvips/convolution/correlation.c:144 +msgid "correlation operation" +msgstr "" + +#: libvips/convolution/correlation.c:157 +msgid "Input reference image" +msgstr "" + +#: libvips/convolution/edge.c:213 +msgid "Edge detector" +msgstr "" + +#: libvips/convolution/edge.c:258 +msgid "Sobel edge detector" +msgstr "" + +#: libvips/convolution/edge.c:291 +msgid "Scharr edge detector" +msgstr "" + +#: libvips/convolution/edge.c:324 +msgid "Prewitt edge detector" +msgstr "" + +#: libvips/convolution/fastcor.c:218 +msgid "fast correlation" +msgstr "" + +#: libvips/convolution/gaussblur.c:126 +msgid "gaussian blur" +msgstr "" + +#: libvips/convolution/gaussblur.c:151 libvips/create/gaussmat.c:192 +msgid "Minimum amplitude" +msgstr "" + +#: libvips/convolution/gaussblur.c:152 libvips/create/gaussmat.c:193 +#: libvips/create/logmat.c:209 +msgid "Minimum amplitude of Gaussian" +msgstr "" + +#: libvips/convolution/sharpen.c:316 +msgid "unsharp masking for print" +msgstr "" + +#: libvips/convolution/sharpen.c:341 libvips/draw/draw_line.c:284 +msgid "x1" +msgstr "" + +#: libvips/convolution/sharpen.c:342 +msgid "Flat/jaggy threshold" +msgstr "" + +#: libvips/convolution/sharpen.c:348 libvips/draw/draw_line.c:305 +msgid "y2" +msgstr "" + +#: libvips/convolution/sharpen.c:349 +msgid "Maximum brightening" +msgstr "" + +#: libvips/convolution/sharpen.c:355 +msgid "y3" +msgstr "" + +#: libvips/convolution/sharpen.c:356 +msgid "Maximum darkening" +msgstr "" + +#: libvips/convolution/sharpen.c:362 +msgid "m1" +msgstr "" + +#: libvips/convolution/sharpen.c:363 +msgid "Slope for flat areas" +msgstr "" + +#: libvips/convolution/sharpen.c:369 +msgid "m2" +msgstr "" + +#: libvips/convolution/sharpen.c:370 +msgid "Slope for jaggy areas" +msgstr "" + +#: libvips/convolution/sharpen.c:378 libvips/create/logmat.c:201 +#: libvips/create/mask_butterworth_band.c:136 +#: libvips/create/mask_gaussian_band.c:121 libvips/create/mask_ideal_band.c:112 +#: libvips/create/sdf.c:326 libvips/draw/draw_circle.c:248 +msgid "Radius" +msgstr "" + +#: libvips/convolution/sharpen.c:379 libvips/create/logmat.c:202 +msgid "Radius of Gaussian" +msgstr "" + +#: libvips/convolution/spcor.c:317 +msgid "spatial correlation" +msgstr "" + +#: libvips/create/black.c:136 +msgid "make a black image" +msgstr "" + +#: libvips/create/buildlut.c:134 +#, c-format +msgid "x value row %d not an int" +msgstr "" + +#: libvips/create/buildlut.c:149 +msgid "x range too small" +msgstr "" + +#: libvips/create/buildlut.c:259 libvips/create/tonelut.c:221 +msgid "build a look-up table" +msgstr "" + +#: libvips/create/buildlut.c:264 libvips/create/invertlut.c:289 +msgid "Matrix of XY coordinates" +msgstr "" + +#: libvips/create/create.c:120 +msgid "create operations" +msgstr "" + +#: libvips/create/eye.c:103 +msgid "make an image showing the eye's spatial response" +msgstr "" + +#: libvips/create/eye.c:109 +msgid "Maximum spatial frequency" +msgstr "" + +#: libvips/create/fractsurf.c:100 +msgid "make a fractal surface" +msgstr "" + +#: libvips/create/fractsurf.c:118 libvips/create/fractsurf.c:119 +#: libvips/create/mask_fractal.c:93 libvips/create/mask_fractal.c:94 +msgid "Fractal dimension" +msgstr "" + +#: libvips/create/gaussmat.c:129 libvips/create/logmat.c:147 +msgid "mask too large" +msgstr "" + +#: libvips/create/gaussmat.c:181 +msgid "make a gaussian image" +msgstr "" + +#: libvips/create/gaussmat.c:199 libvips/create/logmat.c:215 +msgid "Separable" +msgstr "" + +#: libvips/create/gaussmat.c:200 libvips/create/logmat.c:216 +msgid "Generate separable Gaussian" +msgstr "" + +#: libvips/create/gaussmat.c:206 libvips/create/logmat.c:222 +msgid "Integer" +msgstr "" + +#: libvips/create/gaussmat.c:207 libvips/create/logmat.c:223 +msgid "Generate integer Gaussian" +msgstr "" + +#: libvips/create/gaussmat.c:214 libvips/create/logmat.c:230 +msgid "Generate with this precision" +msgstr "" + +#: libvips/create/gaussnoise.c:159 +msgid "make a gaussnoise image" +msgstr "" + +#: libvips/create/gaussnoise.c:181 libvips/histogram/stdif.c:329 +msgid "Mean" +msgstr "" + +#: libvips/create/gaussnoise.c:182 +msgid "Mean of pixels in generated image" +msgstr "" + +#: libvips/create/gaussnoise.c:189 +msgid "Standard deviation of pixels in generated image" +msgstr "" + +#: libvips/create/gaussnoise.c:195 libvips/create/perlin.c:322 +#: libvips/create/worley.c:328 +msgid "Seed" +msgstr "" + +#: libvips/create/gaussnoise.c:196 libvips/create/perlin.c:323 +#: libvips/create/worley.c:329 +msgid "Random number seed" +msgstr "" + +#: libvips/create/grey.c:89 +msgid "make a grey ramp image" +msgstr "" + +#: libvips/create/identity.c:139 +msgid "make a 1D image where pixel values are indexes" +msgstr "" + +#: libvips/create/identity.c:144 +msgid "Number of bands in LUT" +msgstr "" + +#: libvips/create/identity.c:150 +msgid "Ushort" +msgstr "" + +#: libvips/create/identity.c:151 +msgid "Create a 16-bit LUT" +msgstr "" + +#: libvips/create/identity.c:158 +msgid "Size of 16-bit LUT" +msgstr "" + +#: libvips/create/invertlut.c:124 +msgid "bad input matrix" +msgstr "" + +#: libvips/create/invertlut.c:129 +msgid "bad size" +msgstr "" + +#: libvips/create/invertlut.c:149 +#, c-format +msgid "element (%d, %d) is %g, outside range [0,1]" +msgstr "" + +#: libvips/create/invertlut.c:284 +msgid "build an inverted look-up table" +msgstr "" + +#: libvips/create/invertlut.c:295 +msgid "LUT size to generate" +msgstr "" + +#: libvips/create/logmat.c:197 +msgid "make a Laplacian of Gaussian image" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:110 +msgid "make a butterworth_band filter" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:115 +#: libvips/create/mask_butterworth.c:91 +msgid "Order" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:116 +#: libvips/create/mask_butterworth.c:92 +msgid "Filter order" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:122 +#: libvips/create/mask_butterworth_band.c:123 +#: libvips/create/mask_gaussian_band.c:107 +#: libvips/create/mask_gaussian_band.c:108 libvips/create/mask_ideal_band.c:98 +#: libvips/create/mask_ideal_band.c:99 +msgid "Frequency cutoff x" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:129 +#: libvips/create/mask_butterworth_band.c:130 +#: libvips/create/mask_gaussian_band.c:114 +#: libvips/create/mask_gaussian_band.c:115 libvips/create/mask_ideal_band.c:105 +#: libvips/create/mask_ideal_band.c:106 +msgid "Frequency cutoff y" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:137 +#: libvips/create/mask_gaussian_band.c:122 libvips/create/mask_ideal_band.c:113 +msgid "Radius of circle" +msgstr "" + +#: libvips/create/mask_butterworth_band.c:143 +#: libvips/create/mask_butterworth_band.c:144 +#: libvips/create/mask_butterworth.c:105 libvips/create/mask_butterworth.c:106 +#: libvips/create/mask_gaussian_band.c:128 +#: libvips/create/mask_gaussian_band.c:129 libvips/create/mask_gaussian.c:93 +#: libvips/create/mask_gaussian.c:94 +msgid "Amplitude cutoff" +msgstr "" + +#: libvips/create/mask_butterworth.c:86 +msgid "make a butterworth filter" +msgstr "" + +#: libvips/create/mask_butterworth.c:98 libvips/create/mask_butterworth.c:99 +#: libvips/create/mask_gaussian.c:86 libvips/create/mask_gaussian.c:87 +#: libvips/create/mask_ideal.c:84 libvips/create/mask_ideal.c:85 +msgid "Frequency cutoff" +msgstr "" + +#: libvips/create/mask_butterworth_ring.c:101 +msgid "make a butterworth ring filter" +msgstr "" + +#: libvips/create/mask_butterworth_ring.c:106 +#: libvips/create/mask_butterworth_ring.c:107 +#: libvips/create/mask_gaussian_ring.c:101 +#: libvips/create/mask_gaussian_ring.c:102 libvips/create/mask_ideal_ring.c:98 +#: libvips/create/mask_ideal_ring.c:99 +msgid "Ringwidth" +msgstr "" + +#: libvips/create/mask.c:114 +msgid "base class for frequency filters" +msgstr "" + +#: libvips/create/mask.c:122 +msgid "Optical" +msgstr "" + +#: libvips/create/mask.c:123 +msgid "Rotate quadrants to optical space" +msgstr "" + +#: libvips/create/mask.c:129 +msgid "Reject" +msgstr "" + +#: libvips/create/mask.c:130 +msgid "Invert the sense of the filter" +msgstr "" + +#: libvips/create/mask.c:136 +msgid "Nodc" +msgstr "" + +#: libvips/create/mask.c:137 +msgid "Remove DC component" +msgstr "" + +#: libvips/create/mask_fractal.c:88 +msgid "make fractal filter" +msgstr "" + +#: libvips/create/mask_gaussian_band.c:102 libvips/create/mask_gaussian.c:81 +msgid "make a gaussian filter" +msgstr "" + +#: libvips/create/mask_gaussian_ring.c:96 +msgid "make a gaussian ring filter" +msgstr "" + +#: libvips/create/mask_ideal_band.c:93 +msgid "make an ideal band filter" +msgstr "" + +#: libvips/create/mask_ideal.c:79 +msgid "make an ideal filter" +msgstr "" + +#: libvips/create/mask_ideal_ring.c:93 +msgid "make an ideal ring filter" +msgstr "" + +#: libvips/create/perlin.c:290 +msgid "make a perlin noise image" +msgstr "" + +#: libvips/create/perlin.c:308 libvips/create/worley.c:321 +msgid "Cell size" +msgstr "" + +#: libvips/create/perlin.c:309 +msgid "Size of Perlin cells" +msgstr "" + +#: libvips/create/perlin.c:315 libvips/create/point.c:155 +msgid "Uchar" +msgstr "" + +#: libvips/create/perlin.c:316 libvips/create/point.c:156 +msgid "Output an unsigned char image" +msgstr "" + +#: libvips/create/point.c:132 +msgid "make a point image" +msgstr "" + +#: libvips/create/sdf.c:178 +msgid "circle needs a, r to be set" +msgstr "" + +#: libvips/create/sdf.c:183 +msgid "rounded-box needs 2 values for a" +msgstr "" + +#: libvips/create/sdf.c:196 +msgid "box needs a, b to be set" +msgstr "" + +#: libvips/create/sdf.c:202 +msgid "box needs 2 values for a, b" +msgstr "" + +#: libvips/create/sdf.c:216 +msgid "rounded-box needs a, b to be set" +msgstr "" + +#: libvips/create/sdf.c:222 +msgid "rounded-box needs 2 values for a, b" +msgstr "" + +#: libvips/create/sdf.c:227 +msgid "rounded-box needs 4 values for corners" +msgstr "" + +#: libvips/create/sdf.c:242 +msgid "line needs sx, sy to be set" +msgstr "" + +#: libvips/create/sdf.c:248 +msgid "line needs 2 values for a, b" +msgstr "" + +#: libvips/create/sdf.c:259 +#, c-format +msgid "unknown SDF %d" +msgstr "" + +#: libvips/create/sdf.c:300 +msgid "create an SDF image" +msgstr "" + +#: libvips/create/sdf.c:318 +msgid "Shape" +msgstr "" + +#: libvips/create/sdf.c:319 +msgid "SDF shape to create" +msgstr "" + +#: libvips/create/sdf.c:325 +msgid "r" +msgstr "" + +#: libvips/create/sdf.c:333 +msgid "Point a" +msgstr "" + +#: libvips/create/sdf.c:340 +msgid "Point b" +msgstr "" + +#: libvips/create/sdf.c:346 +msgid "corners" +msgstr "" + +#: libvips/create/sdf.c:347 +msgid "Corner radii" +msgstr "" + +#: libvips/create/sines.c:122 +msgid "make a 2D sine wave" +msgstr "" + +#: libvips/create/sines.c:128 +msgid "hfreq" +msgstr "" + +#: libvips/create/sines.c:129 +msgid "Horizontal spatial frequency" +msgstr "" + +#: libvips/create/sines.c:135 +msgid "vfreq" +msgstr "" + +#: libvips/create/sines.c:136 +msgid "Vertical spatial frequency" +msgstr "" + +#: libvips/create/text.c:406 +msgid "invalid markup in text" +msgstr "" + +#: libvips/create/text.c:428 +#, c-format +msgid "unable to load fontfile \"%s\"" +msgstr "" + +#: libvips/create/text.c:467 +msgid "no text to render" msgstr "" -#: ../libvips/conversion/copy.c:326 ../libvips/foreign/tiffsave.c:260 -#: ../libvips/iofuncs/image.c:1172 -msgid "Xres" +#: libvips/create/text.c:549 +msgid "make a text image" msgstr "" -#: ../libvips/conversion/copy.c:327 ../libvips/foreign/tiffsave.c:261 -#: ../libvips/iofuncs/image.c:1173 -msgid "Horizontal resolution in pixels/mm" +#: libvips/create/text.c:553 +msgid "Text" msgstr "" -#: ../libvips/conversion/copy.c:333 ../libvips/foreign/tiffsave.c:267 -#: ../libvips/iofuncs/image.c:1179 -msgid "Yres" +#: libvips/create/text.c:554 +msgid "Text to render" msgstr "" -#: ../libvips/conversion/copy.c:334 ../libvips/foreign/tiffsave.c:268 -#: ../libvips/iofuncs/image.c:1180 -msgid "Vertical resolution in pixels/mm" +#: libvips/create/text.c:560 +msgid "Font" msgstr "" -#: ../libvips/conversion/copy.c:340 ../libvips/iofuncs/image.c:1186 -msgid "Xoffset" +#: libvips/create/text.c:561 +msgid "Font to render with" msgstr "" -#: ../libvips/conversion/copy.c:341 ../libvips/iofuncs/image.c:1187 -msgid "Horizontal offset of origin" +#: libvips/create/text.c:568 +msgid "Maximum image width in pixels" msgstr "" -#: ../libvips/conversion/copy.c:347 ../libvips/iofuncs/image.c:1193 -msgid "Yoffset" +#: libvips/create/text.c:575 +msgid "Maximum image height in pixels" msgstr "" -#: ../libvips/conversion/copy.c:348 ../libvips/iofuncs/image.c:1194 -msgid "Vertical offset of origin" +#: libvips/create/text.c:582 +msgid "Align on the low, centre or high edge" msgstr "" -#: ../libvips/conversion/bandjoin.c:170 -msgid "bandwise join a set of images" +#: libvips/create/text.c:588 +msgid "Justify" msgstr "" -#: ../libvips/conversion/bandjoin.c:389 -msgid "append a constant band to an image" +#: libvips/create/text.c:589 +msgid "Justify lines" msgstr "" -#: ../libvips/conversion/bandjoin.c:401 -msgid "Constants" +#: libvips/create/text.c:595 libvips/foreign/pdfiumload.c:709 +#: libvips/foreign/popplerload.c:559 libvips/foreign/svgload.c:717 +msgid "DPI" msgstr "" -#: ../libvips/conversion/bandjoin.c:402 -msgid "Array of constants to add" +#: libvips/create/text.c:596 libvips/foreign/pdfiumload.c:710 +#: libvips/foreign/popplerload.c:560 +msgid "DPI to render at" msgstr "" -#: ../libvips/conversion/rot45.c:263 ../libvips/conversion/rot.c:355 -msgid "rotate an image" +#: libvips/create/text.c:602 +msgid "Autofit DPI" msgstr "" -#: ../libvips/conversion/rot45.c:273 ../libvips/conversion/autorot.c:184 -#: ../libvips/conversion/rot.c:365 ../libvips/convolution/compass.c:157 -#: ../libvips/foreign/dzsave.c:2178 ../libvips/mosaicing/mosaic.c:282 -#: ../libvips/resample/similarity.c:178 -msgid "Angle" +#: libvips/create/text.c:603 +msgid "DPI selected by autofit" msgstr "" -#: ../libvips/conversion/rot45.c:274 ../libvips/conversion/rot.c:366 -msgid "Angle to rotate image" +#: libvips/create/text.c:609 +msgid "Spacing" msgstr "" -#: ../libvips/conversion/msb.c:166 -msgid "bad band" +#: libvips/create/text.c:610 +msgid "Line spacing" msgstr "" -#: ../libvips/conversion/msb.c:238 -msgid "pick most-significant byte from an image" +#: libvips/create/text.c:616 +msgid "Font file" msgstr "" -#: ../libvips/conversion/msb.c:251 -msgid "Band to msb" +#: libvips/create/text.c:617 +msgid "Load this font file" msgstr "" -#: ../libvips/conversion/extract.c:150 -msgid "bad extract area" +#: libvips/create/text.c:623 +msgid "RGBA" msgstr "" -#: ../libvips/conversion/extract.c:193 -msgid "extract an area from an image" +#: libvips/create/text.c:624 +msgid "Enable RGBA output" msgstr "" -#: ../libvips/conversion/extract.c:387 -msgid "bad extract band" +#: libvips/create/text.c:630 +msgid "Wrap" msgstr "" -#: ../libvips/conversion/extract.c:416 -msgid "extract band from an image" +#: libvips/create/text.c:631 +msgid "Wrap lines on word or character boundaries" msgstr "" -#: ../libvips/conversion/extract.c:429 -msgid "Band to extract" +#: libvips/create/tonelut.c:225 +msgid "In-max" msgstr "" -#: ../libvips/conversion/extract.c:435 ../libvips/foreign/magickload.c:138 -#: ../libvips/foreign/gifload.c:823 ../libvips/foreign/magick7load.c:400 -#: ../libvips/foreign/pdfload.c:475 ../libvips/foreign/tiffload.c:106 -msgid "n" +#: libvips/create/tonelut.c:226 +msgid "Size of LUT to build" msgstr "" -#: ../libvips/conversion/extract.c:436 -msgid "Number of bands to extract" +#: libvips/create/tonelut.c:232 +msgid "Out-max" msgstr "" -#: ../libvips/conversion/cast.c:131 -#, c-format -msgid "%d underflows and %d overflows detected" +#: libvips/create/tonelut.c:233 +msgid "Maximum value in output LUT" msgstr "" -#: ../libvips/conversion/cast.c:542 -msgid "cast an image" +#: libvips/create/tonelut.c:239 +msgid "Black point" msgstr "" -#: ../libvips/conversion/cast.c:555 -msgid "Format to cast to" +#: libvips/create/tonelut.c:240 +msgid "Lowest value in output" msgstr "" -#: ../libvips/conversion/cast.c:561 -msgid "Shift" +#: libvips/create/tonelut.c:246 +msgid "White point" msgstr "" -#: ../libvips/conversion/cast.c:562 -msgid "Shift integer values up and down" +#: libvips/create/tonelut.c:247 +msgid "Highest value in output" msgstr "" -#: ../libvips/conversion/bandunfold.c:125 -msgid "@factor must be a factor of image bands" +#: libvips/create/tonelut.c:253 +msgid "Shadow point" msgstr "" -#: ../libvips/conversion/bandunfold.c:157 -msgid "unfold image bands into x axis" +#: libvips/create/tonelut.c:254 +msgid "Position of shadow" msgstr "" -#: ../libvips/conversion/bandunfold.c:170 -msgid "Unfold by this factor" +#: libvips/create/tonelut.c:260 +msgid "Mid-tone point" msgstr "" -#: ../libvips/conversion/tilecache.c:410 ../libvips/conversion/cache.c:97 -msgid "cache an image" +#: libvips/create/tonelut.c:261 +msgid "Position of mid-tones" msgstr "" -#: ../libvips/conversion/tilecache.c:422 ../libvips/conversion/sequential.c:340 -#: ../libvips/conversion/cache.c:114 ../libvips/conversion/grid.c:205 -#: ../libvips/foreign/tiffsave.c:225 ../libvips/foreign/dzsave.c:2224 -msgid "Tile height" +#: libvips/create/tonelut.c:267 +msgid "Highlight point" msgstr "" -#: ../libvips/conversion/tilecache.c:423 ../libvips/conversion/sequential.c:341 -#: ../libvips/conversion/cache.c:115 ../libvips/foreign/tiffsave.c:226 -#: ../libvips/foreign/dzsave.c:2225 -msgid "Tile height in pixels" +#: libvips/create/tonelut.c:268 +msgid "Position of highlights" msgstr "" -#: ../libvips/conversion/tilecache.c:429 ../libvips/conversion/tilecache.c:999 -#: ../libvips/foreign/foreign.c:1004 -msgid "Access" +#: libvips/create/tonelut.c:274 +msgid "Shadow adjust" msgstr "" -#: ../libvips/conversion/tilecache.c:430 ../libvips/conversion/tilecache.c:1000 -#: ../libvips/conversion/sequential.c:348 -msgid "Expected access pattern" +#: libvips/create/tonelut.c:275 +msgid "Adjust shadows by this much" msgstr "" -#: ../libvips/conversion/tilecache.c:436 -msgid "Threaded" +#: libvips/create/tonelut.c:281 +msgid "Mid-tone adjust" msgstr "" -#: ../libvips/conversion/tilecache.c:437 -msgid "Allow threaded access" +#: libvips/create/tonelut.c:282 +msgid "Adjust mid-tones by this much" msgstr "" -#: ../libvips/conversion/tilecache.c:443 -msgid "Persistent" +#: libvips/create/tonelut.c:288 +msgid "Highlight adjust" msgstr "" -#: ../libvips/conversion/tilecache.c:444 -msgid "Keep cache between evaluations" +#: libvips/create/tonelut.c:289 +msgid "Adjust highlights by this much" msgstr "" -#: ../libvips/conversion/tilecache.c:704 -#, c-format -msgid "error in tile %d x %d" +#: libvips/create/worley.c:303 +msgid "make a worley noise image" msgstr "" -#: ../libvips/conversion/tilecache.c:795 -msgid "cache an image as a set of tiles" +#: libvips/create/worley.c:322 +msgid "Size of Worley cells" msgstr "" -#: ../libvips/conversion/tilecache.c:799 ../libvips/conversion/cache.c:107 -#: ../libvips/foreign/tiffsave.c:218 ../libvips/foreign/dzsave.c:2217 -msgid "Tile width" +#: libvips/create/xyz.c:139 +msgid "lower dimensions not set" msgstr "" -#: ../libvips/conversion/tilecache.c:800 ../libvips/conversion/cache.c:108 -#: ../libvips/foreign/tiffsave.c:219 ../libvips/foreign/dzsave.c:2218 -msgid "Tile width in pixels" +#: libvips/create/xyz.c:156 libvips/foreign/heifsave.c:682 +#: libvips/foreign/webpsave.c:734 +msgid "image too large" msgstr "" -#: ../libvips/conversion/tilecache.c:806 ../libvips/conversion/cache.c:121 -msgid "Max tiles" +#: libvips/create/xyz.c:187 +msgid "make an image where pixel values are coordinates" msgstr "" -#: ../libvips/conversion/tilecache.c:807 ../libvips/conversion/cache.c:122 -msgid "Maximum number of tiles to cache" +#: libvips/create/xyz.c:205 +msgid "csize" msgstr "" -#: ../libvips/conversion/tilecache.c:995 -msgid "cache an image as a set of lines" +#: libvips/create/xyz.c:206 +msgid "Size of third dimension" msgstr "" -#: ../libvips/conversion/sequential.c:323 -msgid "check sequential access" +#: libvips/create/xyz.c:212 +msgid "dsize" msgstr "" -#: ../libvips/conversion/sequential.c:333 -msgid "trace" +#: libvips/create/xyz.c:213 +msgid "Size of fourth dimension" msgstr "" -#: ../libvips/conversion/sequential.c:334 -msgid "trace pixel requests" +#: libvips/create/xyz.c:219 +msgid "esize" msgstr "" -#: ../libvips/conversion/sequential.c:347 -msgid "Strategy" +#: libvips/create/xyz.c:220 +msgid "Size of fifth dimension" msgstr "" -#: ../libvips/conversion/premultiply.c:253 -msgid "premultiply image alpha" +#: libvips/create/zone.c:90 +msgid "make a zone plate" msgstr "" -#: ../libvips/conversion/bandmean.c:192 -msgid "band-wise average" +#: libvips/draw/draw.c:131 +msgid "draw operations" msgstr "" -#: ../libvips/conversion/bandmean.c:199 ../libvips/conversion/bandbool.c:215 -#: ../libvips/conversion/recomb.c:208 ../libvips/convolution/convolution.c:130 -#: ../libvips/convolution/correlation.c:152 -#: ../libvips/morphology/morphology.c:118 ../libvips/resample/resample.c:133 -msgid "Input image argument" +#: libvips/draw/draw.c:138 +msgid "Image" msgstr "" -#: ../libvips/conversion/falsecolour.c:375 -msgid "false-color an image" -msgstr "false-colour an image" +#: libvips/draw/draw.c:139 +msgid "Image to draw on" +msgstr "" -#: ../libvips/conversion/byteswap.c:200 -msgid "byteswap an image" +#: libvips/draw/draw_circle.c:230 +msgid "draw a circle on an image" msgstr "" -#: ../libvips/conversion/subsample.c:230 ../libvips/resample/shrinkv.c:393 -#: ../libvips/resample/shrinkh.c:289 ../libvips/resample/reduceh.cpp:528 -#: ../libvips/resample/reducev.cpp:801 -msgid "image has shrunk to nothing" +#: libvips/draw/draw_circle.c:234 +msgid "cx" msgstr "" -#: ../libvips/conversion/subsample.c:266 -msgid "subsample an image" +#: libvips/draw/draw_circle.c:235 libvips/draw/draw_circle.c:242 +msgid "Centre of draw_circle" msgstr "" -#: ../libvips/conversion/subsample.c:281 -msgid "Horizontal subsample factor" +#: libvips/draw/draw_circle.c:241 +msgid "cy" msgstr "" -#: ../libvips/conversion/subsample.c:288 -msgid "Vertical subsample factor" +#: libvips/draw/draw_circle.c:249 +msgid "Radius in pixels" msgstr "" -#: ../libvips/conversion/subsample.c:294 -msgid "Point" +#: libvips/draw/draw_circle.c:255 libvips/draw/draw_rect.c:201 +msgid "Fill" msgstr "" -#: ../libvips/conversion/subsample.c:295 -msgid "Point sample" +#: libvips/draw/draw_circle.c:256 libvips/draw/draw_rect.c:202 +msgid "Draw a solid object" msgstr "" -#: ../libvips/conversion/bandbool.c:75 -#, c-format -msgid "operator %s not supported across image bands" +#: libvips/draw/draw_flood.c:562 +msgid "flood-fill an area" msgstr "" -#: ../libvips/conversion/bandbool.c:207 -msgid "boolean operation across image bands" +#: libvips/draw/draw_flood.c:567 libvips/draw/draw_flood.c:574 +msgid "DrawFlood start point" msgstr "" -#: ../libvips/conversion/recomb.c:166 -msgid "bands in must equal matrix width" +#: libvips/draw/draw_flood.c:580 +msgid "Test" msgstr "" -#: ../libvips/conversion/recomb.c:201 -msgid "linear recombination with matrix" +#: libvips/draw/draw_flood.c:581 +msgid "Test pixels in this image" msgstr "" -#: ../libvips/conversion/recomb.c:213 -msgid "M" +#: libvips/draw/draw_flood.c:586 +msgid "Equal" msgstr "" -#: ../libvips/conversion/recomb.c:214 -msgid "matrix of coefficients" +#: libvips/draw/draw_flood.c:587 +msgid "DrawFlood while equal to edge" msgstr "" -#: ../libvips/conversion/bandary.c:135 -msgid "no input images" +#: libvips/draw/draw_flood.c:594 +msgid "Left edge of modified area" msgstr "" -#: ../libvips/conversion/bandary.c:186 -msgid "operations on image bands" +#: libvips/draw/draw_flood.c:601 +msgid "Top edge of modified area" msgstr "" -#: ../libvips/conversion/ifthenelse.c:479 -msgid "ifthenelse an image" +#: libvips/draw/draw_flood.c:608 +msgid "Width of modified area" msgstr "" -#: ../libvips/conversion/ifthenelse.c:483 -msgid "Condition" +#: libvips/draw/draw_flood.c:615 +msgid "Height of modified area" msgstr "" -#: ../libvips/conversion/ifthenelse.c:484 -msgid "Condition input image" +#: libvips/draw/draw_image.c:265 +msgid "paint an image into another image" msgstr "" -#: ../libvips/conversion/ifthenelse.c:489 -msgid "Then image" +#: libvips/draw/draw_image.c:276 libvips/draw/draw_image.c:283 +msgid "Draw image here" msgstr "" -#: ../libvips/conversion/ifthenelse.c:490 -msgid "Source for TRUE pixels" +#: libvips/draw/draw_image.c:289 libvips/iofuncs/image.c:1179 +msgid "Mode" msgstr "" -#: ../libvips/conversion/ifthenelse.c:495 -msgid "Else image" +#: libvips/draw/draw_image.c:290 +msgid "Combining mode" msgstr "" -#: ../libvips/conversion/ifthenelse.c:496 -msgid "Source for FALSE pixels" +#: libvips/draw/drawink.c:86 +msgid "draw with ink operations" msgstr "" -#: ../libvips/conversion/ifthenelse.c:501 -msgid "blend" +#: libvips/draw/drawink.c:90 +msgid "Ink" msgstr "" -#: ../libvips/conversion/ifthenelse.c:502 -msgid "Blend smoothly between then and else parts" +#: libvips/draw/drawink.c:91 +msgid "Color for pixels" msgstr "" -#: ../libvips/conversion/gamma.c:137 -msgid "gamma an image" +#: libvips/draw/draw_line.c:280 +msgid "draw a line on an image" msgstr "" -#: ../libvips/conversion/gamma.c:149 -msgid "exponent" +#: libvips/draw/draw_line.c:285 libvips/draw/draw_line.c:292 +msgid "Start of draw_line" msgstr "" -#: ../libvips/conversion/gamma.c:150 -msgid "Gamma factor" +#: libvips/draw/draw_line.c:291 +msgid "y1" msgstr "" -#: ../libvips/conversion/join.c:228 -msgid "join a pair of images" +#: libvips/draw/draw_line.c:298 +msgid "x2" msgstr "" -#: ../libvips/conversion/join.c:232 -msgid "in1" +#: libvips/draw/draw_line.c:299 libvips/draw/draw_line.c:306 +msgid "End of draw_line" msgstr "" -#: ../libvips/conversion/join.c:233 -msgid "First input image" +#: libvips/draw/draw_mask.c:328 +msgid "draw a mask on an image" msgstr "" -#: ../libvips/conversion/join.c:238 ../libvips/freqfilt/phasecor.c:112 -msgid "in2" +#: libvips/draw/draw_mask.c:333 +msgid "Mask of pixels to draw" msgstr "" -#: ../libvips/conversion/join.c:239 ../libvips/freqfilt/phasecor.c:113 -msgid "Second input image" +#: libvips/draw/draw_mask.c:339 libvips/draw/draw_mask.c:346 +msgid "Draw mask here" msgstr "" -#: ../libvips/conversion/join.c:244 ../libvips/morphology/countlines.c:142 -msgid "direction" +#: libvips/draw/draw_rect.c:169 +msgid "paint a rectangle on an image" msgstr "" -#: ../libvips/conversion/join.c:245 -msgid "Join left-right or up-down" +#: libvips/draw/draw_rect.c:174 libvips/draw/draw_rect.c:181 +#: libvips/draw/draw_rect.c:188 libvips/draw/draw_rect.c:195 +#: libvips/draw/draw_smudge.c:216 libvips/draw/draw_smudge.c:223 +#: libvips/draw/draw_smudge.c:230 libvips/draw/draw_smudge.c:237 +msgid "Rect to fill" msgstr "" -#: ../libvips/conversion/join.c:251 ../libvips/conversion/insert.c:543 -msgid "Expand" +#: libvips/draw/draw_smudge.c:211 +msgid "blur a rectangle on an image" msgstr "" -#: ../libvips/conversion/join.c:252 ../libvips/conversion/insert.c:544 -msgid "Expand output to hold all of both inputs" +#: libvips/foreign/analyze2vips.c:308 +msgid "header file size incorrect" msgstr "" -#: ../libvips/conversion/join.c:272 ../libvips/create/text.c:304 -msgid "Align" +#: libvips/foreign/analyze2vips.c:352 +msgid "header size incorrect" msgstr "" -#: ../libvips/conversion/join.c:273 -msgid "Align on the low, centre or high coordinate edge" +#: libvips/foreign/analyze2vips.c:370 libvips/foreign/niftiload.c:399 +#, c-format +msgid "%d-dimensional images not supported" msgstr "" -#: ../libvips/conversion/grid.c:165 -msgid "bad grid geometry" +#: libvips/foreign/analyze2vips.c:423 libvips/foreign/niftiload.c:442 +#, c-format +msgid "datatype %d not supported" msgstr "" -#: ../libvips/conversion/grid.c:195 -msgid "grid an image" +#: libvips/foreign/analyzeload.c:120 +msgid "load an Analyze6 image" msgstr "" -#: ../libvips/conversion/grid.c:206 -msgid "chop into tiles this high" +#: libvips/foreign/analyzeload.c:141 libvips/foreign/cgifsave.c:1058 +#: libvips/foreign/csvload.c:590 libvips/foreign/csvsave.c:274 +#: libvips/foreign/dzsave.c:2597 libvips/foreign/fitsload.c:259 +#: libvips/foreign/fitssave.c:143 libvips/foreign/heifload.c:1271 +#: libvips/foreign/heifsave.c:897 libvips/foreign/jp2kload.c:1309 +#: libvips/foreign/jp2ksave.c:1063 libvips/foreign/jpegload.c:354 +#: libvips/foreign/jpegsave.c:361 libvips/foreign/jxlload.c:1218 +#: libvips/foreign/jxlsave.c:897 libvips/foreign/magick6load.c:238 +#: libvips/foreign/magick7load.c:851 libvips/foreign/matload.c:138 +#: libvips/foreign/matrixload.c:374 libvips/foreign/matrixsave.c:228 +#: libvips/foreign/niftiload.c:713 libvips/foreign/niftisave.c:441 +#: libvips/foreign/nsgifload.c:765 libvips/foreign/openexrload.c:149 +#: libvips/foreign/openslideload.c:1152 libvips/foreign/pdfiumload.c:812 +#: libvips/foreign/pngload.c:318 libvips/foreign/pngsave.c:378 +#: libvips/foreign/popplerload.c:689 libvips/foreign/ppmload.c:829 +#: libvips/foreign/ppmsave.c:592 libvips/foreign/radload.c:281 +#: libvips/foreign/radsave.c:154 libvips/foreign/rawload.c:139 +#: libvips/foreign/rawsave.c:196 libvips/foreign/spngload.c:835 +#: libvips/foreign/spngsave.c:858 libvips/foreign/svgload.c:929 +#: libvips/foreign/tiffload.c:382 libvips/foreign/tiffsave.c:527 +#: libvips/foreign/vips2magick.c:578 libvips/foreign/vipsload.c:236 +#: libvips/foreign/vipssave.c:197 libvips/foreign/webpload.c:346 +#: libvips/foreign/webpsave.c:1038 libvips/iofuncs/connection.c:133 +#: libvips/iofuncs/image.c:1172 libvips/resample/thumbnail.c:1198 +msgid "Filename" msgstr "" -#: ../libvips/conversion/grid.c:213 -msgid "number of tiles across" +#: libvips/foreign/analyzeload.c:142 libvips/foreign/csvload.c:591 +#: libvips/foreign/fitsload.c:260 libvips/foreign/heifload.c:1272 +#: libvips/foreign/jp2kload.c:1310 libvips/foreign/jpegload.c:355 +#: libvips/foreign/jxlload.c:1219 libvips/foreign/magick6load.c:239 +#: libvips/foreign/magick7load.c:852 libvips/foreign/matload.c:139 +#: libvips/foreign/matrixload.c:375 libvips/foreign/niftiload.c:714 +#: libvips/foreign/nsgifload.c:766 libvips/foreign/openexrload.c:150 +#: libvips/foreign/openslideload.c:1153 libvips/foreign/pdfiumload.c:813 +#: libvips/foreign/pngload.c:319 libvips/foreign/popplerload.c:690 +#: libvips/foreign/ppmload.c:830 libvips/foreign/radload.c:282 +#: libvips/foreign/rawload.c:140 libvips/foreign/spngload.c:836 +#: libvips/foreign/svgload.c:930 libvips/foreign/tiffload.c:383 +#: libvips/foreign/vipsload.c:237 libvips/foreign/webpload.c:347 +msgid "Filename to load from" msgstr "" -#: ../libvips/conversion/grid.c:220 -msgid "number of tiles down" +#: libvips/foreign/archive.c:138 +msgid "unable to create archive" msgstr "" -#: ../libvips/conversion/scale.c:147 -msgid "scale an image to uchar" +#: libvips/foreign/archive.c:146 +msgid "unable to set zip format" msgstr "" -#: ../libvips/conversion/scale.c:157 ../libvips/iofuncs/system.c:311 -msgid "Log" +#: libvips/foreign/archive.c:163 +msgid "unable to set compression" msgstr "" -#: ../libvips/conversion/scale.c:158 -msgid "Log scale" +#: libvips/foreign/archive.c:175 +msgid "unable to set padding" msgstr "" -#: ../libvips/conversion/scale.c:164 -msgid "Exponent" +#: libvips/foreign/archive.c:184 libvips/iofuncs/target.c:129 +msgid "unable to open for write" msgstr "" -#: ../libvips/conversion/scale.c:165 -msgid "Exponent for log scale" +#: libvips/foreign/archive.c:205 libvips/iofuncs/util.c:1097 +#, c-format +msgid "unable to create directory \"%s\", %s" msgstr "" -#: ../libvips/conversion/insert.c:509 -msgid "insert image @sub into @main at @x, @y" +#: libvips/foreign/archive.c:240 +msgid "unable to create entry" msgstr "" -#: ../libvips/conversion/insert.c:517 -msgid "Main" +#: libvips/foreign/archive.c:256 +msgid "unable to write header" msgstr "" -#: ../libvips/conversion/insert.c:518 -msgid "Main input image" +#: libvips/foreign/archive.c:265 +msgid "unable to write data" msgstr "" -#: ../libvips/conversion/insert.c:523 ../libvips/draw/draw_image.c:259 -msgid "Sub-image" +#: libvips/foreign/cgifsave.c:407 libvips/foreign/cgifsave.c:833 +#: libvips/foreign/quantise.c:403 libvips/foreign/quantise.c:423 +msgid "quantisation failed" msgstr "" -#: ../libvips/conversion/insert.c:524 ../libvips/draw/draw_image.c:260 -msgid "Sub-image to insert into main image" +#: libvips/foreign/cgifsave.c:587 +msgid "dither failed" msgstr "" -#: ../libvips/conversion/insert.c:529 -msgid "X" +#: libvips/foreign/cgifsave.c:772 +msgid "frame too large" msgstr "" -#: ../libvips/conversion/insert.c:530 -msgid "Left edge of sub in main" +#: libvips/foreign/cgifsave.c:811 +msgid "gif-palette too large" msgstr "" -#: ../libvips/conversion/insert.c:536 -msgid "Y" +#: libvips/foreign/cgifsave.c:884 +msgid "save as gif" msgstr "" -#: ../libvips/conversion/insert.c:537 -msgid "Top edge of sub in main" +#: libvips/foreign/cgifsave.c:893 libvips/foreign/pngsave.c:247 +#: libvips/foreign/spngsave.c:725 +msgid "Dithering" msgstr "" -#: ../libvips/conversion/insert.c:551 -msgid "Color for new pixels" +#: libvips/foreign/cgifsave.c:894 libvips/foreign/pngsave.c:248 +#: libvips/foreign/spngsave.c:726 +msgid "Amount of dithering" msgstr "" -#: ../libvips/conversion/autorot.c:174 -msgid "autorotate image by exif tag" +#: libvips/foreign/cgifsave.c:900 libvips/foreign/heifsave.c:803 +#: libvips/foreign/jxlsave.c:824 libvips/foreign/pngsave.c:261 +#: libvips/foreign/spngsave.c:739 libvips/foreign/webpsave.c:890 +msgid "Effort" msgstr "" -#: ../libvips/conversion/autorot.c:185 -msgid "Angle image was rotated by" +#: libvips/foreign/cgifsave.c:901 +msgid "Quantisation effort" msgstr "" -#: ../libvips/conversion/bandrank.c:238 -msgid "band-wise rank of a set of images" +#: libvips/foreign/cgifsave.c:907 libvips/foreign/heifsave.c:781 +#: libvips/foreign/pngsave.c:254 libvips/foreign/ppmsave.c:521 +#: libvips/foreign/spngsave.c:732 libvips/foreign/tiffsave.c:315 +#: libvips/foreign/vips2magick.c:510 +msgid "Bit depth" msgstr "" -#: ../libvips/conversion/bandrank.c:252 -msgid "Select this band element from sorted list" +#: libvips/foreign/cgifsave.c:908 libvips/foreign/heifsave.c:782 +#: libvips/foreign/vips2magick.c:511 +msgid "Number of bits per pixel" msgstr "" -#: ../libvips/convolution/spcor.c:315 -msgid "spatial correlation" +#: libvips/foreign/cgifsave.c:914 +msgid "Maximum inter-frame error" msgstr "" -#: ../libvips/convolution/conva.c:237 ../libvips/convolution/conva.c:243 -#: ../libvips/convolution/conva.c:760 ../libvips/convolution/convasep.c:152 -msgid "mask too complex" +#: libvips/foreign/cgifsave.c:915 +msgid "Maximum inter-frame error for transparency" msgstr "" -#: ../libvips/convolution/conva.c:988 ../libvips/convolution/conva.c:1216 -#: ../libvips/convolution/convasep.c:823 ../libvips/morphology/hitmiss.c:732 -msgid "image too small for mask" +#: libvips/foreign/cgifsave.c:921 +msgid "Reuse palette" msgstr "" -#: ../libvips/convolution/conva.c:1288 -msgid "approximate integer convolution" +#: libvips/foreign/cgifsave.c:922 +msgid "Reuse palette from input" msgstr "" -#: ../libvips/convolution/conva.c:1292 ../libvips/convolution/compass.c:178 -#: ../libvips/convolution/convasep.c:901 ../libvips/convolution/convsep.c:134 -#: ../libvips/convolution/conv.c:143 -msgid "Layers" +#: libvips/foreign/cgifsave.c:928 +msgid "Maximum inter-palette error" msgstr "" -#: ../libvips/convolution/conva.c:1293 ../libvips/convolution/compass.c:179 -#: ../libvips/convolution/convasep.c:902 ../libvips/convolution/convsep.c:135 -#: ../libvips/convolution/conv.c:144 -msgid "Use this many layers in approximation" +#: libvips/foreign/cgifsave.c:929 +msgid "Maximum inter-palette error for palette reusage" msgstr "" -#: ../libvips/convolution/conva.c:1299 ../libvips/convolution/compass.c:185 -#: ../libvips/convolution/convsep.c:141 ../libvips/convolution/conv.c:150 -msgid "Cluster" +#: libvips/foreign/cgifsave.c:935 +msgid "Interlaced" msgstr "" -#: ../libvips/convolution/conva.c:1300 ../libvips/convolution/compass.c:186 -#: ../libvips/convolution/convsep.c:142 ../libvips/convolution/conv.c:151 -msgid "Cluster lines closer than this in approximation" +#: libvips/foreign/cgifsave.c:936 +msgid "Generate an interlaced (progressive) GIF" msgstr "" -#: ../libvips/convolution/fastcor.c:215 -msgid "fast correlation" +#: libvips/foreign/cgifsave.c:945 +msgid "Reoptimise palettes" msgstr "" -#: ../libvips/convolution/convi.c:1012 -msgid "int convolution operation" +#: libvips/foreign/cgifsave.c:946 +msgid "Reoptimise colour palettes" msgstr "" -#: ../libvips/convolution/compass.c:146 -msgid "convolve with rotating mask" +#: libvips/foreign/cgifsave.c:952 +msgid "Keep duplicate frames" msgstr "" -#: ../libvips/convolution/compass.c:150 -msgid "Times" +#: libvips/foreign/cgifsave.c:953 +msgid "Keep duplicate frames in the output instead of combining them" msgstr "" -#: ../libvips/convolution/compass.c:151 -msgid "Rotate and convolve this many times" +#: libvips/foreign/cgifsave.c:1010 libvips/foreign/csvsave.c:325 +#: libvips/foreign/dzsave.c:2537 libvips/foreign/heifsave.c:1020 +#: libvips/foreign/jp2ksave.c:1182 libvips/foreign/jpegsave.c:292 +#: libvips/foreign/jxlsave.c:1016 libvips/foreign/matrixsave.c:281 +#: libvips/foreign/pngsave.c:326 libvips/foreign/ppmsave.c:648 +#: libvips/foreign/radsave.c:207 libvips/foreign/rawsave.c:252 +#: libvips/foreign/spngsave.c:805 libvips/foreign/tiffsave.c:474 +#: libvips/foreign/vipssave.c:253 libvips/foreign/webpsave.c:987 +#: libvips/iofuncs/target.c:283 +msgid "Target" msgstr "" -#: ../libvips/convolution/compass.c:158 -msgid "Rotate mask by this much between convolutions" +#: libvips/foreign/cgifsave.c:1011 libvips/foreign/csvsave.c:326 +#: libvips/foreign/dzsave.c:2538 libvips/foreign/heifsave.c:1021 +#: libvips/foreign/jp2ksave.c:1183 libvips/foreign/jpegsave.c:293 +#: libvips/foreign/jxlsave.c:1017 libvips/foreign/matrixsave.c:282 +#: libvips/foreign/pngsave.c:327 libvips/foreign/ppmsave.c:649 +#: libvips/foreign/radsave.c:208 libvips/foreign/rawsave.c:253 +#: libvips/foreign/spngsave.c:806 libvips/foreign/tiffsave.c:475 +#: libvips/foreign/vipssave.c:254 libvips/foreign/webpsave.c:988 +msgid "Target to save to" msgstr "" -#: ../libvips/convolution/compass.c:164 -msgid "Combine" +#: libvips/foreign/cgifsave.c:1059 libvips/foreign/csvsave.c:275 +#: libvips/foreign/dzsave.c:2598 libvips/foreign/fitssave.c:144 +#: libvips/foreign/heifsave.c:898 libvips/foreign/jp2ksave.c:1064 +#: libvips/foreign/jpegsave.c:362 libvips/foreign/jxlsave.c:898 +#: libvips/foreign/matrixsave.c:229 libvips/foreign/niftisave.c:442 +#: libvips/foreign/pngsave.c:379 libvips/foreign/ppmsave.c:593 +#: libvips/foreign/radsave.c:155 libvips/foreign/rawsave.c:197 +#: libvips/foreign/spngsave.c:859 libvips/foreign/tiffsave.c:528 +#: libvips/foreign/vips2magick.c:579 libvips/foreign/vipssave.c:198 +#: libvips/foreign/webpsave.c:1039 +msgid "Filename to save to" msgstr "" -#: ../libvips/convolution/compass.c:165 -msgid "Combine convolution results like this" +#: libvips/foreign/cgifsave.c:1117 libvips/foreign/dzsave.c:2656 +#: libvips/foreign/heifload.c:1340 libvips/foreign/heifsave.c:962 +#: libvips/foreign/jp2kload.c:1385 libvips/foreign/jp2ksave.c:1126 +#: libvips/foreign/jpegload.c:430 libvips/foreign/jpegsave.c:439 +#: libvips/foreign/jxlload.c:1293 libvips/foreign/jxlsave.c:960 +#: libvips/foreign/magick6load.c:313 libvips/foreign/magick7load.c:932 +#: libvips/foreign/nsgifload.c:843 libvips/foreign/pdfiumload.c:872 +#: libvips/foreign/pngload.c:394 libvips/foreign/pngsave.c:437 +#: libvips/foreign/popplerload.c:749 libvips/foreign/radload.c:356 +#: libvips/foreign/radsave.c:273 libvips/foreign/rawsave.c:314 +#: libvips/foreign/spngload.c:911 libvips/foreign/spngsave.c:918 +#: libvips/foreign/svgload.c:997 libvips/foreign/tiffload.c:460 +#: libvips/foreign/tiffsave.c:588 libvips/foreign/vips2magick.c:650 +#: libvips/foreign/webpload.c:424 libvips/foreign/webpsave.c:1096 +#: libvips/resample/thumbnail.c:1445 +msgid "Buffer" msgstr "" -#: ../libvips/convolution/compass.c:171 ../libvips/convolution/gaussblur.c:145 -#: ../libvips/convolution/convsep.c:127 ../libvips/convolution/conv.c:136 -#: ../libvips/create/logmat.c:229 ../libvips/create/gaussmat.c:212 -msgid "Precision" +#: libvips/foreign/cgifsave.c:1118 libvips/foreign/dzsave.c:2657 +#: libvips/foreign/heifsave.c:963 libvips/foreign/jp2ksave.c:1127 +#: libvips/foreign/jpegsave.c:440 libvips/foreign/jxlsave.c:961 +#: libvips/foreign/pngsave.c:438 libvips/foreign/radsave.c:274 +#: libvips/foreign/rawsave.c:315 libvips/foreign/spngsave.c:919 +#: libvips/foreign/tiffsave.c:589 libvips/foreign/vips2magick.c:651 +#: libvips/foreign/webpsave.c:1097 +msgid "Buffer to save to" msgstr "" -#: ../libvips/convolution/compass.c:172 ../libvips/convolution/gaussblur.c:146 -#: ../libvips/convolution/convsep.c:128 ../libvips/convolution/conv.c:137 -msgid "Convolve with this precision" +#: libvips/foreign/csvload.c:301 +#, c-format +msgid "bad number, line %d, column %d" msgstr "" -#: ../libvips/convolution/convolution.c:120 -msgid "convolution operations" +#: libvips/foreign/csvload.c:341 libvips/foreign/csvload.c:402 +#: libvips/foreign/csvload.c:434 +msgid "unexpected end of file" msgstr "" -#: ../libvips/convolution/convolution.c:141 -#: ../libvips/convolution/correlation.c:157 ../libvips/draw/draw_mask.c:323 -#: ../libvips/morphology/morph.c:149 ../libvips/morphology/labelregions.c:125 -msgid "Mask" +#: libvips/foreign/csvload.c:440 +#, c-format +msgid "line %d has only %d columns" msgstr "" -#: ../libvips/convolution/convolution.c:142 ../libvips/morphology/morph.c:150 -msgid "Input matrix image" +#: libvips/foreign/csvload.c:479 +msgid "load csv" msgstr "" -#: ../libvips/convolution/convf.c:365 -msgid "float convolution operation" +#: libvips/foreign/csvload.c:492 +msgid "Skip" msgstr "" -#: ../libvips/convolution/gaussblur.c:113 -msgid "gaussian blur" +#: libvips/foreign/csvload.c:493 +msgid "Skip this many lines at the start of the file" msgstr "" -#: ../libvips/convolution/gaussblur.c:131 ../libvips/convolution/sharpen.c:325 -#: ../libvips/create/gaussmat.c:184 ../libvips/create/gaussnoise.c:193 -msgid "Sigma" +#: libvips/foreign/csvload.c:499 +msgid "Lines" msgstr "" -#: ../libvips/convolution/gaussblur.c:132 ../libvips/convolution/sharpen.c:326 -#: ../libvips/create/gaussmat.c:185 -msgid "Sigma of Gaussian" +#: libvips/foreign/csvload.c:500 +msgid "Read this many lines from the file" msgstr "" -#: ../libvips/convolution/gaussblur.c:138 ../libvips/create/gaussmat.c:191 -msgid "Minimum amplitude" +#: libvips/foreign/csvload.c:506 +msgid "Whitespace" msgstr "" -#: ../libvips/convolution/gaussblur.c:139 ../libvips/create/gaussmat.c:192 -msgid "Minimum amplitude of Gaussian" +#: libvips/foreign/csvload.c:507 +msgid "Set of whitespace characters" msgstr "" -#: ../libvips/convolution/convasep.c:897 -msgid "approximate separable integer convolution" +#: libvips/foreign/csvload.c:513 libvips/foreign/csvsave.c:223 +msgid "Separator" msgstr "" -#: ../libvips/convolution/convsep.c:123 -msgid "seperable convolution operation" +#: libvips/foreign/csvload.c:514 +msgid "Set of separator characters" msgstr "" -#: ../libvips/convolution/sharpen.c:307 -msgid "unsharp masking for print" +#: libvips/foreign/csvload.c:661 libvips/foreign/fitsload.c:338 +#: libvips/foreign/heifload.c:1414 libvips/foreign/jp2kload.c:1448 +#: libvips/foreign/jpegload.c:278 libvips/foreign/jxlload.c:1357 +#: libvips/foreign/matrixload.c:462 libvips/foreign/niftiload.c:792 +#: libvips/foreign/nsgifload.c:909 libvips/foreign/openslideload.c:1230 +#: libvips/foreign/pdfiumload.c:932 libvips/foreign/pngload.c:242 +#: libvips/foreign/popplerload.c:809 libvips/foreign/ppmload.c:890 +#: libvips/foreign/radload.c:205 libvips/foreign/spngload.c:757 +#: libvips/foreign/svgload.c:836 libvips/foreign/tiffload.c:302 +#: libvips/foreign/vipsload.c:312 libvips/foreign/webpload.c:266 +#: libvips/resample/thumbnail.c:1658 +msgid "Source" msgstr "" -#: ../libvips/convolution/sharpen.c:332 ../libvips/draw/draw_line.c:284 -msgid "x1" +#: libvips/foreign/csvload.c:662 libvips/foreign/fitsload.c:339 +#: libvips/foreign/heifload.c:1415 libvips/foreign/jp2kload.c:1449 +#: libvips/foreign/jpegload.c:279 libvips/foreign/jxlload.c:1358 +#: libvips/foreign/matrixload.c:463 libvips/foreign/niftiload.c:793 +#: libvips/foreign/nsgifload.c:910 libvips/foreign/openslideload.c:1231 +#: libvips/foreign/pdfiumload.c:933 libvips/foreign/pngload.c:243 +#: libvips/foreign/popplerload.c:810 libvips/foreign/ppmload.c:891 +#: libvips/foreign/radload.c:206 libvips/foreign/spngload.c:758 +#: libvips/foreign/svgload.c:837 libvips/foreign/tiffload.c:303 +#: libvips/foreign/vipsload.c:313 libvips/foreign/webpload.c:267 +#: libvips/iofuncs/sbuf.c:89 libvips/resample/thumbnail.c:1659 +msgid "Source to load from" msgstr "" -#: ../libvips/convolution/sharpen.c:333 -msgid "Flat/jaggy threshold" +#: libvips/foreign/csvsave.c:215 +msgid "save image to csv" msgstr "" -#: ../libvips/convolution/sharpen.c:339 ../libvips/draw/draw_line.c:305 -msgid "y2" +#: libvips/foreign/csvsave.c:224 +msgid "Separator characters" msgstr "" -#: ../libvips/convolution/sharpen.c:340 -msgid "Maximum brightening" +#: libvips/foreign/dzsave.c:2008 +msgid "overlap too large" msgstr "" -#: ../libvips/convolution/sharpen.c:346 -msgid "y3" +#: libvips/foreign/dzsave.c:2319 +msgid "save image to deep zoom format" msgstr "" -#: ../libvips/convolution/sharpen.c:347 -msgid "Maximum darkening" +#: libvips/foreign/dzsave.c:2329 libvips/foreign/dzsave.c:2330 +msgid "Image name" msgstr "" -#: ../libvips/convolution/sharpen.c:353 -msgid "m1" +#: libvips/foreign/dzsave.c:2336 +msgid "Layout" msgstr "" -#: ../libvips/convolution/sharpen.c:354 -msgid "Slope for flat areas" +#: libvips/foreign/dzsave.c:2337 +msgid "Directory layout" msgstr "" -#: ../libvips/convolution/sharpen.c:360 -msgid "m2" +#: libvips/foreign/dzsave.c:2343 +msgid "Suffix" msgstr "" -#: ../libvips/convolution/sharpen.c:361 -msgid "Slope for jaggy areas" +#: libvips/foreign/dzsave.c:2344 +msgid "Filename suffix for tiles" msgstr "" -#: ../libvips/convolution/sharpen.c:369 ../libvips/create/logmat.c:201 -#: ../libvips/draw/draw_circle.c:249 -msgid "Radius" +#: libvips/foreign/dzsave.c:2350 +msgid "Overlap" msgstr "" -#: ../libvips/convolution/sharpen.c:370 -msgid "radius of Gaussian" +#: libvips/foreign/dzsave.c:2351 +msgid "Tile overlap in pixels" msgstr "" -#: ../libvips/convolution/conv.c:132 -msgid "convolution operation" +#: libvips/foreign/dzsave.c:2357 +msgid "Tile size" msgstr "" -#: ../libvips/convolution/correlation.c:145 -msgid "correlation operation" +#: libvips/foreign/dzsave.c:2358 +msgid "Tile size in pixels" msgstr "" -#: ../libvips/convolution/correlation.c:158 -msgid "Input reference image" +#: libvips/foreign/dzsave.c:2365 libvips/foreign/tiffsave.c:379 +msgid "Pyramid depth" msgstr "" -#: ../libvips/create/sines.c:121 -msgid "make a 2D sine wave" +#: libvips/foreign/dzsave.c:2371 +msgid "Center" msgstr "" -#: ../libvips/create/sines.c:127 -msgid "hfreq" +#: libvips/foreign/dzsave.c:2372 +msgid "Center image in tile" msgstr "" -#: ../libvips/create/sines.c:128 -msgid "Horizontal spatial frequency" +#: libvips/foreign/dzsave.c:2379 +msgid "Rotate image during save" msgstr "" -#: ../libvips/create/sines.c:134 -msgid "vfreq" +#: libvips/foreign/dzsave.c:2385 +msgid "Container" msgstr "" -#: ../libvips/create/sines.c:135 -msgid "Vertical spatial frequency" +#: libvips/foreign/dzsave.c:2386 +msgid "Pyramid container type" msgstr "" -#: ../libvips/create/grey.c:89 -msgid "make a grey ramp image" +#: libvips/foreign/dzsave.c:2392 libvips/foreign/heifsave.c:795 +#: libvips/foreign/pngsave.c:211 libvips/foreign/spngsave.c:689 +#: libvips/foreign/tiffsave.c:257 +msgid "Compression" msgstr "" -#: ../libvips/create/mask_ideal.c:79 -msgid "make an ideal filter" +#: libvips/foreign/dzsave.c:2393 +msgid "ZIP deflate compression level" msgstr "" -#: ../libvips/create/mask_ideal.c:84 ../libvips/create/mask_ideal.c:85 -#: ../libvips/create/mask_gaussian.c:86 ../libvips/create/mask_gaussian.c:87 -#: ../libvips/create/mask_butterworth.c:95 -#: ../libvips/create/mask_butterworth.c:96 -msgid "Frequency cutoff" +#: libvips/foreign/dzsave.c:2399 libvips/foreign/tiffsave.c:357 +msgid "Region shrink" msgstr "" -#: ../libvips/create/create.c:97 -msgid "create operations" +#: libvips/foreign/dzsave.c:2400 libvips/foreign/tiffsave.c:358 +msgid "Method to shrink regions" msgstr "" -#: ../libvips/create/mask_gaussian.c:81 -#: ../libvips/create/mask_gaussian_band.c:102 -msgid "make a gaussian filter" +#: libvips/foreign/dzsave.c:2406 +msgid "Skip blanks" msgstr "" -#: ../libvips/create/mask_gaussian.c:93 ../libvips/create/mask_gaussian.c:94 -#: ../libvips/create/mask_butterworth_band.c:141 -#: ../libvips/create/mask_butterworth_band.c:142 -#: ../libvips/create/mask_butterworth.c:102 -#: ../libvips/create/mask_butterworth.c:103 -#: ../libvips/create/mask_gaussian_band.c:128 -#: ../libvips/create/mask_gaussian_band.c:129 -msgid "Amplitude cutoff" +#: libvips/foreign/dzsave.c:2407 +msgid "Skip tiles which are nearly equal to the background" msgstr "" -#: ../libvips/create/xyz.c:139 -msgid "lower dimensions not set" +#: libvips/foreign/dzsave.c:2413 +msgid "id" msgstr "" -#: ../libvips/create/xyz.c:156 -msgid "image too large" +#: libvips/foreign/dzsave.c:2414 +msgid "Resource ID" msgstr "" -#: ../libvips/create/xyz.c:189 -msgid "make an image where pixel values are coordinates" +#: libvips/foreign/dzsave.c:2420 libvips/foreign/heifsave.c:774 +#: libvips/foreign/jp2ksave.c:1000 libvips/foreign/jpegsave.c:164 +#: libvips/foreign/jxlsave.c:838 libvips/foreign/tiffsave.c:265 +#: libvips/foreign/webpsave.c:826 +msgid "Q" msgstr "" -#: ../libvips/create/xyz.c:207 -msgid "csize" +#: libvips/foreign/dzsave.c:2421 libvips/foreign/heifsave.c:775 +#: libvips/foreign/jp2ksave.c:1001 libvips/foreign/jpegsave.c:165 +#: libvips/foreign/tiffsave.c:266 libvips/foreign/webpsave.c:827 +msgid "Q factor" msgstr "" -#: ../libvips/create/xyz.c:208 -msgid "Size of third dimension" +#: libvips/foreign/dzsave.c:2430 +msgid "No strip" msgstr "" -#: ../libvips/create/xyz.c:214 -msgid "dsize" +#: libvips/foreign/dzsave.c:2431 +msgid "Don't strip tile metadata" msgstr "" -#: ../libvips/create/xyz.c:215 -msgid "Size of fourth dimension" +#: libvips/foreign/dzsave.c:2437 +msgid "Base name" msgstr "" -#: ../libvips/create/xyz.c:221 -msgid "esize" +#: libvips/foreign/dzsave.c:2438 +msgid "Base name to save to" msgstr "" -#: ../libvips/create/xyz.c:222 -msgid "Size of fifth dimension" +#: libvips/foreign/dzsave.c:2444 +msgid "Directory name" msgstr "" -#: ../libvips/create/invertlut.c:124 -msgid "bad input matrix" +#: libvips/foreign/dzsave.c:2445 +msgid "Directory name to save to" msgstr "" -#: ../libvips/create/invertlut.c:129 -msgid "bad size" +#: libvips/foreign/dzsave.c:2465 libvips/foreign/tiffsave.c:350 +msgid "Properties" msgstr "" -#: ../libvips/create/invertlut.c:149 -#, c-format -msgid "element (%d, %d) is %g, outside range [0,1]" +#: libvips/foreign/dzsave.c:2466 +msgid "Write a properties file to the output directory" msgstr "" -#: ../libvips/create/invertlut.c:285 -msgid "build an inverted look-up table" +#: libvips/foreign/dzsave.c:2533 +msgid "save image to deepzoom target" msgstr "" -#: ../libvips/create/invertlut.c:290 ../libvips/create/buildlut.c:262 -msgid "Matrix of XY coordinates" +#: libvips/foreign/dzsave.c:2593 +msgid "save image to deepzoom file" msgstr "" -#: ../libvips/create/invertlut.c:296 -msgid "LUT size to generate" +#: libvips/foreign/dzsave.c:2652 +msgid "save image to dz buffer" msgstr "" -#: ../libvips/create/mask_butterworth_ring.c:101 -msgid "make a butterworth ring filter" +#: libvips/foreign/exif.c:199 +msgid "exif too small" msgstr "" -#: ../libvips/create/mask_butterworth_ring.c:106 -#: ../libvips/create/mask_butterworth_ring.c:107 -#: ../libvips/create/mask_gaussian_ring.c:101 -#: ../libvips/create/mask_gaussian_ring.c:102 -#: ../libvips/create/mask_ideal_ring.c:98 -#: ../libvips/create/mask_ideal_ring.c:99 -msgid "Ringwidth" +#: libvips/foreign/exif.c:203 +msgid "exif too large" msgstr "" -#: ../libvips/create/logmat.c:147 ../libvips/create/gaussmat.c:133 -msgid "mask too large" +#: libvips/foreign/exif.c:208 +msgid "unable to init exif" msgstr "" -#: ../libvips/create/logmat.c:197 -msgid "make a laplacian of gaussian image" +#: libvips/foreign/exif.c:1260 libvips/foreign/exif.c:1270 +#: libvips/foreign/exif.c:1279 libvips/foreign/exif.c:1319 +#, c-format +msgid "bad exif meta \"%s\"" msgstr "" -#: ../libvips/create/logmat.c:202 -msgid "Radius of Logmatian" +#: libvips/foreign/exif.c:1496 +msgid "error saving EXIF" msgstr "" -#: ../libvips/create/logmat.c:209 -msgid "Minimum amplitude of Logmatian" +#: libvips/foreign/fits.c:184 libvips/foreign/matlab.c:113 +#: libvips/iofuncs/vips.c:159 libvips/mosaicing/global_balance.c:1240 +#: libvips/mosaicing/global_balance.c:1690 +#, c-format +msgid "unable to open \"%s\"" msgstr "" -#: ../libvips/create/logmat.c:215 ../libvips/create/gaussmat.c:198 -msgid "Separable" +#: libvips/foreign/fits.c:237 +msgid "no HDU found with naxes > 0" msgstr "" -#: ../libvips/create/logmat.c:216 -msgid "Generate separable Logmatian" +#: libvips/foreign/fits.c:275 +msgid "dimensions above 3 must be size 1" msgstr "" -#: ../libvips/create/logmat.c:222 ../libvips/create/gaussmat.c:205 -msgid "Integer" +#: libvips/foreign/fits.c:290 +#, c-format +msgid "bad number of axis %d" msgstr "" -#: ../libvips/create/logmat.c:223 -msgid "Generate integer Logmatian" +#: libvips/foreign/fits.c:301 +#, c-format +msgid "unsupported bitpix %d\n" msgstr "" -#: ../libvips/create/logmat.c:230 ../libvips/create/gaussmat.c:213 -msgid "Generate with this precision" +#: libvips/foreign/fits.c:586 libvips/iofuncs/vips.c:222 +#, c-format +msgid "unable to write to \"%s\"" msgstr "" -#: ../libvips/create/gaussmat.c:180 -msgid "make a gaussian image" +#: libvips/foreign/fits.c:729 +#, c-format +msgid "unsupported BandFmt %d\n" msgstr "" -#: ../libvips/create/gaussmat.c:199 -msgid "Generate separable Gaussian" +#: libvips/foreign/fitsload.c:101 libvips/foreign/niftiload.c:130 +#: libvips/foreign/openslideload.c:916 +msgid "no filename available" msgstr "" -#: ../libvips/create/gaussmat.c:206 -msgid "Generate integer Gaussian" +#: libvips/foreign/fitsload.c:183 +msgid "FITS loader base class" msgstr "" -#: ../libvips/create/worley.c:306 -msgid "make a worley noise image" +#: libvips/foreign/fitsload.c:251 +msgid "load a FITS image" msgstr "" -#: ../libvips/create/worley.c:324 ../libvips/create/perlin.c:311 -msgid "Cell size" +#: libvips/foreign/fitsload.c:329 +msgid "load FITS from a source" msgstr "" -#: ../libvips/create/worley.c:325 -msgid "Size of Worley cells" +#: libvips/foreign/fitssave.c:129 +msgid "save image to fits file" msgstr "" -#: ../libvips/create/mask_gaussian_ring.c:96 -msgid "make a gaussian ring filter" +#: libvips/foreign/foreign.c:408 +msgid "load and save image files" msgstr "" -#: ../libvips/create/gaussnoise.c:164 -msgid "make a gaussnoise image" +#: libvips/foreign/foreign.c:607 +#, c-format +msgid "file \"%s\" does not exist" msgstr "" -#: ../libvips/create/gaussnoise.c:186 ../libvips/histogram/stdif.c:329 -msgid "Mean" +#: libvips/foreign/foreign.c:612 +#, c-format +msgid "\"%s\" is a directory" msgstr "" -#: ../libvips/create/gaussnoise.c:187 -msgid "Mean of pixels in generated image" +#: libvips/foreign/foreign.c:621 libvips/foreign/foreign.c:2003 +#, c-format +msgid "\"%s\" is not a known file format" msgstr "" -#: ../libvips/create/gaussnoise.c:194 -msgid "Standard deviation of pixels in generated image" +#: libvips/foreign/foreign.c:708 +msgid "buffer is not in a known format" msgstr "" -#: ../libvips/create/zone.c:90 -msgid "make a zone plate" +#: libvips/foreign/foreign.c:769 +msgid "source is not in a known format" msgstr "" -#: ../libvips/create/tonelut.c:221 ../libvips/create/buildlut.c:257 -msgid "build a look-up table" +#: libvips/foreign/foreign.c:979 +msgid "images do not match between header and load" msgstr "" -#: ../libvips/create/tonelut.c:225 -msgid "In-max" +#: libvips/foreign/foreign.c:1210 +msgid "loaders" msgstr "" -#: ../libvips/create/tonelut.c:226 -msgid "Size of LUT to build" +#: libvips/foreign/foreign.c:1221 +msgid "Flags" msgstr "" -#: ../libvips/create/tonelut.c:232 -msgid "Out-max" +#: libvips/foreign/foreign.c:1222 +msgid "Flags for this file" msgstr "" -#: ../libvips/create/tonelut.c:233 -msgid "Maximum value in output LUT" +#: libvips/foreign/foreign.c:1228 libvips/iofuncs/target.c:294 +msgid "Memory" msgstr "" -#: ../libvips/create/tonelut.c:239 -msgid "Black point" +#: libvips/foreign/foreign.c:1229 +msgid "Force open via memory" msgstr "" -#: ../libvips/create/tonelut.c:240 -msgid "Lowest value in output" +#: libvips/foreign/foreign.c:1236 +msgid "Required access pattern for this file" msgstr "" -#: ../libvips/create/tonelut.c:246 -msgid "White point" +#: libvips/foreign/foreign.c:1242 libvips/resample/thumbnail.c:1037 +msgid "Fail on" msgstr "" -#: ../libvips/create/tonelut.c:247 -msgid "Highest value in output" +#: libvips/foreign/foreign.c:1243 libvips/resample/thumbnail.c:1038 +msgid "Error level to fail on" msgstr "" -#: ../libvips/create/tonelut.c:253 -msgid "Shadow point" +#: libvips/foreign/foreign.c:1249 +msgid "Revalidate" msgstr "" -#: ../libvips/create/tonelut.c:254 -msgid "Position of shadow" +#: libvips/foreign/foreign.c:1250 +msgid "Don't use a cached result for this operation" msgstr "" -#: ../libvips/create/tonelut.c:260 -msgid "Mid-tone point" +#: libvips/foreign/foreign.c:1256 +msgid "Sequential" msgstr "" -#: ../libvips/create/tonelut.c:261 -msgid "Position of mid-tones" +#: libvips/foreign/foreign.c:1257 +msgid "Sequential read only" msgstr "" -#: ../libvips/create/tonelut.c:267 -msgid "Highlight point" +#: libvips/foreign/foreign.c:1263 +msgid "Fail" msgstr "" -#: ../libvips/create/tonelut.c:268 -msgid "Position of highlights" +#: libvips/foreign/foreign.c:1264 +msgid "Fail on first warning" msgstr "" -#: ../libvips/create/tonelut.c:274 -msgid "Shadow adjust" +#: libvips/foreign/foreign.c:1270 +msgid "Disc" msgstr "" -#: ../libvips/create/tonelut.c:275 -msgid "Adjust shadows by this much" +#: libvips/foreign/foreign.c:1271 +msgid "Open to disc" msgstr "" -#: ../libvips/create/tonelut.c:281 -msgid "Mid-tone adjust" +#: libvips/foreign/foreign.c:1871 +msgid "savers" msgstr "" -#: ../libvips/create/tonelut.c:282 -msgid "Adjust mid-tones by this much" +#: libvips/foreign/foreign.c:1895 +msgid "Image to save" msgstr "" -#: ../libvips/create/tonelut.c:288 -msgid "Highlight adjust" +#: libvips/foreign/foreign.c:1900 +msgid "Keep" msgstr "" -#: ../libvips/create/tonelut.c:289 -msgid "Adjust highlights by this much" +#: libvips/foreign/foreign.c:1901 +msgid "Which metadata to retain" msgstr "" -#: ../libvips/create/perlin.c:293 -msgid "make a perlin noise image" +#: libvips/foreign/foreign.c:1916 +msgid "Set page height for multipage save" msgstr "" -#: ../libvips/create/perlin.c:312 -msgid "Size of Perlin cells" +#: libvips/foreign/foreign.c:1923 +msgid "Filename of ICC profile to embed" msgstr "" -#: ../libvips/create/perlin.c:318 ../libvips/create/point.c:157 -msgid "Uchar" +#: libvips/foreign/foreign.c:1929 +msgid "Strip" msgstr "" -#: ../libvips/create/perlin.c:319 ../libvips/create/point.c:158 -msgid "Output an unsigned char image" +#: libvips/foreign/foreign.c:1930 +msgid "Strip all metadata from image" msgstr "" -#: ../libvips/create/point.c:134 -msgid "make a point image" +#: libvips/foreign/foreign.c:2158 +#, c-format +msgid "\"%s\" is not a known target format" msgstr "" -#: ../libvips/create/mask.c:111 -msgid "base class for frequency filters" +#: libvips/foreign/foreign.c:2216 +#, c-format +msgid "\"%s\" is not a known buffer format" msgstr "" -#: ../libvips/create/mask.c:119 -msgid "Optical" +#: libvips/foreign/heifload.c:820 libvips/foreign/jxlload.c:753 +#: libvips/foreign/nsgifload.c:448 libvips/foreign/webp2vips.c:501 +msgid "bad page number" msgstr "" -#: ../libvips/create/mask.c:120 -msgid "Rotate quadrants to optical space" +#: libvips/foreign/heifload.c:872 +msgid "undefined bits per pixel" msgstr "" -#: ../libvips/create/mask.c:126 -msgid "Reject" +#: libvips/foreign/heifload.c:884 +msgid "not all pages are the same size" msgstr "" -#: ../libvips/create/mask.c:127 -msgid "Invert the sense of the filter" +#: libvips/foreign/heifload.c:983 +msgid "bad image dimensions on decode" msgstr "" -#: ../libvips/create/mask.c:133 -msgid "Nodc" +#: libvips/foreign/heifload.c:990 +msgid "unable to get image data" msgstr "" -#: ../libvips/create/mask.c:134 -msgid "Remove DC component" +#: libvips/foreign/heifload.c:1075 +msgid "load a HEIF image" msgstr "" -#: ../libvips/create/mask_butterworth_band.c:108 -msgid "make a butterworth_band filter" +#: libvips/foreign/heifload.c:1083 libvips/foreign/jp2kload.c:1229 +#: libvips/foreign/jxlload.c:1132 libvips/foreign/magick6load.c:141 +#: libvips/foreign/magick7load.c:382 libvips/foreign/nsgifload.c:620 +#: libvips/foreign/pdfiumload.c:695 libvips/foreign/popplerload.c:545 +#: libvips/foreign/tiffload.c:196 libvips/foreign/webpload.c:178 +msgid "Page" msgstr "" -#: ../libvips/create/mask_butterworth_band.c:113 -#: ../libvips/create/mask_butterworth.c:88 -msgid "Order" +#: libvips/foreign/heifload.c:1084 libvips/foreign/jxlload.c:1133 +#: libvips/foreign/magick6load.c:142 libvips/foreign/magick7load.c:383 +#: libvips/foreign/nsgifload.c:621 libvips/foreign/pdfiumload.c:696 +#: libvips/foreign/popplerload.c:546 libvips/foreign/tiffload.c:197 +#: libvips/foreign/webpload.c:179 +msgid "First page to load" msgstr "" -#: ../libvips/create/mask_butterworth_band.c:114 -#: ../libvips/create/mask_butterworth.c:89 -msgid "Filter order" +#: libvips/foreign/heifload.c:1091 libvips/foreign/jxlload.c:1140 +#: libvips/foreign/magick6load.c:149 libvips/foreign/magick7load.c:390 +#: libvips/foreign/nsgifload.c:628 libvips/foreign/pdfiumload.c:703 +#: libvips/foreign/popplerload.c:553 libvips/foreign/tiffload.c:204 +#: libvips/foreign/webpload.c:186 +msgid "Number of pages to load, -1 for all" msgstr "" -#: ../libvips/create/mask_butterworth_band.c:120 -#: ../libvips/create/mask_butterworth_band.c:121 -#: ../libvips/create/mask_gaussian_band.c:107 -#: ../libvips/create/mask_gaussian_band.c:108 -#: ../libvips/create/mask_ideal_band.c:98 -#: ../libvips/create/mask_ideal_band.c:99 -msgid "Frequency cutoff x" +#: libvips/foreign/heifload.c:1097 +msgid "Thumbnail" msgstr "" -#: ../libvips/create/mask_butterworth_band.c:127 -#: ../libvips/create/mask_butterworth_band.c:128 -#: ../libvips/create/mask_gaussian_band.c:114 -#: ../libvips/create/mask_gaussian_band.c:115 -#: ../libvips/create/mask_ideal_band.c:105 -#: ../libvips/create/mask_ideal_band.c:106 -msgid "Frequency cutoff y" +#: libvips/foreign/heifload.c:1098 +msgid "Fetch thumbnail image" msgstr "" -#: ../libvips/create/mask_butterworth_band.c:134 -#: ../libvips/create/mask_gaussian_band.c:121 -#: ../libvips/create/mask_ideal_band.c:112 -msgid "radius" +#: libvips/foreign/heifload.c:1104 libvips/foreign/jpegload.c:198 +#: libvips/foreign/tiffload.c:210 +msgid "Autorotate" msgstr "" -#: ../libvips/create/mask_butterworth_band.c:135 -#: ../libvips/create/mask_gaussian_band.c:122 -#: ../libvips/create/mask_ideal_band.c:113 -msgid "radius of circle" +#: libvips/foreign/heifload.c:1105 libvips/foreign/jpegload.c:199 +msgid "Rotate image using exif orientation" msgstr "" -#: ../libvips/create/mask_ideal_ring.c:93 -msgid "make an ideal ring filter" +#: libvips/foreign/heifload.c:1112 libvips/foreign/jpegload.c:206 +#: libvips/foreign/pngload.c:171 libvips/foreign/spngload.c:678 +#: libvips/foreign/svgload.c:732 libvips/foreign/tiffload.c:225 +msgid "Unlimited" msgstr "" -#: ../libvips/create/mask_butterworth.c:83 -msgid "make a butterworth filter" +#: libvips/foreign/heifload.c:1113 libvips/foreign/jpegload.c:207 +#: libvips/foreign/pngload.c:172 libvips/foreign/spngload.c:679 +#: libvips/foreign/tiffload.c:226 +msgid "Remove all denial of service limits" msgstr "" -#: ../libvips/create/fractsurf.c:98 -msgid "make a fractal surface" +#: libvips/foreign/heifload.c:1341 libvips/foreign/jp2kload.c:1386 +#: libvips/foreign/jpegload.c:431 libvips/foreign/jxlload.c:1294 +#: libvips/foreign/magick6load.c:314 libvips/foreign/magick7load.c:933 +#: libvips/foreign/nsgifload.c:844 libvips/foreign/pdfiumload.c:873 +#: libvips/foreign/pngload.c:395 libvips/foreign/popplerload.c:750 +#: libvips/foreign/radload.c:357 libvips/foreign/spngload.c:912 +#: libvips/foreign/svgload.c:998 libvips/foreign/tiffload.c:461 +#: libvips/foreign/webpload.c:425 libvips/resample/thumbnail.c:1446 +msgid "Buffer to load from" msgstr "" -#: ../libvips/create/fractsurf.c:116 ../libvips/create/fractsurf.c:117 -#: ../libvips/create/mask_fractal.c:93 ../libvips/create/mask_fractal.c:94 -msgid "Fractal dimension" -msgstr "" +#: libvips/foreign/heifsave.c:441 +#, fuzzy +msgid "unimplemented format conversion" +msgstr "unimplemented output colour space 0x%x" -#: ../libvips/create/identity.c:140 -msgid "make a 1D image where pixel values are indexes" +#: libvips/foreign/heifsave.c:550 +#, c-format +msgid "%d-bit colour depth not supported" msgstr "" -#: ../libvips/create/identity.c:145 -msgid "Number of bands in LUT" +#: libvips/foreign/heifsave.c:583 +#, fuzzy +msgid "Unsupported compression" +msgstr "unsupported colour type" + +#: libvips/foreign/heifsave.c:767 +msgid "save image in HEIF format" msgstr "" -#: ../libvips/create/identity.c:151 -msgid "Ushort" +#: libvips/foreign/heifsave.c:788 libvips/foreign/jp2ksave.c:985 +#: libvips/foreign/jxlsave.c:831 libvips/foreign/tiffsave.c:371 +#: libvips/foreign/webpsave.c:833 +msgid "Lossless" msgstr "" -#: ../libvips/create/identity.c:152 -msgid "Create a 16-bit LUT" +#: libvips/foreign/heifsave.c:789 libvips/foreign/jp2ksave.c:986 +#: libvips/foreign/jxlsave.c:832 libvips/foreign/webpsave.c:834 +msgid "Enable lossless compression" msgstr "" -#: ../libvips/create/identity.c:159 -msgid "Size of 16-bit LUT" +#: libvips/foreign/heifsave.c:796 +msgid "Compression format" msgstr "" -#: ../libvips/create/text.c:170 -msgid "invalid markup in text" +#: libvips/foreign/heifsave.c:804 libvips/foreign/heifsave.c:819 +msgid "CPU effort" msgstr "" -#: ../libvips/create/text.c:212 -msgid "no text to render" +#: libvips/foreign/heifsave.c:810 libvips/foreign/jp2ksave.c:992 +#: libvips/foreign/jpegsave.c:220 +msgid "Subsample mode" msgstr "" -#: ../libvips/create/text.c:279 -msgid "make a text image" +#: libvips/foreign/heifsave.c:811 libvips/foreign/jp2ksave.c:993 +#: libvips/foreign/jpegsave.c:221 +msgid "Select chroma subsample operation mode" msgstr "" -#: ../libvips/create/text.c:283 -msgid "Text" +#: libvips/foreign/heifsave.c:818 +msgid "Speed" msgstr "" -#: ../libvips/create/text.c:284 -msgid "Text to render" +#: libvips/foreign/heifsave.c:825 +msgid "Encoder" msgstr "" -#: ../libvips/create/text.c:290 -msgid "Font" +#: libvips/foreign/heifsave.c:826 +msgid "Select encoder to use" msgstr "" -#: ../libvips/create/text.c:291 -msgid "Font to render with" +#: libvips/foreign/heifsave.c:1047 +msgid "save image in AVIF format" msgstr "" -#: ../libvips/create/text.c:298 -msgid "Maximum image width in pixels" +#: libvips/foreign/jp2kload.c:235 +msgid "unable to create jp2k stream" msgstr "" -#: ../libvips/create/text.c:305 -msgid "Align on the low, centre or high edge" +#: libvips/foreign/jp2kload.c:548 +#, fuzzy, c-format +msgid "unsupported colourspace %d" +msgstr "unsupported colourspace %d" + +#: libvips/foreign/jp2kload.c:597 +msgid "too many image bands" msgstr "" -#: ../libvips/create/text.c:311 ../libvips/foreign/pdfload.c:482 -#: ../libvips/foreign/svgload.c:283 -msgid "DPI" +#: libvips/foreign/jp2kload.c:601 +msgid "no image components" msgstr "" -#: ../libvips/create/text.c:312 -msgid "DPI to render at" +#: libvips/foreign/jp2kload.c:618 +msgid "components differ in geometry" msgstr "" -#: ../libvips/create/text.c:318 -msgid "Spacing" +#: libvips/foreign/jp2kload.c:625 +msgid "components differ in precision" msgstr "" -#: ../libvips/create/text.c:319 -msgid "Line spacing" +#: libvips/foreign/jp2kload.c:996 libvips/foreign/jp2kload.c:1093 +msgid "decoded image does not match container" msgstr "" -#: ../libvips/create/mask_fractal.c:88 -msgid "make fractal filter" +#: libvips/foreign/jp2kload.c:1217 +msgid "load JPEG2000 image" msgstr "" -#: ../libvips/create/eye.c:98 -msgid "make an image showing the eye's spatial response" +#: libvips/foreign/jp2kload.c:1230 +msgid "Load this page from the image" msgstr "" -#: ../libvips/create/eye.c:104 -msgid "Maximum spatial frequency" +#: libvips/foreign/jp2kload.c:1600 libvips/foreign/jp2ksave.c:1434 +msgid "libvips built without JPEG2000 support" msgstr "" -#: ../libvips/create/black.c:125 -msgid "make a black image" +#: libvips/foreign/jp2ksave.c:818 +msgid "not an integer format" msgstr "" -#: ../libvips/create/mask_ideal_band.c:93 -msgid "make an ideal band filter" +#: libvips/foreign/jp2ksave.c:963 +msgid "save image in JPEG2000 format" msgstr "" -#: ../libvips/create/buildlut.c:134 +#: libvips/foreign/jpeg2vips.c:415 #, c-format -msgid "x value row %d not an int" +msgid "read gave %ld warnings" msgstr "" -#: ../libvips/create/buildlut.c:149 -msgid "x range too small" +#: libvips/foreign/jpeg2vips.c:886 libvips/foreign/spngload.c:529 +#: libvips/foreign/vipspng.c:723 +#, c-format +msgid "out of order read at line %d" msgstr "" -#: ../libvips/draw/draw_line.c:280 -msgid "draw a line on an image" +#: libvips/foreign/jpegload.c:116 +#, c-format +msgid "bad shrink factor %d" msgstr "" -#: ../libvips/draw/draw_line.c:285 ../libvips/draw/draw_line.c:292 -msgid "Start of draw_line" +#: libvips/foreign/jpegload.c:177 +msgid "load jpeg" msgstr "" -#: ../libvips/draw/draw_line.c:291 -msgid "y1" +#: libvips/foreign/jpegload.c:191 libvips/foreign/webpload.c:199 +msgid "Shrink" msgstr "" -#: ../libvips/draw/draw_line.c:298 -msgid "x2" +#: libvips/foreign/jpegload.c:192 libvips/foreign/webpload.c:200 +msgid "Shrink factor on load" msgstr "" -#: ../libvips/draw/draw_line.c:299 ../libvips/draw/draw_line.c:306 -msgid "End of draw_line" +#: libvips/foreign/jpegload.c:270 +msgid "load image from jpeg source" msgstr "" -#: ../libvips/draw/draw_image.c:255 -msgid "paint an image into another image" +#: libvips/foreign/jpegload.c:346 +msgid "load jpeg from file" msgstr "" -#: ../libvips/draw/draw_image.c:266 ../libvips/draw/draw_image.c:273 -msgid "Draw image here" +#: libvips/foreign/jpegload.c:424 +msgid "load jpeg from buffer" msgstr "" -#: ../libvips/draw/draw_image.c:279 ../libvips/iofuncs/image.c:1207 -msgid "Mode" +#: libvips/foreign/jpegsave.c:153 +msgid "save jpeg" msgstr "" -#: ../libvips/draw/draw_image.c:280 -msgid "Combining mode" +#: libvips/foreign/jpegsave.c:171 +msgid "Optimize coding" msgstr "" -#: ../libvips/draw/draw_mask.c:319 -msgid "draw a mask on an image" +#: libvips/foreign/jpegsave.c:172 +msgid "Compute optimal Huffman coding tables" msgstr "" -#: ../libvips/draw/draw_mask.c:324 -msgid "Mask of pixels to draw" +#: libvips/foreign/jpegsave.c:178 libvips/foreign/pngsave.c:218 +#: libvips/foreign/spngsave.c:696 +msgid "Interlace" msgstr "" -#: ../libvips/draw/draw_mask.c:330 ../libvips/draw/draw_mask.c:337 -msgid "Draw mask here" +#: libvips/foreign/jpegsave.c:179 +msgid "Generate an interlaced (progressive) jpeg" msgstr "" -#: ../libvips/draw/draw.c:129 -msgid "draw operations" +#: libvips/foreign/jpegsave.c:185 +msgid "No subsample" msgstr "" -#: ../libvips/draw/draw.c:133 -msgid "Image" +#: libvips/foreign/jpegsave.c:186 +msgid "Disable chroma subsample" msgstr "" -#: ../libvips/draw/draw.c:134 -msgid "Image to draw on" +#: libvips/foreign/jpegsave.c:192 +msgid "Trellis quantisation" msgstr "" -#: ../libvips/draw/draw_smudge.c:193 -msgid "blur a rectangle on an image" +#: libvips/foreign/jpegsave.c:193 +msgid "Apply trellis quantisation to each 8x8 block" msgstr "" -#: ../libvips/draw/draw_smudge.c:198 ../libvips/draw/draw_smudge.c:205 -#: ../libvips/draw/draw_smudge.c:212 ../libvips/draw/draw_smudge.c:219 -#: ../libvips/draw/draw_rect.c:174 ../libvips/draw/draw_rect.c:181 -#: ../libvips/draw/draw_rect.c:188 ../libvips/draw/draw_rect.c:195 -msgid "Rect to fill" +#: libvips/foreign/jpegsave.c:199 +msgid "Overshoot de-ringing" msgstr "" -#: ../libvips/draw/draw_smudge.c:204 ../libvips/draw/draw_rect.c:180 -msgid "top" +#: libvips/foreign/jpegsave.c:200 +msgid "Apply overshooting to samples with extreme values" msgstr "" -#: ../libvips/draw/draw_smudge.c:211 ../libvips/draw/draw_rect.c:187 -msgid "width" +#: libvips/foreign/jpegsave.c:206 +msgid "Optimize scans" msgstr "" -#: ../libvips/draw/draw_smudge.c:218 ../libvips/draw/draw_rect.c:194 -msgid "height" +#: libvips/foreign/jpegsave.c:207 +msgid "Split spectrum of DCT coefficients into separate scans" msgstr "" -#: ../libvips/draw/drawink.c:86 -msgid "draw with ink operations" +#: libvips/foreign/jpegsave.c:213 +msgid "Quantization table" msgstr "" -#: ../libvips/draw/drawink.c:90 -msgid "Ink" +#: libvips/foreign/jpegsave.c:214 +msgid "Use predefined quantization table with given index" msgstr "" -#: ../libvips/draw/drawink.c:91 -msgid "Color for pixels" +#: libvips/foreign/jpegsave.c:228 +msgid "Restart interval" msgstr "" -#: ../libvips/draw/draw_circle.c:231 -msgid "draw a circle on an image" +#: libvips/foreign/jpegsave.c:229 +msgid "Add restart markers every specified number of mcu" msgstr "" -#: ../libvips/draw/draw_circle.c:235 -msgid "cx" +#: libvips/foreign/jpegsave.c:288 +msgid "save image to jpeg target" msgstr "" -#: ../libvips/draw/draw_circle.c:236 ../libvips/draw/draw_circle.c:243 -msgid "Centre of draw_circle" +#: libvips/foreign/jpegsave.c:357 +msgid "save image to jpeg file" msgstr "" -#: ../libvips/draw/draw_circle.c:242 -msgid "cy" +#: libvips/foreign/jpegsave.c:435 +msgid "save image to jpeg buffer" msgstr "" -#: ../libvips/draw/draw_circle.c:250 -msgid "Radius in pixels" +#: libvips/foreign/jpegsave.c:511 +msgid "save image to jpeg mime" msgstr "" -#: ../libvips/draw/draw_circle.c:256 ../libvips/draw/draw_rect.c:201 -msgid "Fill" +#: libvips/foreign/jxlload.c:251 libvips/foreign/jxlsave.c:433 +#: libvips/iofuncs/dbuf.c:81 libvips/iofuncs/util.c:684 +msgid "out of memory" msgstr "" -#: ../libvips/draw/draw_circle.c:257 ../libvips/draw/draw_rect.c:202 -msgid "Draw a solid object" +#: libvips/foreign/jxlload.c:576 +msgid "bad buffer size" msgstr "" -#: ../libvips/draw/draw_flood.c:548 -msgid "flood-fill an area" +#: libvips/foreign/jxlload.c:602 libvips/foreign/webp2vips.c:724 +msgid "not enough frames" msgstr "" -#: ../libvips/draw/draw_flood.c:553 ../libvips/draw/draw_flood.c:560 -msgid "DrawFlood start point" +#: libvips/foreign/jxlload.c:683 libvips/foreign/radiance.c:704 +msgid "image size out of bounds" msgstr "" -#: ../libvips/draw/draw_flood.c:566 -msgid "Test" +#: libvips/foreign/jxlload.c:1119 +msgid "load JPEG-XL image" msgstr "" -#: ../libvips/draw/draw_flood.c:567 -msgid "Test pixels in this image" +#: libvips/foreign/jxlsave.c:748 libvips/foreign/webpsave.c:744 +#, c-format +msgid "failed to allocate %zu bytes" msgstr "" -#: ../libvips/draw/draw_flood.c:572 -msgid "Equal" +#: libvips/foreign/jxlsave.c:796 +msgid "save image in JPEG-XL format" msgstr "" -#: ../libvips/draw/draw_flood.c:573 -msgid "DrawFlood while equal to edge" +#: libvips/foreign/jxlsave.c:810 +msgid "Tier" msgstr "" -#: ../libvips/draw/draw_flood.c:580 -msgid "Left edge of modified area" +#: libvips/foreign/jxlsave.c:811 +msgid "Decode speed tier" msgstr "" -#: ../libvips/draw/draw_flood.c:587 -msgid "top edge of modified area" +#: libvips/foreign/jxlsave.c:817 libvips/morphology/nearest.c:315 +msgid "Distance" msgstr "" -#: ../libvips/draw/draw_flood.c:594 -msgid "width of modified area" +#: libvips/foreign/jxlsave.c:818 +msgid "Target butteraugli distance" msgstr "" -#: ../libvips/draw/draw_flood.c:601 -msgid "height of modified area" +#: libvips/foreign/jxlsave.c:825 +msgid "Encoding effort" msgstr "" -#: ../libvips/draw/draw_rect.c:169 -msgid "paint a rectangle on an image" +#: libvips/foreign/jxlsave.c:839 +msgid "Quality factor" msgstr "" -#: ../libvips/foreign/foreign.c:357 -msgid "load and save image files" +#: libvips/foreign/magick2vips.c:305 +#, c-format +msgid "unsupported image type %d" msgstr "" -#: ../libvips/foreign/foreign.c:520 ../libvips/mosaicing/im_remosaic.c:87 +#: libvips/foreign/magick2vips.c:354 libvips/foreign/magick7load.c:471 #, c-format -msgid "file \"%s\" not found" +msgid "bad image dimensions %d x %d pixels, %d bands" msgstr "" -#: ../libvips/foreign/foreign.c:529 ../libvips/foreign/foreign.c:1592 +#: libvips/foreign/magick2vips.c:384 #, c-format -msgid "\"%s\" is not a known file format" +msgid "unsupported bit depth %d" msgstr "" -#: ../libvips/foreign/foreign.c:605 -msgid "buffer is not in a known format" +#: libvips/foreign/magick2vips.c:791 libvips/foreign/webp2vips.c:638 +msgid "unable to read pixels" msgstr "" -#: ../libvips/foreign/foreign.c:773 -msgid "images do not match" +#: libvips/foreign/magick2vips.c:823 libvips/foreign/magick2vips.c:861 +#, c-format +msgid "unable to read file \"%s\"" msgstr "" -#: ../libvips/foreign/foreign.c:979 -msgid "file loaders" +#: libvips/foreign/magick2vips.c:870 libvips/foreign/magick2vips.c:949 +msgid "bad image size" msgstr "" -#: ../libvips/foreign/foreign.c:990 -msgid "Flags" +#: libvips/foreign/magick2vips.c:902 +msgid "unable to read buffer" msgstr "" -#: ../libvips/foreign/foreign.c:991 -msgid "Flags for this file" +#: libvips/foreign/magick2vips.c:940 +msgid "unable to ping blob" msgstr "" -#: ../libvips/foreign/foreign.c:997 -msgid "Disc" +#: libvips/foreign/magick6load.c:113 +msgid "load with ImageMagick" msgstr "" -#: ../libvips/foreign/foreign.c:998 -msgid "Open to disc" +#: libvips/foreign/magick6load.c:134 libvips/foreign/magick7load.c:375 +msgid "Density" msgstr "" -#: ../libvips/foreign/foreign.c:1005 -msgid "Required access pattern for this file" +#: libvips/foreign/magick6load.c:135 libvips/foreign/magick7load.c:376 +msgid "Canvas resolution for rendering vector formats like SVG" msgstr "" -#: ../libvips/foreign/foreign.c:1011 -msgid "Sequential" +#: libvips/foreign/magick6load.c:155 libvips/foreign/magick7load.c:396 +msgid "All frames" msgstr "" -#: ../libvips/foreign/foreign.c:1012 -msgid "Sequential read only" +#: libvips/foreign/magick6load.c:156 libvips/foreign/magick7load.c:397 +msgid "Read all frames from an image" msgstr "" -#: ../libvips/foreign/foreign.c:1018 -msgid "Fail" +#: libvips/foreign/magick6load.c:231 +msgid "load file with ImageMagick" msgstr "" -#: ../libvips/foreign/foreign.c:1019 -msgid "Fail on first warning" +#: libvips/foreign/magick6load.c:306 +msgid "load buffer with ImageMagick" msgstr "" -#: ../libvips/foreign/foreign.c:1499 -msgid "file savers" +#: libvips/foreign/magick7load.c:353 +msgid "load with ImageMagick7" msgstr "" -#: ../libvips/foreign/foreign.c:1523 -msgid "Image to save" +#: libvips/foreign/magick7load.c:414 +#, c-format +msgid "Magick: %s %s" msgstr "" -#: ../libvips/foreign/foreign.c:1528 -msgid "Strip" +#: libvips/foreign/magick7load.c:491 +#, c-format +msgid "unsupported bit depth %zd" msgstr "" -#: ../libvips/foreign/foreign.c:1529 -msgid "Strip all metadata from image" +#: libvips/foreign/magick7load.c:845 +msgid "load file with ImageMagick7" msgstr "" -#: ../libvips/foreign/foreign.c:1667 -#, c-format -msgid "\"%s\" is not a known buffer format" +#: libvips/foreign/magick7load.c:926 +msgid "load buffer with ImageMagick7" msgstr "" -#: ../libvips/foreign/ppm.c:116 -msgid "bad int" +#: libvips/foreign/magick.c:804 +#, c-format +msgid "libMagick error: %s %s" msgstr "" -#: ../libvips/foreign/ppm.c:128 -msgid "bad float" +#: libvips/foreign/magick.c:807 +#, c-format +msgid "libMagick error: %s" msgstr "" -#: ../libvips/foreign/ppm.c:179 -msgid "bad magic number" +#: libvips/foreign/magick.c:810 +msgid "libMagick error:" msgstr "" -#: ../libvips/foreign/ppm.c:230 -msgid "not whitespace before start of binary data" +#: libvips/foreign/matlab.c:121 +#, c-format +msgid "no matrix variables in \"%s\"" msgstr "" -#: ../libvips/foreign/ppm.c:621 ../libvips/foreign/ppm.c:638 -#: ../libvips/foreign/ppm.c:672 ../libvips/foreign/ppm.c:686 -msgid "write error" +#: libvips/foreign/matlab.c:203 +#, c-format +msgid "unsupported rank %d\n" msgstr "" -#: ../libvips/foreign/ppm.c:813 ../libvips/foreign/vips2tiff.c:1001 -msgid "can only squash 1 band uchar images -- disabling squash" +#: libvips/foreign/matlab.c:211 +#, c-format +msgid "unsupported class type %d\n" msgstr "" -#: ../libvips/foreign/csvsave.c:95 -msgid "save image to csv file" +#: libvips/foreign/matlab.c:265 +msgid "Mat_VarReadDataAll failed" msgstr "" -#: ../libvips/foreign/csvsave.c:103 ../libvips/foreign/pngload.c:144 -#: ../libvips/foreign/webpload.c:192 ../libvips/foreign/pngsave.c:189 -#: ../libvips/foreign/fitsload.c:123 ../libvips/foreign/matrixsave.c:121 -#: ../libvips/foreign/ppmsave.c:123 ../libvips/foreign/csvload.c:141 -#: ../libvips/foreign/ppmload.c:135 ../libvips/foreign/magickload.c:223 -#: ../libvips/foreign/gifload.c:892 ../libvips/foreign/magick7load.c:803 -#: ../libvips/foreign/fitssave.c:138 ../libvips/foreign/pdfload.c:590 -#: ../libvips/foreign/openslideload.c:187 ../libvips/foreign/rawload.c:116 -#: ../libvips/foreign/tiffsave.c:362 ../libvips/foreign/svgload.c:368 -#: ../libvips/foreign/radsave.c:154 ../libvips/foreign/dzsave.c:2319 -#: ../libvips/foreign/radload.c:138 ../libvips/foreign/openexrload.c:144 -#: ../libvips/foreign/vipssave.c:114 ../libvips/foreign/webpsave.c:214 -#: ../libvips/foreign/rawsave.c:145 ../libvips/foreign/jpegsave.c:268 -#: ../libvips/foreign/matrixload.c:153 ../libvips/foreign/jpegload.c:232 -#: ../libvips/foreign/analyzeload.c:135 ../libvips/foreign/matload.c:133 -#: ../libvips/foreign/vipsload.c:138 ../libvips/foreign/tiffload.c:223 -#: ../libvips/iofuncs/image.c:1200 ../libvips/resample/thumbnail.c:669 -msgid "Filename" +#: libvips/foreign/matload.c:122 +msgid "load mat from file" msgstr "" -#: ../libvips/foreign/csvsave.c:104 ../libvips/foreign/pngsave.c:190 -#: ../libvips/foreign/matrixsave.c:122 ../libvips/foreign/ppmsave.c:124 -#: ../libvips/foreign/fitssave.c:139 ../libvips/foreign/tiffsave.c:363 -#: ../libvips/foreign/radsave.c:155 ../libvips/foreign/dzsave.c:2320 -#: ../libvips/foreign/vipssave.c:115 ../libvips/foreign/webpsave.c:215 -#: ../libvips/foreign/rawsave.c:146 ../libvips/foreign/jpegsave.c:269 -msgid "Filename to save to" +#: libvips/foreign/matrixload.c:128 libvips/foreign/matrixload.c:242 +#, c-format +msgid "bad number \"%s\"" msgstr "" -#: ../libvips/foreign/csvsave.c:110 ../libvips/foreign/csvload.c:169 -msgid "Separator" +#: libvips/foreign/matrixload.c:137 +msgid "no width / height" msgstr "" -#: ../libvips/foreign/csvsave.c:111 -msgid "Separator characters" +#: libvips/foreign/matrixload.c:143 +msgid "width / height not int" msgstr "" -#: ../libvips/foreign/webp2vips.c:199 -msgid "bad setting for shrink" +#: libvips/foreign/matrixload.c:156 +msgid "width / height out of range" msgstr "" -#: ../libvips/foreign/webp2vips.c:247 -msgid "unable to read image metadata" +#: libvips/foreign/matrixload.c:160 +msgid "zero scale" msgstr "" -#: ../libvips/foreign/webp2vips.c:290 ../libvips/foreign/webp2vips.c:340 -#: ../libvips/foreign/matlab.c:113 ../libvips/foreign/fits.c:189 -#: ../libvips/iofuncs/vips.c:163 ../libvips/mosaicing/global_balance.c:1192 -#: ../libvips/mosaicing/global_balance.c:1530 +#: libvips/foreign/matrixload.c:251 #, c-format -msgid "unable to open \"%s\"" +msgid "line %d too short" msgstr "" -#: ../libvips/foreign/webp2vips.c:323 ../libvips/foreign/magick2vips.c:723 -msgid "unable to read pixels" +#: libvips/foreign/matrixload.c:273 +msgid "load matrix" msgstr "" -#: ../libvips/foreign/webp2vips.c:360 ../libvips/foreign/webp2vips.c:382 -msgid "unable to open buffer" +#: libvips/foreign/matrixsave.c:175 +msgid "save image to matrix" msgstr "" -#: ../libvips/foreign/pngload.c:128 -msgid "load png from file" +#: libvips/foreign/matrixsave.c:323 +msgid "print matrix" msgstr "" -#: ../libvips/foreign/pngload.c:145 ../libvips/foreign/webpload.c:193 -#: ../libvips/foreign/fitsload.c:124 ../libvips/foreign/csvload.c:142 -#: ../libvips/foreign/ppmload.c:136 ../libvips/foreign/magickload.c:224 -#: ../libvips/foreign/gifload.c:893 ../libvips/foreign/magick7load.c:804 -#: ../libvips/foreign/pdfload.c:591 ../libvips/foreign/openslideload.c:188 -#: ../libvips/foreign/rawload.c:117 ../libvips/foreign/svgload.c:369 -#: ../libvips/foreign/radload.c:139 ../libvips/foreign/openexrload.c:145 -#: ../libvips/foreign/matrixload.c:154 ../libvips/foreign/jpegload.c:233 -#: ../libvips/foreign/analyzeload.c:136 ../libvips/foreign/matload.c:134 -#: ../libvips/foreign/vipsload.c:139 ../libvips/foreign/tiffload.c:224 -msgid "Filename to load from" +#: libvips/foreign/niftiload.c:406 +msgid "invalid dimension" msgstr "" -#: ../libvips/foreign/pngload.c:222 -msgid "load png from buffer" +#: libvips/foreign/niftiload.c:417 +msgid "invalid resolution" msgstr "" -#: ../libvips/foreign/pngload.c:230 ../libvips/foreign/webpload.c:268 -#: ../libvips/foreign/pngsave.c:255 ../libvips/foreign/magickload.c:307 -#: ../libvips/foreign/gifload.c:977 ../libvips/foreign/magick7load.c:900 -#: ../libvips/foreign/pdfload.c:652 ../libvips/foreign/tiffsave.c:437 -#: ../libvips/foreign/svgload.c:531 ../libvips/foreign/radsave.c:217 -#: ../libvips/foreign/dzsave.c:2406 ../libvips/foreign/webpsave.c:285 -#: ../libvips/foreign/jpegsave.c:340 ../libvips/foreign/jpegload.c:311 -#: ../libvips/foreign/tiffload.c:314 ../libvips/resample/thumbnail.c:836 -msgid "Buffer" +#: libvips/foreign/niftiload.c:431 libvips/foreign/niftiload.c:435 +#: libvips/foreign/niftisave.c:309 +msgid "dimension overflow" msgstr "" -#: ../libvips/foreign/pngload.c:231 ../libvips/foreign/webpload.c:269 -#: ../libvips/foreign/magickload.c:308 ../libvips/foreign/gifload.c:978 -#: ../libvips/foreign/magick7load.c:901 ../libvips/foreign/pdfload.c:653 -#: ../libvips/foreign/svgload.c:532 ../libvips/foreign/jpegload.c:312 -#: ../libvips/foreign/tiffload.c:315 ../libvips/resample/thumbnail.c:837 -msgid "Buffer to load from" +#: libvips/foreign/niftiload.c:536 +msgid "unable to read NIFTI header" msgstr "" -#: ../libvips/foreign/matlab.c:121 -#, c-format -msgid "no matrix variables in \"%s\"" +#: libvips/foreign/niftiload.c:564 +msgid "unable to load NIFTI file" msgstr "" -#: ../libvips/foreign/matlab.c:203 -#, c-format -msgid "unsupported rank %d\n" +#: libvips/foreign/niftiload.c:594 +msgid "load a NIFTI image" msgstr "" -#: ../libvips/foreign/matlab.c:211 -#, c-format -msgid "unsupported class type %d\n" +#: libvips/foreign/niftiload.c:705 +msgid "load NIfTI volume" msgstr "" -#: ../libvips/foreign/matlab.c:260 -msgid "Mat_VarReadDataAll failed" +#: libvips/foreign/niftiload.c:783 +msgid "load NIfTI volumes" msgstr "" -#: ../libvips/foreign/webpload.c:94 -msgid "load webp" +#: libvips/foreign/niftisave.c:115 libvips/foreign/niftisave.c:322 +#, fuzzy +msgid "unsupported libvips image type" +msgstr "unsupported colour type" + +#: libvips/foreign/niftisave.c:122 +msgid "8-bit colour images only" msgstr "" -#: ../libvips/foreign/webpload.c:100 ../libvips/foreign/jpegload.c:137 -msgid "Shrink" +#: libvips/foreign/niftisave.c:132 +msgid "3 or 4 band colour images only" msgstr "" -#: ../libvips/foreign/webpload.c:101 ../libvips/foreign/jpegload.c:138 -msgid "Shrink factor on load" +#: libvips/foreign/niftisave.c:251 +msgid "bad nifti-ext- field name" msgstr "" -#: ../libvips/foreign/webpload.c:181 -msgid "load webp from file" +#: libvips/foreign/niftisave.c:260 +msgid "unable to attach nifti ext" msgstr "" -#: ../libvips/foreign/webpload.c:257 -msgid "load webp from buffer" +#: libvips/foreign/niftisave.c:315 libvips/foreign/nsgifload.c:644 +#: libvips/foreign/webp2vips.c:550 +msgid "bad image dimensions" msgstr "" -#: ../libvips/foreign/pngsave.c:100 -msgid "save png" +#: libvips/foreign/niftisave.c:375 +msgid "unable to set nifti filename" msgstr "" -#: ../libvips/foreign/pngsave.c:108 ../libvips/foreign/tiffsave.c:181 -#: ../libvips/foreign/dzsave.c:2200 -msgid "Compression" +#: libvips/foreign/niftisave.c:427 +msgid "save image to nifti file" msgstr "" -#: ../libvips/foreign/pngsave.c:109 -msgid "Compression factor" +#: libvips/foreign/nsgifload.c:420 +msgid "no frames in GIF" msgstr "" -#: ../libvips/foreign/pngsave.c:115 ../libvips/foreign/jpegsave.c:170 -msgid "Interlace" +#: libvips/foreign/nsgifload.c:463 +msgid "bad frame" msgstr "" -#: ../libvips/foreign/pngsave.c:116 -msgid "Interlace image" +#: libvips/foreign/nsgifload.c:607 libvips/foreign/nsgifload.c:757 +#: libvips/foreign/nsgifload.c:837 +msgid "load GIF with libnsgif" msgstr "" -#: ../libvips/foreign/pngsave.c:122 ../libvips/foreign/jpegsave.c:156 -msgid "Profile" +#: libvips/foreign/nsgifload.c:901 +msgid "load gif from source" msgstr "" -#: ../libvips/foreign/pngsave.c:123 ../libvips/foreign/tiffsave.c:205 -#: ../libvips/foreign/jpegsave.c:157 -msgid "ICC profile to embed" +#: libvips/foreign/openexr2vips.c:123 +#, c-format +msgid "EXR error: %s" msgstr "" -#: ../libvips/foreign/pngsave.c:129 -msgid "Filter" +#: libvips/foreign/openexrload.c:129 +msgid "load an OpenEXR image" msgstr "" -#: ../libvips/foreign/pngsave.c:130 -msgid "libpng row filter flag(s)" +#: libvips/foreign/openslideload.c:207 +msgid "invalid associated image name" msgstr "" -#: ../libvips/foreign/pngsave.c:185 -msgid "save image to png file" +#: libvips/foreign/openslideload.c:252 +msgid "specify only one of level and associated image" msgstr "" -#: ../libvips/foreign/pngsave.c:251 -msgid "save image to png buffer" +#: libvips/foreign/openslideload.c:259 +msgid "specify only one of attach_assicated and associated image" msgstr "" -#: ../libvips/foreign/pngsave.c:256 ../libvips/foreign/tiffsave.c:438 -#: ../libvips/foreign/radsave.c:218 ../libvips/foreign/dzsave.c:2407 -#: ../libvips/foreign/webpsave.c:286 ../libvips/foreign/jpegsave.c:341 -msgid "Buffer to save to" +#: libvips/foreign/openslideload.c:376 libvips/foreign/openslideload.c:491 +#: libvips/foreign/openslideload.c:652 +#, c-format +msgid "opening slide: %s" msgstr "" -#: ../libvips/foreign/tiff2vips.c:333 ../libvips/foreign/tiff2vips.c:351 +#: libvips/foreign/openslideload.c:398 #, c-format -msgid "required field %d missing" +msgid "reading associated image: %s" msgstr "" -#: ../libvips/foreign/tiff2vips.c:393 -msgid "unknown resolution unit" +#: libvips/foreign/openslideload.c:485 +msgid "unsupported slide format" +msgstr "" + +#: libvips/foreign/openslideload.c:498 +msgid "invalid slide level" msgstr "" -#: ../libvips/foreign/tiff2vips.c:398 +#: libvips/foreign/openslideload.c:590 #, c-format -msgid "" -"no resolution information for TIFF image \"%s\" -- defaulting to 1 pixel per " -"mm" +msgid "getting dimensions: %s" msgstr "" -#: ../libvips/foreign/tiff2vips.c:465 -msgid "read error" +#: libvips/foreign/openslideload.c:597 +msgid "image dimensions overflow int" msgstr "" -#: ../libvips/foreign/tiff2vips.c:482 +#: libvips/foreign/openslideload.c:753 #, c-format -msgid "TIFF does not contain page %d" +msgid "reading region: %s" msgstr "" -#: ../libvips/foreign/tiff2vips.c:516 -#, c-format -msgid "not %d bands" +#: libvips/foreign/openslideload.c:1017 +msgid "load OpenSlide base class" msgstr "" -#: ../libvips/foreign/tiff2vips.c:530 -#, c-format -msgid "not at least %d samples per pixel" +#: libvips/foreign/openslideload.c:1046 libvips/foreign/tiffsave.c:364 +msgid "Level" msgstr "" -#: ../libvips/foreign/tiff2vips.c:544 -#, c-format -msgid "not photometric interpretation %d" +#: libvips/foreign/openslideload.c:1047 +msgid "Load this level from the file" msgstr "" -#: ../libvips/foreign/tiff2vips.c:557 -#, c-format -msgid "not %d bits per sample" +#: libvips/foreign/openslideload.c:1053 +msgid "Autocrop" msgstr "" -#: ../libvips/foreign/tiff2vips.c:573 -#, c-format -msgid "%d bits per sample palette image not supported" +#: libvips/foreign/openslideload.c:1054 +msgid "Crop to image bounds" msgstr "" -#: ../libvips/foreign/tiff2vips.c:630 -msgid "unsupported tiff image type\n" +#: libvips/foreign/openslideload.c:1060 +msgid "Associated" msgstr "" -#: ../libvips/foreign/tiff2vips.c:1038 -msgid "bad colormap" -msgstr "bad colourmap" +#: libvips/foreign/openslideload.c:1061 +msgid "Load this associated image" +msgstr "" -#: ../libvips/foreign/tiff2vips.c:1059 -msgid "assuming 8-bit palette" +#: libvips/foreign/openslideload.c:1067 +msgid "Attach associated" msgstr "" -#: ../libvips/foreign/tiff2vips.c:1594 -msgid "tiled separate planes not supported" +#: libvips/foreign/openslideload.c:1068 +msgid "Attach all associated images" msgstr "" -#: ../libvips/foreign/tiff2vips.c:1616 ../libvips/foreign/tiff2vips.c:1883 -msgid "unsupported tiff image type" +#: libvips/foreign/openslideload.c:1074 +msgid "RGB" msgstr "" -#: ../libvips/foreign/tiff2vips.c:1981 -#, c-format -msgid "bad page number %d" +#: libvips/foreign/openslideload.c:1075 +msgid "Output RGB (not RGBA)" msgstr "" -#: ../libvips/foreign/tiff2vips.c:1991 -#, c-format -msgid "bad number of pages %d" +#: libvips/foreign/openslideload.c:1144 +msgid "load file with OpenSlide" msgstr "" -#: ../libvips/foreign/tiff2vips.c:2022 -msgid "width/height out of range" +#: libvips/foreign/openslideload.c:1223 +msgid "load source with OpenSlide" msgstr "" -#: ../libvips/foreign/tiff2vips.c:2031 -msgid "samples out of range" +#: libvips/foreign/pdfiumload.c:196 +msgid "unknown error" msgstr "" -#: ../libvips/foreign/tiff2vips.c:2160 +#: libvips/foreign/pdfiumload.c:291 #, c-format -msgid "page %d differs from page %d" +msgid "%s: too large for pdfium" msgstr "" -#: ../libvips/foreign/fitsload.c:110 -msgid "load a FITS image" +#: libvips/foreign/pdfiumload.c:307 +#, c-format +msgid "%s: unable to load" msgstr "" -#: ../libvips/foreign/matrixsave.c:112 -msgid "save image to matrix file" +#: libvips/foreign/pdfiumload.c:318 +#, c-format +msgid "%s: unable to initialize form fill environment" msgstr "" -#: ../libvips/foreign/matrixsave.c:192 -msgid "print matrix" +#: libvips/foreign/pdfiumload.c:366 libvips/foreign/popplerload.c:239 +#, c-format +msgid "unable to load page %d" msgstr "" -#: ../libvips/foreign/vips2webp.c:128 -msgid "output webp image too large" +#: libvips/foreign/pdfiumload.c:478 libvips/foreign/popplerload.c:333 +msgid "pages out of range" msgstr "" -#: ../libvips/foreign/vips2webp.c:134 ../libvips/iofuncs/util.c:738 -msgid "out of memory" +#: libvips/foreign/pdfiumload.c:513 +msgid "page size out of range" msgstr "" -#: ../libvips/foreign/vips2webp.c:242 ../libvips/foreign/vips2webp.c:252 -msgid "config version error" +#: libvips/foreign/pdfiumload.c:685 +msgid "load PDF with PDFium" msgstr "" -#: ../libvips/foreign/vips2webp.c:266 -msgid "lossless unsupported" +#: libvips/foreign/pdfiumload.c:717 libvips/foreign/popplerload.c:567 +#: libvips/foreign/webpload.c:193 +msgid "Factor to scale by" msgstr "" -#: ../libvips/foreign/vips2webp.c:268 -msgid "alpha_q unsupported" +#: libvips/foreign/pdfiumload.c:724 libvips/foreign/popplerload.c:574 +msgid "Background colour" msgstr "" -#: ../libvips/foreign/vips2webp.c:278 -msgid "near_lossless unsupported" +#: libvips/foreign/pdfiumload.c:730 libvips/foreign/popplerload.c:580 +msgid "Password" msgstr "" -#: ../libvips/foreign/vips2webp.c:280 -msgid "smart_subsample unsupported" +#: libvips/foreign/pdfiumload.c:731 libvips/foreign/popplerload.c:581 +msgid "Password to decrypt with" msgstr "" -#: ../libvips/foreign/vips2webp.c:284 -msgid "invalid configuration" +#: libvips/foreign/pdfiumload.c:803 libvips/foreign/popplerload.c:680 +msgid "load PDF from file" msgstr "" -#: ../libvips/foreign/vips2webp.c:302 -msgid "picture memory error" +#: libvips/foreign/pdfiumload.c:866 libvips/foreign/popplerload.c:743 +msgid "load PDF from buffer" msgstr "" -#: ../libvips/foreign/vips2webp.c:308 -msgid "unable to encode" +#: libvips/foreign/pdfiumload.c:924 libvips/foreign/popplerload.c:801 +msgid "load PDF from source" msgstr "" -#: ../libvips/foreign/vips2webp.c:526 ../libvips/foreign/vips2webp.c:579 -msgid "picture version error" +#: libvips/foreign/pngload.c:157 libvips/foreign/spngload.c:664 +msgid "load png base class" msgstr "" -#: ../libvips/foreign/tiff.c:123 -#, c-format -msgid "unable to open \"%s\" for output" +#: libvips/foreign/pngload.c:234 libvips/foreign/spngload.c:749 +msgid "load png from source" msgstr "" -#: ../libvips/foreign/tiff.c:169 -#, c-format -msgid "unable to open \"%s\" for input" +#: libvips/foreign/pngload.c:310 libvips/foreign/spngload.c:827 +msgid "load png from file" msgstr "" -#: ../libvips/foreign/tiff.c:195 -msgid "read beyond end of buffer" +#: libvips/foreign/pngload.c:388 libvips/foreign/spngload.c:905 +msgid "load png from buffer" msgstr "" -#: ../libvips/foreign/tiff.c:291 -msgid "unable to open memory buffer for input" +#: libvips/foreign/pngsave.c:202 +msgid "save png" msgstr "" -#: ../libvips/foreign/tiff.c:348 -msgid "Out of memory." +#: libvips/foreign/pngsave.c:212 libvips/foreign/spngsave.c:690 +msgid "Compression factor" msgstr "" -#: ../libvips/foreign/tiff.c:450 -msgid "unable to open memory buffer for output" +#: libvips/foreign/pngsave.c:219 libvips/foreign/spngsave.c:697 +msgid "Interlace image" msgstr "" -#: ../libvips/foreign/ppmsave.c:114 -msgid "save image to ppm file" +#: libvips/foreign/pngsave.c:225 libvips/foreign/spngsave.c:703 +msgid "Filter" msgstr "" -#: ../libvips/foreign/ppmsave.c:130 -msgid "ASCII" +#: libvips/foreign/pngsave.c:226 +msgid "libpng row filter flag(s)" msgstr "" -#: ../libvips/foreign/ppmsave.c:131 -msgid "save as ascii" +#: libvips/foreign/pngsave.c:233 libvips/foreign/spngsave.c:711 +msgid "Palette" msgstr "" -#: ../libvips/foreign/ppmsave.c:137 ../libvips/foreign/tiffsave.c:239 -msgid "Squash" +#: libvips/foreign/pngsave.c:234 libvips/foreign/spngsave.c:712 +msgid "Quantise to 8bpp palette" msgstr "" -#: ../libvips/foreign/ppmsave.c:138 -msgid "save as one bit" +#: libvips/foreign/pngsave.c:240 libvips/foreign/spngsave.c:718 +#: libvips/foreign/vips2magick.c:489 +msgid "Quality" msgstr "" -#. Only a warning, since (for example) exported spreadsheets -#. * will often have text or date fields. -#. -#: ../libvips/foreign/csv.c:198 -#, c-format -msgid "error parsing number, line %d, column %d" +#: libvips/foreign/pngsave.c:241 libvips/foreign/spngsave.c:719 +msgid "Quantisation quality" msgstr "" -#: ../libvips/foreign/csv.c:256 -msgid "end of file while skipping start" +#: libvips/foreign/pngsave.c:255 libvips/foreign/spngsave.c:733 +msgid "Write as a 1, 2, 4, 8 or 16 bit image" msgstr "" -#: ../libvips/foreign/csv.c:265 ../libvips/iofuncs/util.c:1050 -#: ../libvips/iofuncs/util.c:1056 -msgid "unable to seek" +#: libvips/foreign/pngsave.c:262 libvips/foreign/spngsave.c:740 +msgid "Quantisation CPU effort" msgstr "" -#: ../libvips/foreign/csv.c:276 -msgid "empty line" +#: libvips/foreign/pngsave.c:268 libvips/foreign/spngsave.c:746 +msgid "Colours" msgstr "" -#: ../libvips/foreign/csv.c:316 -#, c-format -msgid "unexpected EOF, line %d col %d" +#: libvips/foreign/pngsave.c:269 libvips/foreign/spngsave.c:747 +msgid "Max number of palette colours" msgstr "" -#: ../libvips/foreign/csv.c:322 -#, c-format -msgid "unexpected EOL, line %d col %d" +#: libvips/foreign/pngsave.c:322 libvips/foreign/spngsave.c:801 +msgid "save image to target as PNG" msgstr "" -#: ../libvips/foreign/csv.c:554 -msgid "no width / height" +#: libvips/foreign/pngsave.c:374 +msgid "save image to png file" msgstr "" -#: ../libvips/foreign/csv.c:560 -msgid "width / height not int" +#: libvips/foreign/pngsave.c:433 +msgid "save image to png buffer" msgstr "" -#: ../libvips/foreign/csv.c:570 -msgid "width / height out of range" +#: libvips/foreign/popplerload.c:531 +msgid "load PDF with libpoppler" msgstr "" -#: ../libvips/foreign/csv.c:574 -msgid "extra chars in header" +#: libvips/foreign/ppmload.c:264 +msgid "bad magic number" msgstr "" -#: ../libvips/foreign/csv.c:578 -msgid "zero scale" +#: libvips/foreign/ppmload.c:521 +msgid "file truncated" msgstr "" -#: ../libvips/foreign/csv.c:626 -msgid "line too short" +#: libvips/foreign/ppmload.c:746 +msgid "load ppm base class" msgstr "" -#: ../libvips/foreign/csv.c:670 -#, c-format -msgid "line %d too short" +#: libvips/foreign/ppmload.c:823 +msgid "load ppm from file" msgstr "" -#: ../libvips/foreign/csvload.c:126 -msgid "load csv from file" +#: libvips/foreign/ppmsave.c:321 +msgid "too few bands for format" msgstr "" -#: ../libvips/foreign/csvload.c:148 -msgid "Skip" +#: libvips/foreign/ppmsave.c:499 +msgid "save to ppm" msgstr "" -#: ../libvips/foreign/csvload.c:149 -msgid "Skip this many lines at the start of the file" +#: libvips/foreign/ppmsave.c:507 libvips/foreign/vips2magick.c:483 +msgid "Format to save in" msgstr "" -#: ../libvips/foreign/csvload.c:155 -msgid "Lines" +#: libvips/foreign/ppmsave.c:514 +msgid "ASCII" msgstr "" -#: ../libvips/foreign/csvload.c:156 -msgid "Read this many lines from the file" +#: libvips/foreign/ppmsave.c:515 +msgid "Save as ascii" msgstr "" -#: ../libvips/foreign/csvload.c:162 -msgid "Whitespace" +#: libvips/foreign/ppmsave.c:522 +msgid "Set to 1 to write as a 1 bit image" msgstr "" -#: ../libvips/foreign/csvload.c:163 -msgid "Set of whitespace characters" +#: libvips/foreign/ppmsave.c:528 libvips/foreign/tiffsave.c:406 +msgid "Squash" msgstr "" -#: ../libvips/foreign/csvload.c:170 -msgid "Set of separator characters" +#: libvips/foreign/ppmsave.c:529 +msgid "Save as one bit" msgstr "" -#: ../libvips/foreign/vipspng.c:307 -msgid "unsupported color type" -msgstr "unsupported colour type" +#: libvips/foreign/ppmsave.c:586 +msgid "save image to ppm file" +msgstr "" -#: ../libvips/foreign/vipspng.c:417 -msgid "unable to read PNG header" +#: libvips/foreign/ppmsave.c:675 +msgid "save image in pbm format" msgstr "" -#: ../libvips/foreign/vipspng.c:504 ../libvips/foreign/jpeg2vips.c:560 -#, c-format -msgid "out of order read at line %d" +#: libvips/foreign/ppmsave.c:707 +msgid "save image in pgm format" msgstr "" -#: ../libvips/foreign/vipspng.c:878 -msgid "compress should be in [0,9]" +#: libvips/foreign/ppmsave.c:739 +msgid "save image in pfm format" msgstr "" -#: ../libvips/foreign/vipspng.c:900 -#, c-format -msgid "can't save %d band image as png" +#: libvips/foreign/ppmsave.c:771 +msgid "save image in pnm format" msgstr "" -#: ../libvips/foreign/vipspng.c:1010 -#, c-format -msgid "unable to write \"%s\"" +#: libvips/foreign/quantise.c:469 +msgid "libvips not built with quantisation support" msgstr "" -#: ../libvips/foreign/vipspng.c:1078 -msgid "unable to write to buffer" +#: libvips/foreign/radiance.c:438 +msgid "scanline length mismatch" msgstr "" -#: ../libvips/foreign/vips2jpeg.c:148 -#, c-format -msgid "%s" +#: libvips/foreign/radiance.c:455 +msgid "overrun" msgstr "" -#: ../libvips/foreign/vips2jpeg.c:254 -#, c-format -msgid "field \"%s\" is too large for a single JPEG marker, ignoring" +#: libvips/foreign/radiance.c:687 +msgid "error reading radiance header" msgstr "" -#: ../libvips/foreign/ppmload.c:119 -msgid "load ppm from file" +#: libvips/foreign/radiance.c:774 +#, c-format +msgid "read error line %d" msgstr "" -#: ../libvips/foreign/magickload.c:105 -msgid "load with ImageMagick" +#: libvips/foreign/radload.c:125 +msgid "load rad base class" msgstr "" -#: ../libvips/foreign/magickload.c:117 ../libvips/foreign/magick7load.c:379 -msgid "all_frames" +#: libvips/foreign/radload.c:197 +msgid "load rad from source" msgstr "" -#: ../libvips/foreign/magickload.c:118 ../libvips/foreign/magick7load.c:380 -msgid "Read all frames from an image" +#: libvips/foreign/radload.c:273 +msgid "load a Radiance image from a file" msgstr "" -#: ../libvips/foreign/magickload.c:124 ../libvips/foreign/magick7load.c:386 -msgid "Density" +#: libvips/foreign/radload.c:350 +msgid "load rad from buffer" msgstr "" -#: ../libvips/foreign/magickload.c:125 ../libvips/foreign/magick7load.c:387 -msgid "Canvas resolution for rendering vector formats like SVG" +#: libvips/foreign/radsave.c:92 +msgid "save Radiance" msgstr "" -#: ../libvips/foreign/magickload.c:131 ../libvips/foreign/gifload.c:816 -#: ../libvips/foreign/magick7load.c:393 ../libvips/foreign/pdfload.c:468 -#: ../libvips/foreign/tiffload.c:99 -msgid "Page" +#: libvips/foreign/radsave.c:150 +msgid "save image to Radiance file" msgstr "" -#: ../libvips/foreign/magickload.c:132 ../libvips/foreign/gifload.c:817 -#: ../libvips/foreign/magick7load.c:394 ../libvips/foreign/pdfload.c:469 -msgid "Load this page from the file" +#: libvips/foreign/radsave.c:203 +msgid "save image to Radiance target" msgstr "" -#: ../libvips/foreign/magickload.c:139 ../libvips/foreign/gifload.c:824 -#: ../libvips/foreign/magick7load.c:401 ../libvips/foreign/pdfload.c:476 -#: ../libvips/foreign/tiffload.c:107 -msgid "Load this many pages" +#: libvips/foreign/radsave.c:269 +msgid "save image to Radiance buffer" msgstr "" -#: ../libvips/foreign/magickload.c:216 -msgid "load file with ImageMagick" +#: libvips/foreign/rawload.c:131 +msgid "load raw data from a file" msgstr "" -#: ../libvips/foreign/magickload.c:300 -msgid "load buffer with ImageMagick" +#: libvips/foreign/rawload.c:167 libvips/iofuncs/image.c:1200 +msgid "Size of header" msgstr "" -#: ../libvips/foreign/openexr2vips.c:121 -#, c-format -msgid "EXR error: %s" +#: libvips/foreign/rawload.c:168 libvips/iofuncs/image.c:1201 +msgid "Offset in bytes from start of file" msgstr "" -#: ../libvips/foreign/gifload.c:145 -msgid "Failed to open given file" +#: libvips/foreign/rawsave.c:138 +msgid "save image to raw" msgstr "" -#: ../libvips/foreign/gifload.c:148 -msgid "Failed to read from given file" +#: libvips/foreign/rawsave.c:190 +msgid "save image to raw file" msgstr "" -#: ../libvips/foreign/gifload.c:151 -msgid "Data is not a GIF file" +#: libvips/foreign/rawsave.c:246 +msgid "write raw image to target" msgstr "" -#: ../libvips/foreign/gifload.c:154 -msgid "No screen descriptor detected" +#: libvips/foreign/rawsave.c:308 +msgid "write raw image to buffer" msgstr "" -#: ../libvips/foreign/gifload.c:157 -msgid "No image descriptor detected" +#: libvips/foreign/spngload.c:252 libvips/foreign/vipspng.c:582 +#, c-format +msgid "%d text chunks, only %d text chunks will be loaded" msgstr "" -#: ../libvips/foreign/gifload.c:160 -msgid "Neither global nor local color map" -msgstr "Neither global nor local colour map" +#: libvips/foreign/spngload.c:403 +#, fuzzy +msgid "unknown color type" +msgstr "unsupported colour type" -#: ../libvips/foreign/gifload.c:163 -msgid "Wrong record type detected" +#: libvips/foreign/spngload.c:562 +msgid "libspng read error" msgstr "" -#: ../libvips/foreign/gifload.c:166 -msgid "Number of pixels bigger than width * height" +#: libvips/foreign/spngsave.c:164 libvips/foreign/vipspng.c:1013 +msgid "bad png comment key" msgstr "" -#: ../libvips/foreign/gifload.c:169 -msgid "Failed to allocate required memory" +#: libvips/foreign/spngsave.c:680 +msgid "save spng" msgstr "" -#: ../libvips/foreign/gifload.c:172 -msgid "Failed to close given file" +#: libvips/foreign/spngsave.c:704 +msgid "libspng row filter flag(s)" msgstr "" -#: ../libvips/foreign/gifload.c:175 -msgid "Given file was not opened for read" +#: libvips/foreign/spngsave.c:854 +msgid "save image to file as PNG" msgstr "" -#: ../libvips/foreign/gifload.c:178 -msgid "Image is defective, decoding aborted" +#: libvips/foreign/spngsave.c:914 +msgid "save image to buffer as PNG" msgstr "" -#: ../libvips/foreign/gifload.c:181 -msgid "Image EOF detected, before image complete" +#: libvips/foreign/svgload.c:626 libvips/foreign/svgload.c:644 +msgid "SVG rendering failed" msgstr "" -#: ../libvips/foreign/gifload.c:184 -msgid "Unknown error" +#: libvips/foreign/svgload.c:700 +msgid "load SVG with rsvg" msgstr "" -#: ../libvips/foreign/gifload.c:371 -msgid "pixel value out of range" +#: libvips/foreign/svgload.c:718 +msgid "Render at this DPI" msgstr "" -#: ../libvips/foreign/gifload.c:411 -msgid "frame is outside image area" +#: libvips/foreign/svgload.c:725 +msgid "Scale output by this factor" msgstr "" -#: ../libvips/foreign/gifload.c:662 ../libvips/foreign/gifload.c:711 -msgid "too few frames in GIF file" +#: libvips/foreign/svgload.c:733 +msgid "Allow SVG of any size" msgstr "" -#: ../libvips/foreign/gifload.c:809 ../libvips/foreign/gifload.c:884 -#: ../libvips/foreign/gifload.c:971 -msgid "load GIF with giflib" +#: libvips/foreign/svgload.c:827 +msgid "load svg from source" msgstr "" -#: ../libvips/foreign/magick7load.c:366 -msgid "load with ImageMagick7" +#: libvips/foreign/tiff2vips.c:480 libvips/foreign/tiff2vips.c:498 +#, c-format +msgid "required field %d missing" msgstr "" -#: ../libvips/foreign/magick7load.c:419 -#, c-format -msgid "Magick: %s %s" +#: libvips/foreign/tiff2vips.c:540 +msgid "unknown resolution unit" msgstr "" -#: ../libvips/foreign/magick7load.c:474 +#: libvips/foreign/tiff2vips.c:680 #, c-format -msgid "unsupported bit depth %zd" +msgid "bad page number %d" msgstr "" -#: ../libvips/foreign/magick7load.c:506 ../libvips/foreign/magick2vips.c:387 +#: libvips/foreign/tiff2vips.c:690 #, c-format -msgid "unsupported colorspace %d" -msgstr "unsupported colourspace %d" +msgid "bad number of pages %d" +msgstr "" -#: ../libvips/foreign/magick7load.c:797 -msgid "load file with ImageMagick7" +#: libvips/foreign/tiff2vips.c:718 libvips/foreign/tiff2vips.c:760 +#: libvips/iofuncs/source.c:812 +msgid "read error" msgstr "" -#: ../libvips/foreign/magick7load.c:894 -msgid "load buffer with ImageMagick7" +#: libvips/foreign/tiff2vips.c:802 +#, c-format +msgid "TIFF does not contain page %d" msgstr "" -#: ../libvips/foreign/openslide2vips.c:195 -msgid "invalid associated image name" +#: libvips/foreign/tiff2vips.c:812 +msgid "no SUBIFD tag" msgstr "" -#: ../libvips/foreign/openslide2vips.c:239 -msgid "specify only one of level or associated image" +#: libvips/foreign/tiff2vips.c:818 +#, c-format +msgid "subifd %d out of range, only 0-%d available" msgstr "" -#: ../libvips/foreign/openslide2vips.c:275 -msgid "unsupported slide format" +#: libvips/foreign/tiff2vips.c:826 +msgid "subdirectory unreadable" msgstr "" -#: ../libvips/foreign/openslide2vips.c:282 +#: libvips/foreign/tiff2vips.c:867 #, c-format -msgid "opening slide: %s" +msgid "not %d bands" msgstr "" -#: ../libvips/foreign/openslide2vips.c:289 -msgid "invalid slide level" +#: libvips/foreign/tiff2vips.c:880 +#, c-format +msgid "not at least %d samples per pixel" msgstr "" -#: ../libvips/foreign/openslide2vips.c:371 -#, c-format -msgid "getting dimensions: %s" +#: libvips/foreign/tiff2vips.c:895 +msgid "samples_per_pixel not a whole number of bytes" msgstr "" -#: ../libvips/foreign/openslide2vips.c:378 -msgid "image dimensions overflow int" +#: libvips/foreign/tiff2vips.c:908 +#, c-format +msgid "not photometric interpretation %d" msgstr "" -#: ../libvips/foreign/openslide2vips.c:505 +#: libvips/foreign/tiff2vips.c:920 #, c-format -msgid "reading region: %s" +msgid "not %d bits per sample" msgstr "" -#: ../libvips/foreign/openslide2vips.c:587 +#: libvips/foreign/tiff2vips.c:936 #, c-format -msgid "reading associated image: %s" +msgid "%d bits per sample palette image not supported" msgstr "" -#: ../libvips/foreign/exif.c:158 -msgid "unable to init exif" +#: libvips/foreign/tiff2vips.c:995 +msgid "unsupported tiff image type\n" msgstr "" -#: ../libvips/foreign/exif.c:918 ../libvips/foreign/exif.c:928 -#: ../libvips/foreign/exif.c:933 +#: libvips/foreign/tiff2vips.c:1603 +msgid "bad colormap" +msgstr "bad colourmap" + +#: libvips/foreign/tiff2vips.c:2330 #, c-format -msgid "bad exif meta \"%s\"" +msgid "decompress error tile %d x %d" msgstr "" -#: ../libvips/foreign/exif.c:1097 -msgid "error saving EXIF" +#: libvips/foreign/tiff2vips.c:2608 +msgid "tiled separate planes not supported" msgstr "" -#: ../libvips/foreign/fitssave.c:129 -msgid "save image to fits file" +#: libvips/foreign/tiff2vips.c:2627 libvips/foreign/tiff2vips.c:2910 +#: libvips/foreign/tiff2vips.c:3034 +msgid "unsupported tiff image type" msgstr "" -#: ../libvips/foreign/pdfload.c:189 +#: libvips/foreign/tiff2vips.c:2761 #, c-format -msgid "unable to load page %d" +msgid "out of order read -- at line %d, but line %d requested" msgstr "" -#: ../libvips/foreign/pdfload.c:281 -msgid "pages out of range" +#: libvips/foreign/tiff2vips.c:3070 +msgid "subsampled images not supported" msgstr "" -#: ../libvips/foreign/pdfload.c:459 -msgid "load PDF with libpoppler" +#: libvips/foreign/tiff2vips.c:3082 +msgid "not SGI-compressed LOGLUV" msgstr "" -#: ../libvips/foreign/pdfload.c:483 ../libvips/foreign/svgload.c:284 -msgid "Render at this DPI" +#: libvips/foreign/tiff2vips.c:3099 +msgid "width/height out of range" msgstr "" -#: ../libvips/foreign/pdfload.c:490 ../libvips/foreign/svgload.c:291 -msgid "Scale output by this factor" +#: libvips/foreign/tiff2vips.c:3108 +msgid "samples out of range" msgstr "" -#: ../libvips/foreign/magick2vips.c:293 -#, c-format -msgid "unsupported image type %d" +#: libvips/foreign/tiff2vips.c:3194 libvips/foreign/tiff2vips.c:3222 +msgid "tile size out of range" msgstr "" -#: ../libvips/foreign/magick2vips.c:355 +#: libvips/foreign/tiff2vips.c:3414 #, c-format -msgid "unsupported bit depth %d" +msgid "page %d differs from page %d" msgstr "" -#: ../libvips/foreign/magick2vips.c:753 -#, c-format -msgid "" -"unable to read file \"%s\"\n" -"libMagick error: %s %s" +#: libvips/foreign/tiff.c:207 libvips/foreign/tiff.c:222 +msgid "unable to open source for input" msgstr "" -#: ../libvips/foreign/magick2vips.c:792 -#, c-format -msgid "" -"unable to ping file \"%s\"\n" -"libMagick error: %s %s" +#: libvips/foreign/tiff.c:330 libvips/foreign/tiff.c:345 +msgid "unable to open target for output" msgstr "" -#: ../libvips/foreign/magick2vips.c:804 ../libvips/foreign/magick2vips.c:880 -msgid "bad image size" +#: libvips/foreign/tiffload.c:183 +msgid "load tiff" msgstr "" -#: ../libvips/foreign/magick2vips.c:835 -#, c-format -msgid "" -"unable to read buffer\n" -"libMagick error: %s %s" +#: libvips/foreign/tiffload.c:211 +msgid "Rotate image using orientation tag" msgstr "" -#: ../libvips/foreign/magick2vips.c:869 -#, c-format -msgid "" -"unable to ping blob\n" -"libMagick error: %s %s" +#: libvips/foreign/tiffload.c:217 +msgid "subifd" msgstr "" -#: ../libvips/foreign/fits.c:263 -msgid "dimensions above 3 must be size 1" +#: libvips/foreign/tiffload.c:218 +msgid "Subifd index" msgstr "" -#: ../libvips/foreign/fits.c:279 -#, c-format -msgid "bad number of axis %d" +#: libvips/foreign/tiffload.c:294 +msgid "load tiff from source" msgstr "" -#: ../libvips/foreign/fits.c:295 -#, c-format -msgid "unsupported bitpix %d\n" +#: libvips/foreign/tiffload.c:374 +msgid "load tiff from file" msgstr "" -#: ../libvips/foreign/fits.c:612 ../libvips/iofuncs/vips.c:191 -#, c-format -msgid "unable to write to \"%s\"" +#: libvips/foreign/tiffload.c:454 +msgid "load tiff from buffer" msgstr "" -#: ../libvips/foreign/fits.c:673 -#, c-format -msgid "unsupported BandFmt %d\n" +#: libvips/foreign/tiffsave.c:248 +msgid "save image as tiff" msgstr "" -#: ../libvips/foreign/openslideload.c:167 -msgid "load file with OpenSlide" +#: libvips/foreign/tiffsave.c:258 +msgid "Compression for this file" msgstr "" -#: ../libvips/foreign/openslideload.c:194 -msgid "Level" +#: libvips/foreign/tiffsave.c:272 +msgid "Predictor" msgstr "" -#: ../libvips/foreign/openslideload.c:195 -msgid "Load this level from the file" +#: libvips/foreign/tiffsave.c:273 +msgid "Compression prediction" msgstr "" -#: ../libvips/foreign/openslideload.c:201 -msgid "Autocrop" +#: libvips/foreign/tiffsave.c:280 +msgid "Tile" msgstr "" -#: ../libvips/foreign/openslideload.c:202 -msgid "Crop to image bounds" +#: libvips/foreign/tiffsave.c:281 +msgid "Write a tiled tiff" msgstr "" -#: ../libvips/foreign/openslideload.c:208 -msgid "Associated" +#: libvips/foreign/tiffsave.c:301 +msgid "Pyramid" msgstr "" -#: ../libvips/foreign/openslideload.c:209 -msgid "Load this associated image" +#: libvips/foreign/tiffsave.c:302 +msgid "Write a pyramidal tiff" msgstr "" -#: ../libvips/foreign/rawload.c:108 -msgid "load raw data from a file" +#: libvips/foreign/tiffsave.c:308 +msgid "Miniswhite" msgstr "" -#: ../libvips/foreign/rawload.c:144 ../libvips/iofuncs/image.c:1228 -msgid "Size of header" +#: libvips/foreign/tiffsave.c:309 +msgid "Use 0 for white in 1-bit images" msgstr "" -#: ../libvips/foreign/rawload.c:145 ../libvips/iofuncs/image.c:1229 -msgid "Offset in bytes from start of file" +#: libvips/foreign/tiffsave.c:316 +msgid "Write as a 1, 2, 4 or 8 bit image" msgstr "" -#: ../libvips/foreign/jpeg2vips.c:187 -#, c-format -msgid "read gave %ld warnings" +#: libvips/foreign/tiffsave.c:322 libvips/foreign/tiffsave.c:323 +msgid "Resolution unit" msgstr "" -#: ../libvips/foreign/tiffsave.c:172 ../libvips/foreign/tiffsave.c:358 -msgid "save image to tiff file" +#: libvips/foreign/tiffsave.c:343 +msgid "Bigtiff" msgstr "" -#: ../libvips/foreign/tiffsave.c:182 -msgid "Compression for this file" +#: libvips/foreign/tiffsave.c:344 +msgid "Write a bigtiff image" msgstr "" -#: ../libvips/foreign/tiffsave.c:189 ../libvips/foreign/webpsave.c:115 -#: ../libvips/foreign/jpegsave.c:149 -msgid "Q" +#: libvips/foreign/tiffsave.c:351 +msgid "Write a properties document to IMAGEDESCRIPTION" msgstr "" -#: ../libvips/foreign/tiffsave.c:190 ../libvips/foreign/webpsave.c:116 -#: ../libvips/foreign/jpegsave.c:150 -msgid "Q factor" +#: libvips/foreign/tiffsave.c:365 +msgid "Deflate (1-9, default 6) or ZSTD (1-22, default 9) compression level" msgstr "" -#: ../libvips/foreign/tiffsave.c:196 -msgid "predictor" +#: libvips/foreign/tiffsave.c:372 +msgid "Enable WEBP lossless mode" msgstr "" -#: ../libvips/foreign/tiffsave.c:197 -msgid "Compression prediction" +#: libvips/foreign/tiffsave.c:385 +msgid "Sub-IFD" msgstr "" -#: ../libvips/foreign/tiffsave.c:204 -msgid "profile" +#: libvips/foreign/tiffsave.c:386 +msgid "Save pyr layers as sub-IFDs" msgstr "" -#: ../libvips/foreign/tiffsave.c:211 -msgid "Tile" +#: libvips/foreign/tiffsave.c:392 +msgid "Premultiply" msgstr "" -#: ../libvips/foreign/tiffsave.c:212 -msgid "Write a tiled tiff" +#: libvips/foreign/tiffsave.c:393 +msgid "Save with premultiplied alpha" msgstr "" -#: ../libvips/foreign/tiffsave.c:232 -msgid "Pyramid" +#: libvips/foreign/tiffsave.c:399 +msgid "RGB JPEG" msgstr "" -#: ../libvips/foreign/tiffsave.c:233 -msgid "Write a pyramidal tiff" +#: libvips/foreign/tiffsave.c:400 +msgid "Output RGB JPEG rather than YCbCr" msgstr "" -#: ../libvips/foreign/tiffsave.c:240 +#: libvips/foreign/tiffsave.c:407 msgid "Squash images down to 1 bit" msgstr "" -#: ../libvips/foreign/tiffsave.c:246 -msgid "Miniswhite" +#: libvips/foreign/tiffsave.c:470 +msgid "save image to tiff target" msgstr "" -#: ../libvips/foreign/tiffsave.c:247 -msgid "Use 0 for white in 1-bit images" +#: libvips/foreign/tiffsave.c:523 +msgid "save image to tiff file" msgstr "" -#: ../libvips/foreign/tiffsave.c:253 ../libvips/foreign/tiffsave.c:254 -msgid "Resolution unit" +#: libvips/foreign/tiffsave.c:584 +msgid "save image to tiff buffer" msgstr "" -#: ../libvips/foreign/tiffsave.c:274 -msgid "Bigtiff" +#: libvips/foreign/vips2jpeg.c:176 +#, c-format +msgid "%s" msgstr "" -#: ../libvips/foreign/tiffsave.c:275 -msgid "Write a bigtiff image" +#: libvips/foreign/vips2jpeg.c:273 +#, c-format +msgid "field \"%s\" is too large for a single JPEG marker, ignoring" msgstr "" -#: ../libvips/foreign/tiffsave.c:281 -msgid "RGB JPEG" +#: libvips/foreign/vips2jpeg.c:1059 +msgid "libvips built without JPEG support" msgstr "" -#: ../libvips/foreign/tiffsave.c:282 -msgid "Output RGB JPEG rather than YCbCr" -msgstr "" +#: libvips/foreign/vips2magick.c:319 +#, fuzzy +msgid "unsupported image format" +msgstr "unsupported colour type" -#: ../libvips/foreign/tiffsave.c:288 ../libvips/foreign/dzsave.c:2193 -msgid "Properties" +#: libvips/foreign/vips2magick.c:349 +msgid "unsupported number of image bands" msgstr "" -#: ../libvips/foreign/tiffsave.c:289 -msgid "Write a properties document to IMAGEDESCRIPTION" +#: libvips/foreign/vips2magick.c:464 +msgid "save with ImageMagick" msgstr "" -#: ../libvips/foreign/tiffsave.c:433 -msgid "save image to tiff buffer" +#: libvips/foreign/vips2magick.c:490 +msgid "Quality to use" msgstr "" -#: ../libvips/foreign/svgload.c:207 -msgid "SVG rendering failed" +#: libvips/foreign/vips2magick.c:496 +msgid "Optimize_gif_frames" msgstr "" -#: ../libvips/foreign/svgload.c:274 -msgid "load SVG with rsvg" +#: libvips/foreign/vips2magick.c:497 +msgid "Apply GIF frames optimization" msgstr "" -#: ../libvips/foreign/radsave.c:97 -msgid "save Radiance" +#: libvips/foreign/vips2magick.c:503 +msgid "Optimize_gif_transparency" msgstr "" -#: ../libvips/foreign/radsave.c:150 -msgid "save image to Radiance file" +#: libvips/foreign/vips2magick.c:504 +msgid "Apply GIF transparency optimization" msgstr "" -#: ../libvips/foreign/radsave.c:213 -msgid "save image to Radiance buffer" +#: libvips/foreign/vips2magick.c:574 +msgid "save file with ImageMagick" msgstr "" -#: ../libvips/foreign/dzsave.c:181 ../libvips/iofuncs/vips.c:712 -#, c-format -msgid "unable to set property \"%s\" to value \"%s\"." +#: libvips/foreign/vips2magick.c:646 +msgid "save image to magick buffer" msgstr "" -#: ../libvips/foreign/dzsave.c:196 -#, c-format -msgid "unable to set create node \"%s\"" +#: libvips/foreign/vips2magick.c:677 +msgid "save bmp image with ImageMagick" msgstr "" -#: ../libvips/foreign/dzsave.c:252 ../libvips/foreign/dzsave.c:257 -#: ../libvips/foreign/dzsave.c:284 ../libvips/iofuncs/vips.c:849 -#: ../libvips/iofuncs/vips.c:856 -msgid "xml save error" +#: libvips/foreign/vips2magick.c:710 +msgid "save bmp image to magick buffer" msgstr "" -#: ../libvips/foreign/dzsave.c:351 ../libvips/foreign/dzsave.c:357 -msgid "unable to close stream" +#: libvips/foreign/vips2magick.c:743 +msgid "save gif image with ImageMagick" msgstr "" -#: ../libvips/foreign/dzsave.c:1395 -msgid "too many files in zip" +#: libvips/foreign/vips2magick.c:776 +msgid "save gif image to magick buffer" msgstr "" -#: ../libvips/foreign/dzsave.c:1405 -msgid "output file too large" +#: libvips/foreign/vips2tiff.c:1449 +msgid "can only pyramid LABQ and non-complex images" msgstr "" -#: ../libvips/foreign/dzsave.c:1762 -msgid "overlap too large" +#: libvips/foreign/vips2tiff.c:1472 +msgid "tile size not a multiple of 16" msgstr "" -#: ../libvips/foreign/dzsave.c:1904 -#, c-format -msgid "output directory %s/%s_files exists" +#: libvips/foreign/vips2tiff.c:1830 libvips/foreign/vips2tiff.c:2019 +msgid "TIFF write tile failed" msgstr "" -#: ../libvips/foreign/dzsave.c:1932 ../libvips/iofuncs/util.c:1625 -#, c-format -msgid "unable to make temporary file %s" +#: libvips/foreign/vipsload.c:126 +msgid "no filename associated with source" msgstr "" -#: ../libvips/foreign/dzsave.c:2002 -msgid "deflate-level not supported by libgsf, using default compression" +#: libvips/foreign/vipsload.c:157 +msgid "load vips base class" msgstr "" -#: ../libvips/foreign/dzsave.c:2117 -msgid "save image to deep zoom format" +#: libvips/foreign/vipsload.c:228 +msgid "load vips from file" msgstr "" -#: ../libvips/foreign/dzsave.c:2127 -msgid "Base name" +#: libvips/foreign/vipsload.c:303 +msgid "load vips from source" msgstr "" -#: ../libvips/foreign/dzsave.c:2128 -msgid "Base name to save to" +#: libvips/foreign/vipspng.c:450 +msgid "unsupported color type" +msgstr "unsupported colour type" + +#: libvips/foreign/vipspng.c:564 +msgid "unable to read PNG header" msgstr "" -#: ../libvips/foreign/dzsave.c:2134 -msgid "Layout" +#: libvips/foreign/vipspng.c:756 +msgid "libpng read error" msgstr "" -#: ../libvips/foreign/dzsave.c:2135 -msgid "Directory layout" +#: libvips/foreign/vipspng.c:1113 +msgid "compress should be in [0,9]" msgstr "" -#: ../libvips/foreign/dzsave.c:2142 -msgid "suffix" +#: libvips/foreign/vipspng.c:1141 +#, c-format +msgid "can't save %d band image as png" msgstr "" -#: ../libvips/foreign/dzsave.c:2143 -msgid "Filename suffix for tiles" +#: libvips/foreign/vipspng.c:1349 +#, c-format +msgid "unable to write to target %s" msgstr "" -#: ../libvips/foreign/dzsave.c:2149 -msgid "Overlap" +#: libvips/foreign/vipssave.c:114 +msgid "no filename associated with target" msgstr "" -#: ../libvips/foreign/dzsave.c:2150 -msgid "Tile overlap in pixels" +#: libvips/foreign/vipssave.c:141 +msgid "save vips base class" msgstr "" -#: ../libvips/foreign/dzsave.c:2156 -msgid "Tile size" +#: libvips/foreign/vipssave.c:193 +msgid "save image to file in vips format" msgstr "" -#: ../libvips/foreign/dzsave.c:2157 -msgid "Tile size in pixels" +#: libvips/foreign/vipssave.c:249 +msgid "save image to target in vips format" msgstr "" -#: ../libvips/foreign/dzsave.c:2164 -msgid "Pyramid depth" +#: libvips/foreign/webp2vips.c:407 +msgid "unable to parse image" msgstr "" -#: ../libvips/foreign/dzsave.c:2171 -msgid "Center" +#: libvips/foreign/webp2vips.c:595 +msgid "unable to loop through frames" msgstr "" -#: ../libvips/foreign/dzsave.c:2172 -msgid "Center image in tile" +#: libvips/foreign/webpload.c:164 +msgid "load webp" msgstr "" -#: ../libvips/foreign/dzsave.c:2179 -msgid "Rotate image during save" +#: libvips/foreign/webpload.c:258 +msgid "load webp from source" msgstr "" -#: ../libvips/foreign/dzsave.c:2185 -msgid "Container" +#: libvips/foreign/webpload.c:338 +msgid "load webp from file" msgstr "" -#: ../libvips/foreign/dzsave.c:2186 -msgid "Pyramid container type" +#: libvips/foreign/webpload.c:418 +msgid "load webp from buffer" msgstr "" -#: ../libvips/foreign/dzsave.c:2194 -msgid "Write a properties file to the output directory" +#: libvips/foreign/webpsave.c:248 +msgid "picture version error" msgstr "" -#: ../libvips/foreign/dzsave.c:2201 -msgid "ZIP deflate compression level" +#: libvips/foreign/webpsave.c:290 +msgid "picture memory error" msgstr "" -#: ../libvips/foreign/dzsave.c:2210 -msgid "Directory name" +#: libvips/foreign/webpsave.c:315 +msgid "anim add error" msgstr "" -#: ../libvips/foreign/dzsave.c:2211 -msgid "Directory name to save to" +#: libvips/foreign/webpsave.c:332 +msgid "unable to encode" msgstr "" -#: ../libvips/foreign/dzsave.c:2315 -msgid "save image to deepzoom file" +#: libvips/foreign/webpsave.c:428 +msgid "chunk add error" msgstr "" -#: ../libvips/foreign/dzsave.c:2377 ../libvips/iofuncs/image.c:2590 -#: ../libvips/iofuncs/image.c:2592 ../libvips/iofuncs/memory.c:309 -#: ../libvips/iofuncs/memory.c:311 -#, c-format -msgid "out of memory --- size == %dMB" +#: libvips/foreign/webpsave.c:534 libvips/foreign/webpsave.c:575 +msgid "mux error" msgstr "" -#: ../libvips/foreign/dzsave.c:2402 -msgid "save image to dz buffer" +#: libvips/foreign/webpsave.c:595 libvips/foreign/webpsave.c:605 +#: libvips/foreign/webpsave.c:644 +msgid "config version error" msgstr "" -#: ../libvips/foreign/radload.c:122 -msgid "load a Radiance image from a file" +#: libvips/foreign/webpsave.c:625 +msgid "invalid configuration" msgstr "" -#: ../libvips/foreign/openexrload.c:128 -msgid "load an OpenEXR image" +#: libvips/foreign/webpsave.c:655 +msgid "unable to init animation" msgstr "" -#: ../libvips/foreign/vipssave.c:104 -msgid "save image to vips file" +#: libvips/foreign/webpsave.c:698 +msgid "anim close error" msgstr "" -#: ../libvips/foreign/webpsave.c:107 -msgid "save webp" +#: libvips/foreign/webpsave.c:703 +msgid "anim build error" msgstr "" -#: ../libvips/foreign/webpsave.c:122 -msgid "lossless" +#: libvips/foreign/webpsave.c:711 libvips/mosaicing/lrmerge.c:309 +#: libvips/mosaicing/tbmerge.c:187 libvips/mosaicing/tbmerge.c:262 +#: libvips/mosaicing/tbmerge.c:594 +msgid "internal error" msgstr "" -#: ../libvips/foreign/webpsave.c:123 -msgid "enable lossless compression" +#: libvips/foreign/webpsave.c:817 +msgid "save as WebP" msgstr "" -#: ../libvips/foreign/webpsave.c:129 -msgid "preset" +#: libvips/foreign/webpsave.c:840 +msgid "Preset" msgstr "" -#: ../libvips/foreign/webpsave.c:130 +#: libvips/foreign/webpsave.c:841 msgid "Preset for lossy compression" msgstr "" -#: ../libvips/foreign/webpsave.c:137 +#: libvips/foreign/webpsave.c:848 msgid "Smart subsampling" msgstr "" -#: ../libvips/foreign/webpsave.c:138 +#: libvips/foreign/webpsave.c:849 msgid "Enable high quality chroma subsampling" msgstr "" -#: ../libvips/foreign/webpsave.c:144 +#: libvips/foreign/webpsave.c:855 msgid "Near lossless" msgstr "" -#: ../libvips/foreign/webpsave.c:145 +#: libvips/foreign/webpsave.c:856 msgid "Enable preprocessing in lossless mode (uses Q)" msgstr "" -#: ../libvips/foreign/webpsave.c:151 +#: libvips/foreign/webpsave.c:862 msgid "Alpha quality" msgstr "" -#: ../libvips/foreign/webpsave.c:152 +#: libvips/foreign/webpsave.c:863 msgid "Change alpha plane fidelity for lossy compression" msgstr "" -#: ../libvips/foreign/webpsave.c:210 -msgid "save image to webp file" +#: libvips/foreign/webpsave.c:869 +msgid "Minimise size" msgstr "" -#: ../libvips/foreign/webpsave.c:281 -msgid "save image to webp buffer" +#: libvips/foreign/webpsave.c:870 +msgid "Optimise for minimum size" msgstr "" -#: ../libvips/foreign/webpsave.c:330 ../libvips/foreign/jpegsave.c:386 -msgid "error writing output" +#: libvips/foreign/webpsave.c:876 +msgid "Minimum keyframe spacing" msgstr "" -#: ../libvips/foreign/webpsave.c:346 -msgid "save image to webp mime" +#: libvips/foreign/webpsave.c:877 +msgid "Minimum number of frames between key frames" msgstr "" -#: ../libvips/foreign/radiance.c:685 -msgid "end of file" +#: libvips/foreign/webpsave.c:883 +msgid "Maximum keyframe spacing" msgstr "" -#: ../libvips/foreign/radiance.c:773 -msgid "scanline length mismatch" +#: libvips/foreign/webpsave.c:884 +msgid "Maximum number of frames between key frames" msgstr "" -#: ../libvips/foreign/radiance.c:790 -msgid "overrun" +#: libvips/foreign/webpsave.c:891 libvips/foreign/webpsave.c:912 +msgid "Level of CPU effort to reduce file size" msgstr "" -#: ../libvips/foreign/radiance.c:1040 -msgid "error reading radiance header" +#: libvips/foreign/webpsave.c:897 +msgid "Target size" msgstr "" -#: ../libvips/foreign/radiance.c:1057 -msgid "image size out of bounds" +#: libvips/foreign/webpsave.c:898 +msgid "Desired target size in bytes" msgstr "" -#: ../libvips/foreign/radiance.c:1125 -#, c-format -msgid "read error line %d" +#: libvips/foreign/webpsave.c:904 +msgid "Passes" msgstr "" -#: ../libvips/foreign/rawsave.c:139 -msgid "save image to raw file" +#: libvips/foreign/webpsave.c:905 +msgid "Number of entropy-analysis passes (in [1..10])" msgstr "" -#: ../libvips/foreign/rawsave.c:245 -msgid "write raw image to file descriptor" +#: libvips/foreign/webpsave.c:911 +msgid "Reduction effort" msgstr "" -#: ../libvips/foreign/rawsave.c:251 -msgid "File descriptor" +#: libvips/foreign/webpsave.c:918 +msgid "Mixed encoding" msgstr "" -#: ../libvips/foreign/rawsave.c:252 -msgid "File descriptor to write to" +#: libvips/foreign/webpsave.c:919 +msgid "Allow mixed encoding (might reduce file size)" msgstr "" -#: ../libvips/foreign/jpegsave.c:139 -msgid "save jpeg" +#: libvips/foreign/webpsave.c:925 +msgid "Smart deblocking" msgstr "" -#: ../libvips/foreign/jpegsave.c:163 -msgid "Optimize_coding" +#: libvips/foreign/webpsave.c:926 +msgid "Enable auto-adjusting of the deblocking filter" msgstr "" -#: ../libvips/foreign/jpegsave.c:164 -msgid "Compute optimal Huffman coding tables" +#: libvips/foreign/webpsave.c:1156 +msgid "save image to webp mime" msgstr "" -#: ../libvips/foreign/jpegsave.c:171 -msgid "Generate an interlaced (progressive) jpeg" +#: libvips/freqfilt/freqfilt.c:94 +msgid "frequency-domain filter operations" msgstr "" -#: ../libvips/foreign/jpegsave.c:177 -msgid "No subsample" +#: libvips/freqfilt/freqmult.c:126 +msgid "frequency-domain filtering" msgstr "" -#: ../libvips/foreign/jpegsave.c:178 -msgid "Disable chroma subsample" +#: libvips/freqfilt/freqmult.c:131 +msgid "Input mask image" msgstr "" -#: ../libvips/foreign/jpegsave.c:184 -msgid "Trellis quantisation" +#: libvips/freqfilt/fwfft.c:145 libvips/freqfilt/fwfft.c:266 +#: libvips/freqfilt/invfft.c:124 libvips/freqfilt/invfft.c:203 +msgid "unable to create transform plan" msgstr "" -#: ../libvips/foreign/jpegsave.c:185 -msgid "Apply trellis quantisation to each 8x8 block" +#: libvips/freqfilt/fwfft.c:351 +msgid "forward FFT" msgstr "" -#: ../libvips/foreign/jpegsave.c:191 -msgid "Overshoot de-ringing" +#: libvips/freqfilt/invfft.c:263 +msgid "inverse FFT" msgstr "" -#: ../libvips/foreign/jpegsave.c:192 -msgid "Apply overshooting to samples with extreme values" +#: libvips/freqfilt/invfft.c:267 +msgid "Real" msgstr "" -#: ../libvips/foreign/jpegsave.c:198 -msgid "Optimize scans" +#: libvips/freqfilt/invfft.c:268 +msgid "Output only the real part of the transform" msgstr "" -#: ../libvips/foreign/jpegsave.c:199 -msgid "Split the spectrum of DCT coefficients into separate scans" +#: libvips/freqfilt/phasecor.c:107 +msgid "calculate phase correlation" msgstr "" -#: ../libvips/foreign/jpegsave.c:205 -msgid "Quantization table" +#: libvips/freqfilt/spectrum.c:100 +msgid "make displayable power spectrum" msgstr "" -#: ../libvips/foreign/jpegsave.c:206 -msgid "Use predefined quantization table with given index" +#: libvips/histogram/case.c:164 +msgid "bad number of cases" msgstr "" -#: ../libvips/foreign/jpegsave.c:264 -msgid "save image to jpeg file" +#: libvips/histogram/case.c:169 +msgid "index image not 1-band" msgstr "" -#: ../libvips/foreign/jpegsave.c:336 -msgid "save image to jpeg buffer" +#: libvips/histogram/case.c:233 +msgid "use pixel values to pick cases from an array of images" msgstr "" -#: ../libvips/foreign/jpegsave.c:402 -msgid "save image to jpeg mime" +#: libvips/histogram/case.c:245 +msgid "Cases" msgstr "" -#: ../libvips/foreign/analyze2vips.c:311 -msgid "header file size incorrect" +#: libvips/histogram/case.c:246 +msgid "Array of case images" msgstr "" -#: ../libvips/foreign/analyze2vips.c:356 -msgid "header size incorrect" +#: libvips/histogram/hist_cum.c:158 +msgid "form cumulative histogram" msgstr "" -#: ../libvips/foreign/analyze2vips.c:374 -#, c-format -msgid "%d-dimensional images not supported" +#: libvips/histogram/hist_entropy.c:107 +msgid "estimate image entropy" msgstr "" -#: ../libvips/foreign/analyze2vips.c:427 -#, c-format -msgid "datatype %d not supported" +#: libvips/histogram/hist_entropy.c:112 +#: libvips/histogram/hist_ismonotonic.c:119 +msgid "Input histogram image" msgstr "" -#: ../libvips/foreign/matrixload.c:137 -msgid "load matrix from file" +#: libvips/histogram/hist_equal.c:110 +msgid "histogram equalisation" msgstr "" -#: ../libvips/foreign/jpegload.c:109 -#, c-format -msgid "bad shrink factor %d" +#: libvips/histogram/hist_equal.c:127 +msgid "Equalise with this band" msgstr "" -#: ../libvips/foreign/jpegload.c:131 -msgid "load jpeg" +#: libvips/histogram/hist_ismonotonic.c:114 +msgid "test for monotonicity" msgstr "" -#: ../libvips/foreign/jpegload.c:144 ../libvips/foreign/tiffload.c:113 -msgid "Autorotate" +#: libvips/histogram/hist_ismonotonic.c:124 +msgid "Monotonic" msgstr "" -#: ../libvips/foreign/jpegload.c:145 -msgid "Rotate image using exif orientation" +#: libvips/histogram/hist_ismonotonic.c:125 +msgid "true if in is monotonic" msgstr "" -#: ../libvips/foreign/jpegload.c:219 -msgid "load jpeg from file" +#: libvips/histogram/hist_local.c:304 libvips/histogram/stdif.c:236 +#: libvips/morphology/rank.c:491 +msgid "window too large" msgstr "" -#: ../libvips/foreign/jpegload.c:304 -msgid "load jpeg from buffer" +#: libvips/histogram/hist_local.c:355 +msgid "local histogram equalisation" msgstr "" -#: ../libvips/foreign/analyzeload.c:119 -msgid "load an Analyze6 image" +#: libvips/histogram/hist_local.c:374 libvips/histogram/stdif.c:309 +#: libvips/morphology/rank.c:571 +msgid "Window width in pixels" msgstr "" -#: ../libvips/foreign/vips2tiff.c:470 -msgid "rounding up IPCT data length" +#: libvips/histogram/hist_local.c:381 libvips/histogram/stdif.c:316 +#: libvips/morphology/rank.c:578 +msgid "Window height in pixels" msgstr "" -#: ../libvips/foreign/vips2tiff.c:948 -#, c-format -msgid "image height %d is not a factor of page-height %d" +#: libvips/histogram/hist_local.c:387 +msgid "Max slope" msgstr "" -#: ../libvips/foreign/vips2tiff.c:964 -msgid "can't pyramid multi page images --- disabling pyramid" +#: libvips/histogram/hist_local.c:388 +msgid "Maximum slope (CLAHE)" msgstr "" -#: ../libvips/foreign/vips2tiff.c:977 -msgid "tile size not a multiple of 16" +#: libvips/histogram/hist_match.c:154 +msgid "match two histograms" msgstr "" -#: ../libvips/foreign/vips2tiff.c:988 -msgid "can only pyramid LABQ and non-complex images" +#: libvips/histogram/hist_match.c:162 +msgid "Input histogram" msgstr "" -#: ../libvips/foreign/vips2tiff.c:1043 -msgid "image over 4gb, enabling bigtiff" +#: libvips/histogram/hist_match.c:167 libvips/mosaicing/match.c:196 +#: libvips/mosaicing/merge.c:122 libvips/mosaicing/mosaic1.c:498 +#: libvips/mosaicing/mosaic.c:179 +msgid "Reference" msgstr "" -#: ../libvips/foreign/vips2tiff.c:1295 -msgid "TIFF write tile failed" +#: libvips/histogram/hist_match.c:168 +msgid "Reference histogram" msgstr "" -#: ../libvips/foreign/matload.c:121 -msgid "load mat from file" +#: libvips/histogram/hist_norm.c:137 +msgid "normalise histogram" +msgstr "" + +#: libvips/histogram/histogram.c:223 +msgid "histogram operations" +msgstr "" + +#: libvips/histogram/hist_plot.c:329 +msgid "plot histogram" +msgstr "" + +#: libvips/histogram/hist_unary.c:84 +msgid "hist_unary operations" +msgstr "" + +#: libvips/histogram/maplut.c:110 +#, c-format +msgid "%d overflows detected" msgstr "" -#: ../libvips/foreign/vipsload.c:122 -msgid "load vips from file" +#: libvips/histogram/maplut.c:738 +msgid "map an image though a lut" msgstr "" -#: ../libvips/foreign/tiffload.c:96 -msgid "load tiff" +#: libvips/histogram/maplut.c:756 +msgid "LUT" msgstr "" -#: ../libvips/foreign/tiffload.c:100 -msgid "Load this page from the image" +#: libvips/histogram/maplut.c:757 +msgid "Look-up table image" msgstr "" -#: ../libvips/foreign/tiffload.c:114 -msgid "Rotate image using orientation tag" +#: libvips/histogram/maplut.c:763 +msgid "Apply one-band lut to this band of in" msgstr "" -#: ../libvips/foreign/tiffload.c:207 -msgid "load tiff from file" +#: libvips/histogram/percent.c:105 +msgid "find threshold for percent of pixels" msgstr "" -#: ../libvips/foreign/tiffload.c:306 -msgid "load tiff from buffer" +#: libvips/histogram/percent.c:115 +msgid "Percent" msgstr "" -#: ../libvips/freqfilt/spectrum.c:101 -msgid "make displayable power spectrum" +#: libvips/histogram/percent.c:116 +msgid "Percent of pixels" msgstr "" -#: ../libvips/freqfilt/phasecor.c:108 -msgid "calculate phase correlation" +#: libvips/histogram/percent.c:123 +msgid "Threshold above which lie percent of pixels" msgstr "" -#: ../libvips/freqfilt/fwfft.c:137 ../libvips/freqfilt/fwfft.c:252 -#: ../libvips/freqfilt/invfft.c:120 ../libvips/freqfilt/invfft.c:194 -msgid "unable to create transform plan" +#: libvips/histogram/stdif.c:240 +msgid "too many bands" msgstr "" -#: ../libvips/freqfilt/fwfft.c:335 -msgid "forward FFT" +#: libvips/histogram/stdif.c:290 +msgid "statistical difference" msgstr "" -#: ../libvips/freqfilt/freqmult.c:127 -msgid "frequency-domain filtering" +#: libvips/histogram/stdif.c:322 +msgid "Mean weight" msgstr "" -#: ../libvips/freqfilt/freqmult.c:131 -msgid "mask" +#: libvips/histogram/stdif.c:323 +msgid "Weight of new mean" msgstr "" -#: ../libvips/freqfilt/freqmult.c:132 -msgid "Input mask image" +#: libvips/histogram/stdif.c:330 +msgid "New mean" msgstr "" -#: ../libvips/freqfilt/freqfilt.c:94 -msgid "frequency-domain filter operations" +#: libvips/histogram/stdif.c:336 +msgid "Deviation weight" msgstr "" -#: ../libvips/freqfilt/invfft.c:252 -msgid "inverse FFT" +#: libvips/histogram/stdif.c:337 +msgid "Weight of new deviation" msgstr "" -#: ../libvips/freqfilt/invfft.c:256 -msgid "Real" +#: libvips/histogram/stdif.c:343 +msgid "Deviation" msgstr "" -#: ../libvips/freqfilt/invfft.c:257 -msgid "Output only the real part of the transform" +#: libvips/histogram/stdif.c:344 +msgid "New deviation" msgstr "" -#: ../libvips/histogram/hist_match.c:154 -msgid "match two histograms" +#: libvips/iofuncs/buf.c:609 +#, c-format +msgid "%zd bytes of binary data" msgstr "" -#: ../libvips/histogram/hist_match.c:162 -msgid "Input histogram" +#: libvips/iofuncs/connection.c:126 +msgid "Descriptor" msgstr "" -#: ../libvips/histogram/hist_match.c:167 ../libvips/mosaicing/merge.c:109 -#: ../libvips/mosaicing/mosaic.c:180 ../libvips/mosaicing/match.c:204 -#: ../libvips/mosaicing/mosaic1.c:489 -msgid "Reference" +#: libvips/iofuncs/connection.c:127 +msgid "File descriptor for read or write" msgstr "" -#: ../libvips/histogram/hist_match.c:168 -msgid "Reference histogram" +#: libvips/iofuncs/connection.c:134 +msgid "Name of file to open" msgstr "" -#: ../libvips/histogram/hist_cum.c:148 -msgid "form cumulative histogram" +#: libvips/iofuncs/error.c:296 +msgid "system error" msgstr "" -#: ../libvips/histogram/hist_equal.c:104 -msgid "histogram equalisation" +#: libvips/iofuncs/error.c:443 +msgid "image must be uncoded" msgstr "" -#: ../libvips/histogram/hist_equal.c:121 -msgid "Equalise with this band" +#: libvips/iofuncs/error.c:471 +msgid "image coding must be 'none' or 'labq'" msgstr "" -#: ../libvips/histogram/stdif.c:236 ../libvips/histogram/hist_local.c:304 -#: ../libvips/morphology/rank.c:354 -msgid "window too large" +#: libvips/iofuncs/error.c:499 +msgid "unknown image coding" msgstr "" -#: ../libvips/histogram/stdif.c:240 -msgid "too many bands" +#: libvips/iofuncs/error.c:524 +#, c-format +msgid "coding '%s' only" msgstr "" -#: ../libvips/histogram/stdif.c:290 -msgid "statistical difference" +#: libvips/iofuncs/error.c:549 +msgid "image must one band" msgstr "" -#: ../libvips/histogram/stdif.c:309 ../libvips/histogram/hist_local.c:371 -#: ../libvips/morphology/rank.c:420 -msgid "Window width in pixels" +#: libvips/iofuncs/error.c:574 +#, c-format +msgid "image must have %d bands" msgstr "" -#: ../libvips/histogram/stdif.c:316 ../libvips/histogram/hist_local.c:378 -#: ../libvips/morphology/rank.c:427 -msgid "Window height in pixels" +#: libvips/iofuncs/error.c:599 +msgid "image must have one or three bands" msgstr "" -#: ../libvips/histogram/stdif.c:322 -msgid "Mean weight" +#: libvips/iofuncs/error.c:625 +#, c-format +msgid "image must have at least %d bands" msgstr "" -#: ../libvips/histogram/stdif.c:323 -msgid "Weight of new mean" +#: libvips/iofuncs/error.c:653 +msgid "images must have the same number of bands, or one must be single-band" msgstr "" -#: ../libvips/histogram/stdif.c:330 -msgid "New mean" +#: libvips/iofuncs/error.c:680 +#, c-format +msgid "image must have 1 or %d bands" msgstr "" -#: ../libvips/histogram/stdif.c:336 -msgid "Deviation weight" +#: libvips/iofuncs/error.c:704 +msgid "image must be non-complex" msgstr "" -#: ../libvips/histogram/stdif.c:337 -msgid "Weight of new deviation" +#: libvips/iofuncs/error.c:728 +msgid "image must be complex" msgstr "" -#: ../libvips/histogram/stdif.c:343 -msgid "Deviation" +#: libvips/iofuncs/error.c:755 +msgid "image must be two-band or complex" msgstr "" -#: ../libvips/histogram/stdif.c:344 -msgid "New deviation" +#: libvips/iofuncs/error.c:781 +#, c-format +msgid "image must be %s" msgstr "" -#: ../libvips/histogram/histogram.c:223 -msgid "histogram operations" +#: libvips/iofuncs/error.c:806 +msgid "image must be integer" msgstr "" -#: ../libvips/histogram/hist_entropy.c:109 -msgid "estimate image entropy" +#: libvips/iofuncs/error.c:831 +msgid "image must be unsigned integer" msgstr "" -#: ../libvips/histogram/hist_entropy.c:114 -#: ../libvips/histogram/hist_ismonotonic.c:118 -msgid "Input histogram image" +#: libvips/iofuncs/error.c:859 +msgid "image must be 8- or 16-bit integer, signed or unsigned" msgstr "" -#: ../libvips/histogram/hist_ismonotonic.c:113 -msgid "test for monotonicity" +#: libvips/iofuncs/error.c:885 +msgid "image must be 8- or 16-bit unsigned integer" msgstr "" -#: ../libvips/histogram/hist_ismonotonic.c:123 -msgid "Monotonic" +#: libvips/iofuncs/error.c:911 +msgid "image must be 8- or 16-bit unsigned integer, or float" msgstr "" -#: ../libvips/histogram/hist_ismonotonic.c:124 -msgid "true if in is monotonic" +#: libvips/iofuncs/error.c:938 +msgid "image must be unsigned int or float" msgstr "" -#: ../libvips/histogram/hist_norm.c:137 -msgid "normalise histogram" +#: libvips/iofuncs/error.c:964 +msgid "images must match in size" msgstr "" -#: ../libvips/histogram/hist_plot.c:338 -msgid "plot histogram" +#: libvips/iofuncs/error.c:990 +msgid "images must be odd and square" msgstr "" -#: ../libvips/histogram/hist_unary.c:85 -msgid "hist_unary operations" +#: libvips/iofuncs/error.c:1016 +msgid "images must have the same number of bands" msgstr "" -#: ../libvips/histogram/hist_local.c:354 -msgid "local histogram equalisation" +#: libvips/iofuncs/error.c:1070 +msgid "images must have the same band format" msgstr "" -#: ../libvips/histogram/hist_local.c:384 -msgid "Max slope" +#: libvips/iofuncs/error.c:1096 +msgid "images must have the same coding" msgstr "" -#: ../libvips/histogram/hist_local.c:385 -msgid "Maximum slope (CLAHE)" +#: libvips/iofuncs/error.c:1119 +#, c-format +msgid "vector must have %d elements" msgstr "" -#: ../libvips/histogram/percent.c:106 -msgid "find threshold for percent of pixels" +#: libvips/iofuncs/error.c:1155 +msgid "vector must have 1 element" msgstr "" -#: ../libvips/histogram/percent.c:116 -msgid "Percent" +#: libvips/iofuncs/error.c:1158 +#, c-format +msgid "vector must have 1 or %d elements" msgstr "" -#: ../libvips/histogram/percent.c:117 -msgid "Percent of pixels" +#: libvips/iofuncs/error.c:1183 +msgid "histograms must have width or height 1" msgstr "" -#: ../libvips/histogram/percent.c:123 -msgid "Threshold" +#: libvips/iofuncs/error.c:1188 +msgid "histograms must have not have more than 65536 elements" msgstr "" -#: ../libvips/histogram/percent.c:124 -msgid "Threshold above which lie percent of pixels" +#: libvips/iofuncs/error.c:1224 +msgid "matrix image too large" msgstr "" -#: ../libvips/histogram/maplut.c:110 -#, c-format -msgid "%d overflows detected" +#: libvips/iofuncs/error.c:1229 +msgid "matrix image must have one band" msgstr "" -#: ../libvips/histogram/maplut.c:688 -msgid "map an image though a lut" +#: libvips/iofuncs/error.c:1263 +msgid "separable matrix images must have width or height 1" msgstr "" -#: ../libvips/histogram/maplut.c:706 -msgid "LUT" +#: libvips/iofuncs/error.c:1289 +msgid "precision must be int or float" msgstr "" -#: ../libvips/histogram/maplut.c:707 -msgid "Look-up table image" +#: libvips/iofuncs/generate.c:696 +msgid "demand hint not set" msgstr "" -#: ../libvips/histogram/maplut.c:712 -msgid "band" +#: libvips/iofuncs/generate.c:715 libvips/iofuncs/generate.c:743 +msgid "generate() called twice" msgstr "" -#: ../libvips/histogram/maplut.c:713 -msgid "apply one-band lut to this band of in" +#: libvips/iofuncs/generate.c:784 libvips/iofuncs/image.c:3235 +#, c-format +msgid "unable to output to a %s image" msgstr "" -#: ../libvips/introspect.c:54 -msgid "dump introspection data" +#: libvips/iofuncs/ginputsource.c:164 libvips/iofuncs/ginputsource.c:229 +#, c-format +msgid "Error while seeking: %s" msgstr "" -#: ../libvips/introspect.c:71 -msgid "- introspect" +#: libvips/iofuncs/ginputsource.c:185 +msgid "Cannot truncate VipsGInputStream" msgstr "" -#: ../libvips/iofuncs/sink.c:106 +#: libvips/iofuncs/ginputsource.c:206 #, c-format -msgid "stop function failed for image \"%s\"" +msgid "Error while reading: %s" msgstr "" -#: ../libvips/iofuncs/sink.c:143 -#, c-format -msgid "start function failed for image \"%s\"" +#: libvips/iofuncs/ginputsource.c:275 +msgid "Stream to wrap" msgstr "" -#: ../libvips/iofuncs/sink.c:176 -msgid "per-thread state for sink" +#: libvips/iofuncs/header.c:1380 +#, c-format +msgid "field \"%s\" not found" msgstr "" -#: ../libvips/iofuncs/type.c:854 +#: libvips/iofuncs/header.c:1614 #, c-format -msgid "unable to convert \"%s\" to int" +msgid "field \"%s\" is of type %s, not %s" msgstr "" -#: ../libvips/iofuncs/type.c:1046 +#: libvips/iofuncs/header.c:1888 #, c-format -msgid "unable to convert \"%s\" to float" +msgid "field \"%s\" is of type %s, not VipsRefString" msgstr "" -#: ../libvips/iofuncs/image.c:536 +#: libvips/iofuncs/image.c:539 msgid "unable to close fd" msgstr "" -#: ../libvips/iofuncs/image.c:617 -#, c-format -msgid "%dx%d %s, %d band, %s" -msgid_plural "%dx%d %s, %d bands, %s" -msgstr[0] "" -msgstr[1] "" - -#: ../libvips/iofuncs/image.c:651 -#, c-format -msgid " %s, %d band, %s" -msgid_plural " %s, %d bands, %s" -msgstr[0] "" -msgstr[1] "" - -#: ../libvips/iofuncs/image.c:784 +#: libvips/iofuncs/image.c:762 #, c-format msgid "%s %s: %d x %d pixels, %d threads, %d x %d tiles, %d lines in buffer" msgstr "" -#: ../libvips/iofuncs/image.c:797 +#: libvips/iofuncs/image.c:775 #, c-format msgid "%s %s: %d%% complete" msgstr "" -#. Spaces at end help to erase the %complete message we overwrite. -#. -#: ../libvips/iofuncs/image.c:816 +#: libvips/iofuncs/image.c:794 #, c-format msgid "%s %s: done in %.3gs \n" msgstr "" -#: ../libvips/iofuncs/image.c:1000 +#: libvips/iofuncs/image.c:976 #, c-format msgid "unable to open \"%s\", file too short" msgstr "" -#: ../libvips/iofuncs/image.c:1009 +#: libvips/iofuncs/image.c:985 #, c-format msgid "%s is longer than expected" msgstr "" -#: ../libvips/iofuncs/image.c:1027 +#: libvips/iofuncs/image.c:1003 #, c-format msgid "bad mode \"%s\"" msgstr "" -#: ../libvips/iofuncs/image.c:1103 +#: libvips/iofuncs/image.c:1075 msgid "image class" msgstr "" -#: ../libvips/iofuncs/image.c:1201 +#: libvips/iofuncs/image.c:1173 msgid "Image filename" msgstr "" -#: ../libvips/iofuncs/image.c:1208 +#: libvips/iofuncs/image.c:1180 msgid "Open mode" msgstr "" -#: ../libvips/iofuncs/image.c:1214 +#: libvips/iofuncs/image.c:1186 msgid "Kill" msgstr "" -#: ../libvips/iofuncs/image.c:1215 +#: libvips/iofuncs/image.c:1187 msgid "Block evaluation on this image" msgstr "" -#: ../libvips/iofuncs/image.c:1221 +#: libvips/iofuncs/image.c:1193 msgid "Demand style" msgstr "" -#: ../libvips/iofuncs/image.c:1222 +#: libvips/iofuncs/image.c:1194 msgid "Preferred demand style for this image" msgstr "" -#: ../libvips/iofuncs/image.c:1235 +#: libvips/iofuncs/image.c:1207 msgid "Foreign buffer" msgstr "" -#: ../libvips/iofuncs/image.c:1236 +#: libvips/iofuncs/image.c:1208 msgid "Pointer to foreign pixels" msgstr "" -#: ../libvips/iofuncs/image.c:1647 +#: libvips/iofuncs/image.c:1660 #, c-format msgid "killed for image \"%s\"" msgstr "" -#: ../libvips/iofuncs/image.c:2049 -#, c-format -msgid "memory area too small --- should be %zd bytes, you passed %zd" +#: libvips/iofuncs/image.c:2069 +msgid "memory area too small --- should be %" +msgstr "" + +#: libvips/iofuncs/image.c:2258 +msgid "unable to load source" msgstr "" -#: ../libvips/iofuncs/image.c:2264 +#: libvips/iofuncs/image.c:2369 #, c-format msgid "bad array length --- should be %d, you passed %d" msgstr "" -#: ../libvips/iofuncs/image.c:2854 -msgid "bad image descriptor" +#: libvips/iofuncs/image.c:2886 libvips/iofuncs/image.c:2888 +#: libvips/iofuncs/memory.c:336 libvips/iofuncs/memory.c:338 +#: libvips/iofuncs/memory.c:409 libvips/iofuncs/memory.c:411 +#, c-format +msgid "out of memory --- size == %dMB" msgstr "" -#: ../libvips/iofuncs/image.c:2912 ../libvips/iofuncs/generate.c:779 -#, c-format -msgid "unable to output to a %s image" +#: libvips/iofuncs/image.c:3179 +msgid "bad image descriptor" msgstr "" -#: ../libvips/iofuncs/image.c:2976 +#: libvips/iofuncs/image.c:3298 #, c-format msgid "auto-rewind for %s failed" msgstr "" -#: ../libvips/iofuncs/image.c:3045 ../libvips/iofuncs/image.c:3175 -#: ../libvips/iofuncs/image.c:3354 +#: libvips/iofuncs/image.c:3372 libvips/iofuncs/image.c:3502 +#: libvips/iofuncs/image.c:3679 msgid "image not readable" msgstr "" -#: ../libvips/iofuncs/image.c:3090 ../libvips/iofuncs/image.c:3314 -#: ../libvips/iofuncs/image.c:3331 +#: libvips/iofuncs/image.c:3417 libvips/iofuncs/image.c:3643 msgid "no image data" msgstr "" -#: ../libvips/iofuncs/image.c:3196 ../libvips/iofuncs/image.c:3384 -#: ../libvips/iofuncs/image.c:3393 +#: libvips/iofuncs/image.c:3523 libvips/iofuncs/image.c:3709 +#: libvips/iofuncs/image.c:3718 msgid "image already written" msgstr "" -#: ../libvips/iofuncs/image.c:3220 ../libvips/iofuncs/image.c:3405 +#: libvips/iofuncs/image.c:3547 libvips/iofuncs/image.c:3730 msgid "image not writeable" msgstr "" -#: ../libvips/iofuncs/image.c:3272 +#: libvips/iofuncs/image.c:3602 msgid "bad file type" msgstr "" -#: ../libvips/iofuncs/threadpool.c:247 -msgid "unable to create thread" -msgstr "" - -#: ../libvips/iofuncs/threadpool.c:410 +#: libvips/iofuncs/init.c:316 tools/vips.c:772 #, c-format -msgid "threads clipped to %d" +msgid "unable to load \"%s\" -- %s" msgstr "" -#: ../libvips/iofuncs/threadpool.c:456 -msgid "per-thread state for vipsthreadpool" +#: libvips/iofuncs/init.c:1270 +msgid "flag not in [0, 5]" msgstr "" -#: ../libvips/iofuncs/mapfile.c:131 ../libvips/iofuncs/mapfile.c:298 +#: libvips/iofuncs/mapfile.c:189 libvips/iofuncs/mapfile.c:355 msgid "unable to CreateFileMapping" msgstr "" -#: ../libvips/iofuncs/mapfile.c:139 ../libvips/iofuncs/mapfile.c:310 +#: libvips/iofuncs/mapfile.c:196 libvips/iofuncs/mapfile.c:367 msgid "unable to MapViewOfFile" msgstr "" -#: ../libvips/iofuncs/mapfile.c:179 +#: libvips/iofuncs/mapfile.c:235 msgid "unable to mmap" msgstr "" -#: ../libvips/iofuncs/mapfile.c:180 -#, c-format -msgid "" -"map failed (%s), running very low on system resources, expect a crash soon" -msgstr "" - -#: ../libvips/iofuncs/mapfile.c:197 ../libvips/iofuncs/mapfile.c:304 +#: libvips/iofuncs/mapfile.c:250 libvips/iofuncs/mapfile.c:361 msgid "unable to UnmapViewOfFile" msgstr "" -#: ../libvips/iofuncs/mapfile.c:203 +#: libvips/iofuncs/mapfile.c:256 msgid "unable to munmap file" msgstr "" -#: ../libvips/iofuncs/mapfile.c:225 +#: libvips/iofuncs/mapfile.c:278 msgid "file is less than 64 bytes" msgstr "" -#: ../libvips/iofuncs/mapfile.c:230 ../libvips/iofuncs/mapfile.c:264 +#: libvips/iofuncs/mapfile.c:283 libvips/iofuncs/mapfile.c:317 msgid "unable to get file status" msgstr "" -#: ../libvips/iofuncs/mapfile.c:236 +#: libvips/iofuncs/mapfile.c:289 msgid "not a regular file" msgstr "" -#: ../libvips/iofuncs/mapfile.c:270 +#: libvips/iofuncs/mapfile.c:323 msgid "unable to read data" msgstr "" -#: ../libvips/iofuncs/mapfile.c:330 +#: libvips/iofuncs/mapfile.c:387 #, c-format msgid "unable to mmap: \"%s\" - %s" msgstr "" -#: ../libvips/iofuncs/mapfile.c:340 +#: libvips/iofuncs/mapfile.c:398 #, c-format msgid "unable to mmap \"%s\" to same address" msgstr "" -#: ../libvips/iofuncs/sinkdisc.c:122 -msgid "per-thread state for sinkdisc" -msgstr "" - -#: ../libvips/iofuncs/sinkdisc.c:261 ../libvips/iofuncs/util.c:535 -msgid "write failed" -msgstr "" - -#: ../libvips/iofuncs/operation.c:225 -#, c-format -msgid "%d pixels calculated" -msgstr "" - -#: ../libvips/iofuncs/operation.c:309 ../libvips/iofuncs/operation.c:330 -#: ../libvips/iofuncs/operation.c:338 ../libvips/iofuncs/operation.c:350 -msgid "default" -msgstr "" - -#: ../libvips/iofuncs/operation.c:313 -msgid "allowed" -msgstr "" - -#: ../libvips/iofuncs/operation.c:341 ../libvips/iofuncs/operation.c:353 -msgid "min" -msgstr "" - -#: ../libvips/iofuncs/operation.c:343 ../libvips/iofuncs/operation.c:355 -msgid "max" -msgstr "" - -#: ../libvips/iofuncs/operation.c:571 -msgid "operations" -msgstr "" - -#: ../libvips/iofuncs/operation.c:659 ../libvips/iofuncs/object.c:1511 -#: ../libvips/resample/interpolate.c:637 -#, c-format -msgid "class \"%s\" not found" -msgstr "" - -#: ../libvips/iofuncs/operation.c:665 +#: libvips/iofuncs/object.c:346 #, c-format -msgid "\"%s\" is not an instantiable class" +msgid "parameter %s not set" msgstr "" -#: ../libvips/iofuncs/operation.c:1129 +#: libvips/iofuncs/object.c:781 #, c-format -msgid "unknown argument '%s'" -msgstr "" - -#: ../libvips/iofuncs/operation.c:1253 -msgid "too few arguments" -msgstr "" - -#: ../libvips/iofuncs/operation.c:1374 -msgid "too many arguments" -msgstr "" - -#: ../libvips/iofuncs/sinkmemory.c:109 -msgid "per-thread state for sinkmemory" -msgstr "" - -#: ../libvips/iofuncs/generate.c:690 -msgid "demand hint not set" -msgstr "" - -#: ../libvips/iofuncs/generate.c:709 ../libvips/iofuncs/generate.c:737 -msgid "generate() called twice" +msgid "no property named `%s'" msgstr "" -#: ../libvips/iofuncs/window.c:237 ../libvips/iofuncs/vips.c:918 +#: libvips/iofuncs/object.c:787 #, c-format -msgid "unable to read data for \"%s\", %s" -msgstr "" - -#: ../libvips/iofuncs/window.c:238 ../libvips/iofuncs/vips.c:808 -#: ../libvips/iofuncs/vips.c:919 -msgid "file has been truncated" -msgstr "" - -#: ../libvips/iofuncs/system.c:184 -msgid "unable to substitute input filename" -msgstr "" - -#: ../libvips/iofuncs/system.c:191 -msgid "unable to substitute output filename" +msgid "no vips argument named `%s'" msgstr "" -#: ../libvips/iofuncs/system.c:226 +#: libvips/iofuncs/object.c:793 #, c-format -msgid "command \"%s\" failed" +msgid "argument `%s' has no instance" msgstr "" -#: ../libvips/iofuncs/system.c:234 +#: libvips/iofuncs/object.c:1533 libvips/iofuncs/operation.c:749 +#: libvips/resample/interpolate.c:659 #, c-format -msgid "stderr output: %s" -msgstr "" - -#: ../libvips/iofuncs/system.c:269 -msgid "run an external command" -msgstr "" - -#: ../libvips/iofuncs/system.c:290 -msgid "Command" -msgstr "" - -#: ../libvips/iofuncs/system.c:291 -msgid "Command to run" +msgid "class \"%s\" not found" msgstr "" -#: ../libvips/iofuncs/system.c:297 -msgid "Input format" +#: libvips/iofuncs/object.c:1584 +msgid "base class" msgstr "" -#: ../libvips/iofuncs/system.c:298 -msgid "Format for input filename" +#: libvips/iofuncs/object.c:1598 +msgid "Nickname" msgstr "" -#: ../libvips/iofuncs/system.c:304 -msgid "Output format" +#: libvips/iofuncs/object.c:1599 +msgid "Class nickname" msgstr "" -#: ../libvips/iofuncs/system.c:305 -msgid "Format for output filename" +#: libvips/iofuncs/object.c:1605 +msgid "Description" msgstr "" -#: ../libvips/iofuncs/system.c:312 -msgid "Command log" +#: libvips/iofuncs/object.c:1606 +msgid "Class description" msgstr "" -#: ../libvips/iofuncs/header.c:1067 +#: libvips/iofuncs/object.c:1844 #, c-format -msgid "field \"%s\" not found" +msgid "no value supplied for argument '%s'" msgstr "" -#: ../libvips/iofuncs/header.c:1269 +#: libvips/iofuncs/object.c:1847 #, c-format -msgid "field \"%s\" is of type %s, not %s" +msgid "no value supplied for argument '%s' ('%s')" msgstr "" -#: ../libvips/iofuncs/header.c:1498 +#: libvips/iofuncs/object.c:2039 libvips/iofuncs/object.c:2058 #, c-format -msgid "field \"%s\" is of type %s, not VipsRefString" +msgid "'%s' is not an integer" msgstr "" -#: ../libvips/iofuncs/init.c:234 +#: libvips/iofuncs/object.c:2481 #, c-format -msgid "unable to load \"%s\" -- %s" -msgstr "" - -#: ../libvips/iofuncs/init.c:655 -msgid "show informative messages" -msgstr "" - -#: ../libvips/iofuncs/init.c:658 -msgid "abort on first error or warning" +msgid "expected string or ), saw %s" msgstr "" -#: ../libvips/iofuncs/init.c:661 -msgid "evaluate with N concurrent threads" +#: libvips/iofuncs/object.c:2524 +#, c-format +msgid "unable to set '%s'" msgstr "" -#: ../libvips/iofuncs/init.c:664 -msgid "set tile width to N (DEBUG)" +#: libvips/iofuncs/object.c:2537 +msgid "not , or ) after parameter" msgstr "" -#: ../libvips/iofuncs/init.c:667 -msgid "set tile height to N (DEBUG)" +#: libvips/iofuncs/object.c:2544 +msgid "extra tokens after ')'" msgstr "" -#: ../libvips/iofuncs/init.c:670 -msgid "set thinstrip height to N (DEBUG)" +#: libvips/iofuncs/operation.c:235 +#, c-format +msgid "%d pixels calculated" msgstr "" -#: ../libvips/iofuncs/init.c:673 -msgid "set fatstrip height to N (DEBUG)" +#: libvips/iofuncs/operation.c:343 +msgid "default enum" msgstr "" -#: ../libvips/iofuncs/init.c:676 -msgid "show progress feedback" +#: libvips/iofuncs/operation.c:347 +msgid "allowed enums" msgstr "" -#: ../libvips/iofuncs/init.c:679 -msgid "leak-check on exit" +#: libvips/iofuncs/operation.c:375 +msgid "default flags" msgstr "" -#: ../libvips/iofuncs/init.c:682 -msgid "profile and dump timing on exit" +#: libvips/iofuncs/operation.c:380 +msgid "allowed flags" msgstr "" -#: ../libvips/iofuncs/init.c:685 -msgid "images larger than N are decompressed to disc" +#: libvips/iofuncs/operation.c:396 libvips/iofuncs/operation.c:404 +#: libvips/iofuncs/operation.c:416 +msgid "default" msgstr "" -#: ../libvips/iofuncs/init.c:688 -msgid "disable vectorised versions of operations" +#: libvips/iofuncs/operation.c:407 libvips/iofuncs/operation.c:419 +msgid "min" msgstr "" -#: ../libvips/iofuncs/init.c:691 -msgid "cache at most N operations" +#: libvips/iofuncs/operation.c:409 libvips/iofuncs/operation.c:421 +msgid "max" msgstr "" -#: ../libvips/iofuncs/init.c:694 -msgid "cache at most N bytes in memory" +#: libvips/iofuncs/operation.c:618 +msgid "operation is blocked" msgstr "" -#: ../libvips/iofuncs/init.c:697 -msgid "allow at most N open files" +#: libvips/iofuncs/operation.c:664 +msgid "operations" msgstr "" -#: ../libvips/iofuncs/init.c:700 -msgid "trace operation cache" +#: libvips/iofuncs/operation.c:755 +#, c-format +msgid "\"%s\" is not an instantiable class" msgstr "" -#: ../libvips/iofuncs/init.c:703 -msgid "dump operation cache on exit" +#: libvips/iofuncs/operation.c:1225 +#, c-format +msgid "unknown argument '%s'" msgstr "" -#: ../libvips/iofuncs/init.c:706 -msgid "print libvips version" +#: libvips/iofuncs/operation.c:1350 +msgid "too few arguments" msgstr "" -#: ../libvips/iofuncs/init.c:1091 -msgid "flag not in [0, 5]" +#: libvips/iofuncs/operation.c:1469 +msgid "too many arguments" msgstr "" -#: ../libvips/iofuncs/region.c:585 ../libvips/iofuncs/region.c:657 -#: ../libvips/iofuncs/region.c:805 ../libvips/iofuncs/region.c:1516 +#: libvips/iofuncs/region.c:565 libvips/iofuncs/region.c:635 +#: libvips/iofuncs/region.c:777 libvips/iofuncs/region.c:1848 msgid "valid clipped to nothing" msgstr "" -#: ../libvips/iofuncs/region.c:702 +#: libvips/iofuncs/region.c:675 msgid "bad image type" msgstr "" -#: ../libvips/iofuncs/region.c:747 +#: libvips/iofuncs/region.c:719 msgid "no pixel data on attached image" msgstr "" -#: ../libvips/iofuncs/region.c:753 +#: libvips/iofuncs/region.c:725 msgid "images do not match in pixel size" msgstr "" -#: ../libvips/iofuncs/region.c:786 ../libvips/iofuncs/region.c:1498 +#: libvips/iofuncs/region.c:758 libvips/iofuncs/region.c:1830 msgid "dest too small" msgstr "" -#: ../libvips/iofuncs/region.c:875 +#: libvips/iofuncs/region.c:847 msgid "bad position" msgstr "" -#: ../libvips/iofuncs/region.c:1291 +#: libvips/iofuncs/region.c:1628 msgid "stop requested" msgstr "" -#: ../libvips/iofuncs/region.c:1376 ../libvips/iofuncs/region.c:1569 +#: libvips/iofuncs/region.c:1711 libvips/iofuncs/region.c:1901 #, c-format msgid "unable to input from a %s image" msgstr "" -#: ../libvips/iofuncs/region.c:1400 +#: libvips/iofuncs/region.c:1735 msgid "incomplete header" msgstr "" -#: ../libvips/iofuncs/region.c:1472 +#: libvips/iofuncs/region.c:1804 msgid "inappropriate region type" msgstr "" -#: ../libvips/iofuncs/vips.c:306 -#, c-format -msgid "\"%s\" is not a VIPS image" +#: libvips/iofuncs/sbuf.c:85 +msgid "buffered source" msgstr "" -#: ../libvips/iofuncs/vips.c:406 -msgid "unable to read history" +#: libvips/iofuncs/sbuf.c:280 +msgid "end of file" msgstr "" -#: ../libvips/iofuncs/vips.c:439 -msgid "more than a 10 megabytes of XML? sufferin' succotash!" +#: libvips/iofuncs/sink.c:262 +#, c-format +msgid "stop function failed for image \"%s\"" msgstr "" -#: ../libvips/iofuncs/vips.c:487 -msgid "incorrect namespace in XML" +#: libvips/iofuncs/sink.c:299 +#, c-format +msgid "start function failed for image \"%s\"" msgstr "" -#: ../libvips/iofuncs/vips.c:611 -msgid "error transforming from save format" +#: libvips/iofuncs/sink.c:331 +msgid "per-thread state for sink" msgstr "" -#: ../libvips/iofuncs/vips.c:760 -msgid "error transforming to save format" +#: libvips/iofuncs/sinkdisc.c:108 libvips/iofuncs/util.c:477 +msgid "write failed" msgstr "" -#: ../libvips/iofuncs/vips.c:904 -#, c-format -msgid "unable to read header for \"%s\"" +#: libvips/iofuncs/sinkdisc.c:137 +msgid "per-thread state for sinkdisc" msgstr "" -#: ../libvips/iofuncs/vips.c:930 -#, c-format -msgid "error reading XML: %s" +#: libvips/iofuncs/sinkmemory.c:109 +msgid "per-thread state for sinkmemory" msgstr "" -#: ../libvips/iofuncs/error.c:287 -msgid "windows error" +#: libvips/iofuncs/sinkscreen.c:196 +msgid "per-thread state for render" msgstr "" -#: ../libvips/iofuncs/error.c:296 -msgid "unix error" +#: libvips/iofuncs/sinkscreen.c:1122 +msgid "bad parameters" msgstr "" -#: ../libvips/iofuncs/error.c:447 -msgid "image must be uncoded" +#: libvips/iofuncs/source.c:281 libvips/iofuncs/target.c:114 +msgid "don't set 'filename' and 'descriptor'" msgstr "" -#: ../libvips/iofuncs/error.c:475 -msgid "image coding must be 'none' or 'labq'" +#: libvips/iofuncs/source.c:358 +msgid "input source" msgstr "" -#: ../libvips/iofuncs/error.c:503 -msgid "unknown image coding" +#: libvips/iofuncs/source.c:366 libvips/iofuncs/target.c:304 +msgid "Blob" msgstr "" -#: ../libvips/iofuncs/error.c:528 -#, c-format -msgid "coding '%s' only" +#: libvips/iofuncs/source.c:367 +msgid "Blob to load from" msgstr "" -#: ../libvips/iofuncs/error.c:553 -msgid "image must one band" -msgstr "" +#: libvips/iofuncs/source.c:512 +#, fuzzy +msgid "unimplemented target" +msgstr "unimplemented input colour space 0x%x" -#: ../libvips/iofuncs/error.c:578 -#, c-format -msgid "image must have %d bands" +#: libvips/iofuncs/source.c:649 +msgid "unable to open for read" msgstr "" -#: ../libvips/iofuncs/error.c:603 -msgid "image must have one or three bands" +#: libvips/iofuncs/source.c:890 +msgid "pipe too long" msgstr "" -#: ../libvips/iofuncs/error.c:629 -#, c-format -msgid "image must have at least %d bands" +#: libvips/iofuncs/source.c:1165 libvips/iofuncs/source.c:1190 +#: libvips/iofuncs/target.c:206 +msgid "bad 'whence'" msgstr "" -#: ../libvips/iofuncs/error.c:657 -msgid "images must have the same number of bands, or one must be single-band" +#: libvips/iofuncs/source.c:1211 +msgid "bad seek to %" msgstr "" -#: ../libvips/iofuncs/error.c:684 -#, c-format -msgid "image must have 1 or %d bands" +#: libvips/iofuncs/sourcecustom.c:173 +msgid "Custom source" msgstr "" -#: ../libvips/iofuncs/error.c:708 -msgid "image must be non-complex" +#: libvips/iofuncs/sourceginput.c:219 +msgid "GInputStream source" msgstr "" -#: ../libvips/iofuncs/error.c:732 -msgid "image must be complex" +#: libvips/iofuncs/sourceginput.c:227 +msgid "Stream" msgstr "" -#: ../libvips/iofuncs/error.c:759 -msgid "image must be two-band or complex" +#: libvips/iofuncs/sourceginput.c:228 +msgid "GInputStream to read from" msgstr "" -#: ../libvips/iofuncs/error.c:785 -#, c-format -msgid "image must be %s" +#: libvips/iofuncs/system.c:185 +msgid "unable to substitute input filename" msgstr "" -#: ../libvips/iofuncs/error.c:810 -msgid "image must be integer" +#: libvips/iofuncs/system.c:191 +msgid "unable to substitute output filename" msgstr "" -#: ../libvips/iofuncs/error.c:835 -msgid "image must be unsigned integer" +#: libvips/iofuncs/system.c:226 +#, c-format +msgid "command \"%s\" failed" msgstr "" -#: ../libvips/iofuncs/error.c:863 -msgid "image must be 8- or 16-bit integer, signed or unsigned" +#: libvips/iofuncs/system.c:234 +#, c-format +msgid "stderr output: %s" msgstr "" -#: ../libvips/iofuncs/error.c:890 -msgid "image must be 8- or 16-bit unsigned integer" +#: libvips/iofuncs/system.c:269 +msgid "run an external command" msgstr "" -#: ../libvips/iofuncs/error.c:916 -msgid "image must be 8- or 16-bit unsigned integer, or float" +#: libvips/iofuncs/system.c:290 +msgid "Command" msgstr "" -#: ../libvips/iofuncs/error.c:944 -msgid "image must be unsigned int or float" +#: libvips/iofuncs/system.c:291 +msgid "Command to run" msgstr "" -#: ../libvips/iofuncs/error.c:969 -msgid "images must match in size" +#: libvips/iofuncs/system.c:297 +msgid "Input format" msgstr "" -#: ../libvips/iofuncs/error.c:995 -msgid "images must be odd and square" +#: libvips/iofuncs/system.c:298 +msgid "Format for input filename" msgstr "" -#: ../libvips/iofuncs/error.c:1021 -msgid "images must have the same number of bands" +#: libvips/iofuncs/system.c:304 +msgid "Output format" msgstr "" -#: ../libvips/iofuncs/error.c:1075 -msgid "images must have the same band format" +#: libvips/iofuncs/system.c:305 +msgid "Format for output filename" msgstr "" -#: ../libvips/iofuncs/error.c:1101 -msgid "images must have the same coding" +#: libvips/iofuncs/system.c:312 +msgid "Command log" msgstr "" -#: ../libvips/iofuncs/error.c:1124 -#, c-format -msgid "vector must have %d elements" +#: libvips/iofuncs/target.c:295 +msgid "File descriptor should output to memory" msgstr "" -#: ../libvips/iofuncs/error.c:1149 -#, c-format -msgid "vector must have 1 or %d elements" +#: libvips/iofuncs/target.c:305 +msgid "Blob to save to" msgstr "" -#: ../libvips/iofuncs/error.c:1174 -msgid "histograms must have width or height 1" +#: libvips/iofuncs/target.c:474 +msgid "write error" msgstr "" -#: ../libvips/iofuncs/error.c:1179 -msgid "histograms must have not have more than 65536 elements" +#: libvips/iofuncs/targetcustom.c:235 +msgid "Custom target" msgstr "" -#: ../libvips/iofuncs/error.c:1216 -msgid "matrix image too large" +#: libvips/iofuncs/thread.c:179 +msgid "unable to create thread" msgstr "" -#: ../libvips/iofuncs/error.c:1221 -msgid "matrix image must have one band" +#: libvips/iofuncs/thread.c:214 libvips/iofuncs/thread.c:243 +#, c-format +msgid "threads clipped to %d" msgstr "" -#: ../libvips/iofuncs/error.c:1255 -msgid "separable matrix images must have width or height 1" +#: libvips/iofuncs/threadpool.c:193 +msgid "per-thread state for vipsthreadpool" msgstr "" -#: ../libvips/iofuncs/error.c:1282 -msgid "precision must be int or float" +#: libvips/iofuncs/type.c:958 +#, c-format +msgid "unable to convert \"%s\" to int" msgstr "" -#: ../libvips/iofuncs/util.c:518 +#: libvips/iofuncs/util.c:455 msgid "unable to get file stats" msgstr "" -#: ../libvips/iofuncs/util.c:674 +#: libvips/iofuncs/util.c:619 #, c-format msgid "unable to open file \"%s\" for reading" msgstr "" -#: ../libvips/iofuncs/util.c:696 +#: libvips/iofuncs/util.c:641 #, c-format msgid "unable to open file \"%s\" for writing" msgstr "" -#: ../libvips/iofuncs/util.c:718 +#: libvips/iofuncs/util.c:662 #, c-format msgid "\"%s\" too long" msgstr "" -#: ../libvips/iofuncs/util.c:765 +#: libvips/iofuncs/util.c:710 #, c-format msgid "error reading from file \"%s\"" msgstr "" -#: ../libvips/iofuncs/util.c:812 +#: libvips/iofuncs/util.c:756 #, c-format msgid "write error (%zd out of %zd blocks written)" msgstr "" -#: ../libvips/iofuncs/util.c:1084 ../libvips/iofuncs/util.c:1091 -msgid "unable to truncate" +#: libvips/iofuncs/util.c:1003 +msgid "unable to seek" msgstr "" -#: ../libvips/iofuncs/util.c:1167 -#, c-format -msgid "unable to create directory \"%s\", %s" +#: libvips/iofuncs/util.c:1028 libvips/iofuncs/util.c:1035 +msgid "unable to truncate" msgstr "" -#: ../libvips/iofuncs/util.c:1191 +#: libvips/iofuncs/util.c:1121 #, c-format msgid "unable to remove directory \"%s\", %s" msgstr "" -#: ../libvips/iofuncs/util.c:1208 +#: libvips/iofuncs/util.c:1138 #, c-format msgid "unable to rename file \"%s\" as \"%s\", %s" msgstr "" -#: ../libvips/iofuncs/util.c:1348 +#: libvips/iofuncs/util.c:1267 msgid "unexpected end of string" msgstr "" -#: ../libvips/iofuncs/util.c:1366 ../libvips/iofuncs/util.c:1436 +#: libvips/iofuncs/util.c:1285 libvips/iofuncs/util.c:1355 #, c-format msgid "expected %s, saw %s" msgstr "" -#: ../libvips/iofuncs/util.c:1750 +#: libvips/iofuncs/util.c:1664 msgid "no such enum type" msgstr "" -#: ../libvips/iofuncs/util.c:1768 +#: libvips/iofuncs/util.c:1682 #, c-format msgid "enum '%s' has no member '%s', should be one of: %s" msgstr "" -#: ../libvips/iofuncs/util.c:1786 +#: libvips/iofuncs/util.c:1701 msgid "no such flag type" msgstr "" -#: ../libvips/iofuncs/util.c:1802 +#: libvips/iofuncs/util.c:1720 #, c-format -msgid "flags '%s' has no member '%s', should be one of: %s" +msgid "flags '%s' has no member '%s'" msgstr "" -#: ../libvips/iofuncs/util.c:1889 -msgid "unable to form filename" -msgstr "" - -#: ../libvips/iofuncs/sinkscreen.c:188 -msgid "per-thread state for render" +#: libvips/iofuncs/vips.c:338 +#, c-format +msgid "\"%s\" is not a VIPS image" msgstr "" -#: ../libvips/iofuncs/sinkscreen.c:1088 -msgid "bad parameters" +#: libvips/iofuncs/vips.c:395 +msgid "unknown coding" msgstr "" -#: ../libvips/iofuncs/object.c:316 -#, c-format -msgid "parameter %s not set" +#: libvips/iofuncs/vips.c:405 +msgid "malformed LABQ image" msgstr "" -#: ../libvips/iofuncs/object.c:751 -#, c-format -msgid "no property named `%s'" +#: libvips/iofuncs/vips.c:414 +msgid "malformed RAD image" msgstr "" -#: ../libvips/iofuncs/object.c:759 -#, c-format -msgid "no vips argument named `%s'" +#: libvips/iofuncs/vips.c:485 +msgid "unable to read history" msgstr "" -#: ../libvips/iofuncs/object.c:765 -#, c-format -msgid "argument `%s' has no instance" +#: libvips/iofuncs/vips.c:518 +msgid "more than 100 megabytes of XML? sufferin' succotash!" msgstr "" -#: ../libvips/iofuncs/object.c:1561 -msgid "base class" +#: libvips/iofuncs/vips.c:552 +msgid "unable to allocate read buffer" msgstr "" -#: ../libvips/iofuncs/object.c:1575 -msgid "Nickname" +#: libvips/iofuncs/vips.c:558 +msgid "read error while fetching XML" msgstr "" -#: ../libvips/iofuncs/object.c:1576 -msgid "Class nickname" +#: libvips/iofuncs/vips.c:570 +msgid "XML parse error" msgstr "" -#: ../libvips/iofuncs/object.c:1582 -msgid "Description" +#: libvips/iofuncs/vips.c:635 +msgid "incorrect namespace in XML" msgstr "" -#: ../libvips/iofuncs/object.c:1583 -msgid "Class description" +#: libvips/iofuncs/vips.c:683 +msgid "error transforming from save format" msgstr "" -#: ../libvips/iofuncs/object.c:1781 -#, c-format -msgid "no value supplied for argument '%s'" +#: libvips/iofuncs/vips.c:784 libvips/iofuncs/vips.c:1056 +#: libvips/iofuncs/window.c:232 +msgid "file has been truncated" msgstr "" -#: ../libvips/iofuncs/object.c:1784 -#, c-format -msgid "no value supplied for argument '%s' ('%s')" +#: libvips/iofuncs/vips.c:836 libvips/iofuncs/vips.c:927 +msgid "error transforming to save format" msgstr "" -#: ../libvips/iofuncs/object.c:1942 ../libvips/iofuncs/object.c:1961 -#: ../libvips/iofuncs/object.c:2014 +#: libvips/iofuncs/vips.c:1041 #, c-format -msgid "'%s' is not an integer" +msgid "unable to read header for \"%s\"" msgstr "" -#: ../libvips/iofuncs/object.c:1978 +#: libvips/iofuncs/vips.c:1055 libvips/iofuncs/window.c:231 #, c-format -msgid "'%s' is not a double" +msgid "unable to read data for \"%s\", %s" msgstr "" -#: ../libvips/iofuncs/object.c:2293 +#: libvips/iofuncs/vips.c:1067 #, c-format -msgid "expected string or ), saw %s" +msgid "error reading vips image metadata: %s" msgstr "" -#: ../libvips/iofuncs/object.c:2336 -#, c-format -msgid "unable to set '%s'" +#: libvips/morphology/countlines.c:135 +msgid "count lines in an image" msgstr "" -#: ../libvips/iofuncs/object.c:2349 -msgid "not , or ) after parameter" +#: libvips/morphology/countlines.c:139 +msgid "Nolines" msgstr "" -#: ../libvips/iofuncs/object.c:2356 -msgid "extra tokens after ')'" +#: libvips/morphology/countlines.c:140 +msgid "Number of lines" msgstr "" -#: ../libvips/iofuncs/buf.c:610 -#, c-format -msgid "%zd bytes of binary data" +#: libvips/morphology/countlines.c:147 +msgid "Countlines left-right or up-down" msgstr "" -#. File length unit. -#. -#: ../libvips/iofuncs/buf.c:679 -msgid "bytes" +#: libvips/morphology/labelregions.c:120 +msgid "label regions in an image" msgstr "" -#. Kilobyte unit. -#. -#: ../libvips/iofuncs/buf.c:683 -msgid "KB" +#: libvips/morphology/labelregions.c:125 +msgid "Mask of region labels" msgstr "" -#. Megabyte unit. -#. -#: ../libvips/iofuncs/buf.c:687 -msgid "MB" +#: libvips/morphology/labelregions.c:130 +msgid "Segments" msgstr "" -#. Gigabyte unit. -#. -#: ../libvips/iofuncs/buf.c:691 -msgid "GB" +#: libvips/morphology/labelregions.c:131 +msgid "Number of discrete contiguous regions" msgstr "" -#. Terabyte unit. -#. -#: ../libvips/iofuncs/buf.c:695 -msgid "TB" +#: libvips/morphology/morph.c:885 +#, c-format +msgid "bad mask element (%f should be 0, 128 or 255)" msgstr "" -#: ../libvips/morphology/morph.c:139 +#: libvips/morphology/morph.c:955 msgid "morphology operation" msgstr "" -#: ../libvips/morphology/morph.c:155 +#: libvips/morphology/morph.c:971 msgid "Morphology" msgstr "" -#: ../libvips/morphology/morph.c:156 +#: libvips/morphology/morph.c:972 msgid "Morphological operation to perform" msgstr "" -#: ../libvips/morphology/rank.c:359 -msgid "index out of range" +#: libvips/morphology/morphology.c:115 +msgid "morphological operations" msgstr "" -#: ../libvips/morphology/rank.c:409 -msgid "rank filter" +#: libvips/morphology/nearest.c:305 +msgid "fill image zeros with nearest non-zero pixel" msgstr "" -#: ../libvips/morphology/rank.c:433 -msgid "index" +#: libvips/morphology/nearest.c:309 +msgid "Out" msgstr "" -#: ../libvips/morphology/rank.c:434 -msgid "Select pixel at index" +#: libvips/morphology/nearest.c:310 +msgid "Value of nearest non-zero pixel" msgstr "" -#: ../libvips/morphology/countlines.c:131 -msgid "count lines in an image" +#: libvips/morphology/nearest.c:316 +msgid "Distance to nearest non-zero pixel" msgstr "" -#: ../libvips/morphology/countlines.c:135 -msgid "Nolines" +#: libvips/morphology/rank.c:496 +msgid "index out of range" msgstr "" -#: ../libvips/morphology/countlines.c:136 -msgid "Number of lines" +#: libvips/morphology/rank.c:560 +msgid "rank filter" msgstr "" -#: ../libvips/morphology/countlines.c:143 -msgid "Countlines left-right or up-down" +#: libvips/morphology/rank.c:585 +msgid "Select pixel at index" msgstr "" -#: ../libvips/morphology/labelregions.c:121 -msgid "label regions in an image" +#: libvips/mosaicing/chkpair.c:200 +msgid "inputs incompatible" msgstr "" -#: ../libvips/morphology/labelregions.c:126 -msgid "Mask of region labels" +#: libvips/mosaicing/chkpair.c:204 libvips/mosaicing/im_tbcalcon.c:105 +msgid "help!" msgstr "" -#: ../libvips/morphology/labelregions.c:131 -msgid "Segments" +#: libvips/mosaicing/global_balance.c:151 +msgid "no matching '>'" msgstr "" -#: ../libvips/morphology/labelregions.c:132 -msgid "Number of discrete contiguous regions" +#: libvips/mosaicing/global_balance.c:160 +msgid "too many items" msgstr "" -#: ../libvips/morphology/morphology.c:111 -msgid "morphological operations" +#: libvips/mosaicing/global_balance.c:463 +msgid "circularity detected" msgstr "" -#: ../libvips/morphology/hitmiss.c:321 +#: libvips/mosaicing/global_balance.c:497 +#: libvips/mosaicing/global_balance.c:557 #, c-format -msgid "bad mask element (%d should be 0, 128 or 255)" +msgid "image \"%s\" used twice as output" msgstr "" -#: ../libvips/mosaicing/im_tbmerge.c:164 ../libvips/mosaicing/im_tbmerge.c:218 -#: ../libvips/mosaicing/im_tbmerge.c:536 ../libvips/mosaicing/im_lrmerge.c:216 -#: ../libvips/mosaicing/im_lrmerge.c:265 ../libvips/mosaicing/im_lrmerge.c:606 -msgid "internal error" +#: libvips/mosaicing/global_balance.c:606 +msgid "bad number of args in join line" msgstr "" -#: ../libvips/mosaicing/im_tbmerge.c:635 ../libvips/mosaicing/im_lrmerge.c:806 -msgid "unknown coding type" +#: libvips/mosaicing/global_balance.c:648 +msgid "bad number of args in join1 line" msgstr "" -#: ../libvips/mosaicing/im_tbmerge.c:653 ../libvips/mosaicing/im_lrmerge.c:823 -msgid "too much overlap" +#: libvips/mosaicing/global_balance.c:684 +msgid "bad number of args in copy line" msgstr "" -#: ../libvips/mosaicing/im_chkpair.c:201 -msgid "inputs incompatible" +#: libvips/mosaicing/global_balance.c:742 +msgid "" +"mosaic root not found in desc file\n" +"is this really a mosaiced image?" msgstr "" -#: ../libvips/mosaicing/im_chkpair.c:205 ../libvips/mosaicing/im_tbcalcon.c:103 -msgid "help!" +#: libvips/mosaicing/global_balance.c:753 +msgid "more than one root" msgstr "" -#: ../libvips/mosaicing/im_lrmosaic.c:114 ../libvips/mosaicing/im_tbmosaic.c:90 -msgid "bad area parameters" +#: libvips/mosaicing/global_balance.c:1525 +msgid "bad sizes" msgstr "" -#: ../libvips/mosaicing/im_lrmosaic.c:135 -#: ../libvips/mosaicing/im_tbmosaic.c:111 -msgid "overlap too small for search" +#: libvips/mosaicing/global_balance.c:1920 +msgid "global balance an image mosaic" msgstr "" -#: ../libvips/mosaicing/im_lrmosaic.c:168 -#: ../libvips/mosaicing/im_tbmosaic.c:144 -msgid "unknown Coding type" +#: libvips/mosaicing/global_balance.c:1936 +msgid "Gamma" msgstr "" -#: ../libvips/mosaicing/im_tbcalcon.c:117 -msgid "overlap too small" +#: libvips/mosaicing/global_balance.c:1937 +msgid "Image gamma" msgstr "" -#: ../libvips/mosaicing/merge.c:105 -msgid "merge two images" +#: libvips/mosaicing/global_balance.c:1943 +msgid "Int output" msgstr "" -#: ../libvips/mosaicing/merge.c:110 ../libvips/mosaicing/mosaic.c:181 -#: ../libvips/mosaicing/match.c:205 ../libvips/mosaicing/mosaic1.c:490 -msgid "Reference image" +#: libvips/mosaicing/global_balance.c:1944 +msgid "Integer output" msgstr "" -#: ../libvips/mosaicing/merge.c:115 ../libvips/mosaicing/mosaic.c:186 -#: ../libvips/mosaicing/match.c:210 ../libvips/mosaicing/mosaic1.c:495 -msgid "Secondary" +#: libvips/mosaicing/im_avgdxdy.c:65 +msgid "no points to average" msgstr "" -#: ../libvips/mosaicing/merge.c:116 ../libvips/mosaicing/mosaic.c:187 -#: ../libvips/mosaicing/match.c:211 ../libvips/mosaicing/mosaic1.c:496 -msgid "Secondary image" +#: libvips/mosaicing/im_clinear.c:138 +msgid "vips_invmat failed" msgstr "" -#: ../libvips/mosaicing/merge.c:128 -msgid "Horizontal or vertcial merge" +#: libvips/mosaicing/im_lrcalcon.c:206 +msgid "overlap too small for your search size" msgstr "" -#: ../libvips/mosaicing/merge.c:134 -msgid "dx" +#: libvips/mosaicing/im_lrcalcon.c:245 +#, c-format +msgid "found %d tie-points, need at least %d" msgstr "" -#: ../libvips/mosaicing/merge.c:135 -msgid "Horizontal displacement from sec to ref" +#: libvips/mosaicing/im_lrcalcon.c:290 +msgid "not 1-band uchar image" msgstr "" -#: ../libvips/mosaicing/merge.c:141 -msgid "dy" +#: libvips/mosaicing/im_tbcalcon.c:119 +msgid "overlap too small" msgstr "" -#: ../libvips/mosaicing/merge.c:142 -msgid "Vertical displacement from sec to ref" +#: libvips/mosaicing/lrmerge.c:786 +msgid "mwidth must be -1 or >= 0" msgstr "" -#: ../libvips/mosaicing/merge.c:148 ../libvips/mosaicing/mosaic.c:247 -#: ../libvips/mosaicing/mosaic1.c:597 -msgid "Max blend" +#: libvips/mosaicing/lrmerge.c:818 +msgid "no overlap" msgstr "" -#: ../libvips/mosaicing/merge.c:149 ../libvips/mosaicing/mosaic.c:248 -#: ../libvips/mosaicing/mosaic1.c:598 -msgid "Maximum blend size" +#: libvips/mosaicing/lrmerge.c:888 libvips/mosaicing/tbmerge.c:693 +msgid "unknown coding type" msgstr "" -#: ../libvips/mosaicing/im_remosaic.c:115 -#, c-format -msgid "substitute image \"%s\" is not the same size as \"%s\"" +#: libvips/mosaicing/lrmerge.c:906 libvips/mosaicing/tbmerge.c:711 +msgid "too much overlap" msgstr "" -#: ../libvips/mosaicing/im_remosaic.c:160 -#: ../libvips/mosaicing/global_balance.c:1767 -msgid "global balance an image mosaic" +#: libvips/mosaicing/lrmosaic.c:122 libvips/mosaicing/tbmosaic.c:93 +msgid "bad area parameters" msgstr "" -#: ../libvips/mosaicing/im_remosaic.c:176 -msgid "old_str" +#: libvips/mosaicing/lrmosaic.c:143 libvips/mosaicing/tbmosaic.c:114 +msgid "overlap too small for search" msgstr "" -#: ../libvips/mosaicing/im_remosaic.c:177 -msgid "Search for this string" +#: libvips/mosaicing/lrmosaic.c:171 libvips/mosaicing/tbmosaic.c:142 +msgid "unknown Coding type" msgstr "" -#: ../libvips/mosaicing/im_remosaic.c:183 -msgid "new_str" +#: libvips/mosaicing/match.c:192 +msgid "first-order match of two images" msgstr "" -#: ../libvips/mosaicing/im_remosaic.c:184 -msgid "And swap for this string" +#: libvips/mosaicing/match.c:197 libvips/mosaicing/merge.c:123 +#: libvips/mosaicing/mosaic1.c:499 libvips/mosaicing/mosaic.c:180 +msgid "Reference image" msgstr "" -#: ../libvips/mosaicing/im_lrcalcon.c:204 -msgid "overlap too small for your search size" +#: libvips/mosaicing/match.c:202 libvips/mosaicing/merge.c:128 +#: libvips/mosaicing/mosaic1.c:504 libvips/mosaicing/mosaic.c:185 +msgid "Secondary" msgstr "" -#: ../libvips/mosaicing/im_lrcalcon.c:243 -#, c-format -msgid "found %d tie-points, need at least %d" +#: libvips/mosaicing/match.c:203 libvips/mosaicing/merge.c:129 +#: libvips/mosaicing/mosaic1.c:505 libvips/mosaicing/mosaic.c:186 +msgid "Secondary image" msgstr "" -#: ../libvips/mosaicing/im_lrcalcon.c:288 -msgid "not 1-band uchar image" +#: libvips/mosaicing/match.c:214 libvips/mosaicing/mosaic1.c:523 +msgid "xr1" msgstr "" -#: ../libvips/mosaicing/global_balance.c:148 -msgid "no matching '>'" +#: libvips/mosaicing/match.c:215 libvips/mosaicing/match.c:222 +#: libvips/mosaicing/mosaic1.c:524 libvips/mosaicing/mosaic1.c:531 +msgid "Position of first reference tie-point" msgstr "" -#: ../libvips/mosaicing/global_balance.c:157 -msgid "too many items" +#: libvips/mosaicing/match.c:221 libvips/mosaicing/mosaic1.c:530 +msgid "yr1" msgstr "" -#: ../libvips/mosaicing/global_balance.c:451 -msgid "circularity detected" +#: libvips/mosaicing/match.c:228 libvips/mosaicing/mosaic1.c:537 +msgid "xs1" msgstr "" -#: ../libvips/mosaicing/global_balance.c:485 -#: ../libvips/mosaicing/global_balance.c:545 -#, c-format -msgid "image \"%s\" used twice as output" +#: libvips/mosaicing/match.c:229 libvips/mosaicing/match.c:236 +#: libvips/mosaicing/mosaic1.c:538 libvips/mosaicing/mosaic1.c:545 +msgid "Position of first secondary tie-point" msgstr "" -#: ../libvips/mosaicing/global_balance.c:594 -msgid "bad number of args in join line" +#: libvips/mosaicing/match.c:235 libvips/mosaicing/mosaic1.c:544 +msgid "ys1" msgstr "" -#: ../libvips/mosaicing/global_balance.c:636 -msgid "bad number of args in join1 line" +#: libvips/mosaicing/match.c:242 libvips/mosaicing/mosaic1.c:551 +msgid "xr2" msgstr "" -#: ../libvips/mosaicing/global_balance.c:672 -msgid "bad number of args in copy line" +#: libvips/mosaicing/match.c:243 libvips/mosaicing/match.c:250 +#: libvips/mosaicing/mosaic1.c:552 libvips/mosaicing/mosaic1.c:559 +msgid "Position of second reference tie-point" msgstr "" -#: ../libvips/mosaicing/global_balance.c:730 -msgid "" -"mosaic root not found in desc file\n" -"is this really a mosaiced image?" +#: libvips/mosaicing/match.c:249 libvips/mosaicing/mosaic1.c:558 +msgid "yr2" msgstr "" -#: ../libvips/mosaicing/global_balance.c:741 -msgid "more than one root" +#: libvips/mosaicing/match.c:256 libvips/mosaicing/mosaic1.c:565 +msgid "xs2" msgstr "" -#: ../libvips/mosaicing/global_balance.c:1783 -msgid "gamma" +#: libvips/mosaicing/match.c:257 libvips/mosaicing/match.c:264 +#: libvips/mosaicing/mosaic1.c:566 libvips/mosaicing/mosaic1.c:573 +msgid "Position of second secondary tie-point" msgstr "" -#: ../libvips/mosaicing/global_balance.c:1784 -msgid "Image gamma" +#: libvips/mosaicing/match.c:263 libvips/mosaicing/mosaic1.c:572 +msgid "ys2" msgstr "" -#: ../libvips/mosaicing/global_balance.c:1790 -msgid "Int output" +#: libvips/mosaicing/match.c:270 libvips/mosaicing/mosaic1.c:579 +#: libvips/mosaicing/mosaic.c:232 +msgid "hwindow" msgstr "" -#: ../libvips/mosaicing/global_balance.c:1791 -msgid "Integer output" +#: libvips/mosaicing/match.c:271 libvips/mosaicing/mosaic1.c:580 +#: libvips/mosaicing/mosaic.c:233 +msgid "Half window size" msgstr "" -#: ../libvips/mosaicing/im_avgdxdy.c:65 -msgid "no points to average" +#: libvips/mosaicing/match.c:277 libvips/mosaicing/mosaic1.c:586 +#: libvips/mosaicing/mosaic.c:239 +msgid "harea" +msgstr "" + +#: libvips/mosaicing/match.c:278 libvips/mosaicing/mosaic1.c:587 +#: libvips/mosaicing/mosaic.c:240 +msgid "Half area size" msgstr "" -#: ../libvips/mosaicing/im_lrmerge.c:706 -msgid "mwidth must be -1 or >= 0" +#: libvips/mosaicing/match.c:284 libvips/mosaicing/mosaic1.c:593 +msgid "Search" msgstr "" -#: ../libvips/mosaicing/im_lrmerge.c:735 -msgid "no overlap" +#: libvips/mosaicing/match.c:285 libvips/mosaicing/mosaic1.c:594 +msgid "Search to improve tie-points" msgstr "" -#: ../libvips/mosaicing/mosaic.c:176 -msgid "mosaic two images" +#: libvips/mosaicing/match.c:291 libvips/mosaicing/mosaic1.c:600 +#: libvips/resample/affine.c:651 libvips/resample/mapim.c:561 +#: libvips/resample/quadratic.c:351 libvips/resample/resize.c:376 +#: libvips/resample/similarity.c:127 +msgid "Interpolate" msgstr "" -#: ../libvips/mosaicing/mosaic.c:199 ../libvips/mosaicing/mosaic1.c:508 -msgid "Horizontal or vertcial mosaic" +#: libvips/mosaicing/match.c:292 libvips/mosaicing/mosaic1.c:601 +#: libvips/resample/affine.c:652 libvips/resample/mapim.c:562 +#: libvips/resample/resize.c:377 libvips/resample/similarity.c:128 +msgid "Interpolate pixels with this" msgstr "" -#: ../libvips/mosaicing/mosaic.c:205 -msgid "xref" +#: libvips/mosaicing/matrixinvert.c:312 libvips/mosaicing/matrixinvert.c:328 +#: libvips/mosaicing/matrixinvert.c:353 libvips/resample/transform.c:60 +msgid "singular or near-singular matrix" msgstr "" -#: ../libvips/mosaicing/mosaic.c:206 ../libvips/mosaicing/mosaic.c:213 -msgid "Position of reference tie-point" +#: libvips/mosaicing/matrixinvert.c:406 +msgid "non-square matrix" msgstr "" -#: ../libvips/mosaicing/mosaic.c:212 -msgid "yref" +#: libvips/mosaicing/matrixinvert.c:439 +msgid "invert an matrix" msgstr "" -#: ../libvips/mosaicing/mosaic.c:219 -msgid "xsec" +#: libvips/mosaicing/matrixinvert.c:444 +msgid "An square matrix" msgstr "" -#: ../libvips/mosaicing/mosaic.c:220 ../libvips/mosaicing/mosaic.c:227 -msgid "Position of secondary tie-point" +#: libvips/mosaicing/matrixinvert.c:450 +msgid "Output matrix" msgstr "" -#: ../libvips/mosaicing/mosaic.c:226 -msgid "ysec" +#: libvips/mosaicing/merge.c:116 +msgid "merge two images" msgstr "" -#: ../libvips/mosaicing/mosaic.c:233 ../libvips/mosaicing/match.c:278 -#: ../libvips/mosaicing/mosaic1.c:570 -msgid "hwindow" +#: libvips/mosaicing/merge.c:141 +msgid "Horizontal or vertical merge" msgstr "" -#: ../libvips/mosaicing/mosaic.c:234 ../libvips/mosaicing/match.c:279 -#: ../libvips/mosaicing/mosaic1.c:571 -msgid "Half window size" +#: libvips/mosaicing/merge.c:147 +msgid "dx" msgstr "" -#: ../libvips/mosaicing/mosaic.c:240 ../libvips/mosaicing/match.c:285 -#: ../libvips/mosaicing/mosaic1.c:577 -msgid "harea" +#: libvips/mosaicing/merge.c:148 +msgid "Horizontal displacement from sec to ref" msgstr "" -#: ../libvips/mosaicing/mosaic.c:241 ../libvips/mosaicing/match.c:286 -#: ../libvips/mosaicing/mosaic1.c:578 -msgid "Half area size" +#: libvips/mosaicing/merge.c:154 +msgid "dy" msgstr "" -#: ../libvips/mosaicing/mosaic.c:254 ../libvips/mosaicing/mosaic1.c:604 -msgid "Search band" +#: libvips/mosaicing/merge.c:155 +msgid "Vertical displacement from sec to ref" msgstr "" -#: ../libvips/mosaicing/mosaic.c:255 ../libvips/mosaicing/mosaic1.c:605 -msgid "Band to search for features on" +#: libvips/mosaicing/merge.c:161 libvips/mosaicing/mosaic1.c:606 +#: libvips/mosaicing/mosaic.c:246 +msgid "Max blend" msgstr "" -#: ../libvips/mosaicing/mosaic.c:261 ../libvips/mosaicing/mosaic.c:268 -msgid "Integer offset" +#: libvips/mosaicing/merge.c:162 libvips/mosaicing/mosaic1.c:607 +#: libvips/mosaicing/mosaic.c:247 +msgid "Maximum blend size" msgstr "" -#: ../libvips/mosaicing/mosaic.c:262 ../libvips/mosaicing/mosaic.c:269 -msgid "Detected integer offset" +#: libvips/mosaicing/mosaic1.c:494 +msgid "first-order mosaic of two images" msgstr "" -#: ../libvips/mosaicing/mosaic.c:276 -msgid "Detected scale" +#: libvips/mosaicing/mosaic1.c:517 libvips/mosaicing/mosaic.c:198 +msgid "Horizontal or vertical mosaic" msgstr "" -#: ../libvips/mosaicing/mosaic.c:283 -msgid "Detected rotation" +#: libvips/mosaicing/mosaic1.c:613 libvips/mosaicing/mosaic.c:253 +msgid "Search band" msgstr "" -#: ../libvips/mosaicing/mosaic.c:289 ../libvips/mosaicing/mosaic.c:296 -msgid "First-order displacement" +#: libvips/mosaicing/mosaic1.c:614 libvips/mosaicing/mosaic.c:254 +msgid "Band to search for features on" msgstr "" -#: ../libvips/mosaicing/mosaic.c:290 ../libvips/mosaicing/mosaic.c:297 -msgid "Detected first-order displacement" +#: libvips/mosaicing/mosaic.c:175 +msgid "mosaic two images" msgstr "" -#: ../libvips/mosaicing/im_clinear.c:137 -msgid "im_invmat failed" +#: libvips/mosaicing/mosaic.c:204 +msgid "xref" msgstr "" -#: ../libvips/mosaicing/match.c:200 -msgid "first-order match of two images" +#: libvips/mosaicing/mosaic.c:205 libvips/mosaicing/mosaic.c:212 +msgid "Position of reference tie-point" msgstr "" -#: ../libvips/mosaicing/match.c:222 ../libvips/mosaicing/mosaic1.c:514 -msgid "xr1" +#: libvips/mosaicing/mosaic.c:211 +msgid "yref" msgstr "" -#: ../libvips/mosaicing/match.c:223 ../libvips/mosaicing/match.c:230 -#: ../libvips/mosaicing/mosaic1.c:515 ../libvips/mosaicing/mosaic1.c:522 -msgid "Position of first reference tie-point" +#: libvips/mosaicing/mosaic.c:218 +msgid "xsec" msgstr "" -#: ../libvips/mosaicing/match.c:229 ../libvips/mosaicing/mosaic1.c:521 -msgid "yr1" +#: libvips/mosaicing/mosaic.c:219 libvips/mosaicing/mosaic.c:226 +msgid "Position of secondary tie-point" msgstr "" -#: ../libvips/mosaicing/match.c:236 ../libvips/mosaicing/mosaic1.c:528 -msgid "xs1" +#: libvips/mosaicing/mosaic.c:225 +msgid "ysec" msgstr "" -#: ../libvips/mosaicing/match.c:237 ../libvips/mosaicing/match.c:244 -#: ../libvips/mosaicing/mosaic1.c:529 ../libvips/mosaicing/mosaic1.c:536 -msgid "Position of first secondary tie-point" +#: libvips/mosaicing/mosaic.c:260 libvips/mosaicing/mosaic.c:267 +msgid "Integer offset" msgstr "" -#: ../libvips/mosaicing/match.c:243 ../libvips/mosaicing/mosaic1.c:535 -msgid "ys1" +#: libvips/mosaicing/mosaic.c:261 libvips/mosaicing/mosaic.c:268 +msgid "Detected integer offset" msgstr "" -#: ../libvips/mosaicing/match.c:250 ../libvips/mosaicing/mosaic1.c:542 -msgid "xr2" +#: libvips/mosaicing/mosaic.c:275 +msgid "Detected scale" msgstr "" -#: ../libvips/mosaicing/match.c:251 ../libvips/mosaicing/match.c:258 -#: ../libvips/mosaicing/mosaic1.c:543 ../libvips/mosaicing/mosaic1.c:550 -msgid "Position of second reference tie-point" +#: libvips/mosaicing/mosaic.c:282 +msgid "Detected rotation" msgstr "" -#: ../libvips/mosaicing/match.c:257 ../libvips/mosaicing/mosaic1.c:549 -msgid "yr2" +#: libvips/mosaicing/mosaic.c:288 libvips/mosaicing/mosaic.c:295 +msgid "First-order displacement" msgstr "" -#: ../libvips/mosaicing/match.c:264 ../libvips/mosaicing/mosaic1.c:556 -msgid "xs2" +#: libvips/mosaicing/mosaic.c:289 libvips/mosaicing/mosaic.c:296 +msgid "Detected first-order displacement" msgstr "" -#: ../libvips/mosaicing/match.c:265 ../libvips/mosaicing/match.c:272 -#: ../libvips/mosaicing/mosaic1.c:557 ../libvips/mosaicing/mosaic1.c:564 -msgid "Position of second secondary tie-point" +#: libvips/mosaicing/remosaic.c:89 +#, c-format +msgid "file \"%s\" not found" msgstr "" -#: ../libvips/mosaicing/match.c:271 ../libvips/mosaicing/mosaic1.c:563 -msgid "ys2" +#: libvips/mosaicing/remosaic.c:117 +#, c-format +msgid "substitute image \"%s\" is not the same size as \"%s\"" msgstr "" -#: ../libvips/mosaicing/match.c:292 ../libvips/mosaicing/mosaic1.c:584 -msgid "search" +#: libvips/mosaicing/remosaic.c:160 +msgid "rebuild an mosaiced image" msgstr "" -#: ../libvips/mosaicing/match.c:293 ../libvips/mosaicing/mosaic1.c:585 -msgid "Search to improve tie-points" +#: libvips/mosaicing/remosaic.c:176 +msgid "old_str" msgstr "" -#: ../libvips/mosaicing/match.c:299 ../libvips/mosaicing/mosaic1.c:591 -#: ../libvips/resample/affine.c:568 ../libvips/resample/mapim.c:418 -#: ../libvips/resample/resize.c:384 ../libvips/resample/quadratic.c:354 -#: ../libvips/resample/similarity.c:185 -msgid "Interpolate" +#: libvips/mosaicing/remosaic.c:177 +msgid "Search for this string" msgstr "" -#: ../libvips/mosaicing/match.c:300 ../libvips/mosaicing/mosaic1.c:592 -#: ../libvips/resample/affine.c:569 ../libvips/resample/mapim.c:419 -#: ../libvips/resample/resize.c:385 ../libvips/resample/similarity.c:186 -msgid "Interpolate pixels with this" +#: libvips/mosaicing/remosaic.c:183 +msgid "new_str" msgstr "" -#: ../libvips/mosaicing/mosaic1.c:485 -msgid "first-order mosaic of two images" +#: libvips/mosaicing/remosaic.c:184 +msgid "And swap for this string" msgstr "" -#: ../libvips/resample/affine.c:486 +#: libvips/resample/affine.c:516 msgid "output coordinates out of range" msgstr "" -#: ../libvips/resample/affine.c:557 +#: libvips/resample/affine.c:640 msgid "affine transform of an image" msgstr "" -#: ../libvips/resample/affine.c:561 +#: libvips/resample/affine.c:644 msgid "Matrix" msgstr "" -#: ../libvips/resample/affine.c:562 +#: libvips/resample/affine.c:645 msgid "Transformation matrix" msgstr "" -#: ../libvips/resample/affine.c:574 +#: libvips/resample/affine.c:657 msgid "Output rect" msgstr "" -#: ../libvips/resample/affine.c:575 +#: libvips/resample/affine.c:658 msgid "Area of output to generate" msgstr "" -#: ../libvips/resample/affine.c:581 ../libvips/resample/affine.c:588 -#: ../libvips/resample/similarity.c:191 ../libvips/resample/similarity.c:198 +#: libvips/resample/affine.c:664 libvips/resample/affine.c:671 +#: libvips/resample/similarity.c:140 libvips/resample/similarity.c:147 msgid "Output offset" msgstr "" -#: ../libvips/resample/affine.c:582 ../libvips/resample/similarity.c:192 +#: libvips/resample/affine.c:665 libvips/resample/similarity.c:141 msgid "Horizontal output displacement" msgstr "" -#: ../libvips/resample/affine.c:589 ../libvips/resample/similarity.c:199 +#: libvips/resample/affine.c:672 libvips/resample/similarity.c:148 msgid "Vertical output displacement" msgstr "" -#: ../libvips/resample/affine.c:595 ../libvips/resample/affine.c:602 -#: ../libvips/resample/resize.c:368 ../libvips/resample/resize.c:375 -#: ../libvips/resample/similarity.c:205 ../libvips/resample/similarity.c:212 +#: libvips/resample/affine.c:678 libvips/resample/affine.c:685 +#: libvips/resample/resize.c:360 libvips/resample/resize.c:367 +#: libvips/resample/similarity.c:154 libvips/resample/similarity.c:161 msgid "Input offset" msgstr "" -#: ../libvips/resample/affine.c:596 ../libvips/resample/resize.c:369 -#: ../libvips/resample/similarity.c:206 +#: libvips/resample/affine.c:679 libvips/resample/resize.c:361 +#: libvips/resample/similarity.c:155 msgid "Horizontal input displacement" msgstr "" -#: ../libvips/resample/affine.c:603 ../libvips/resample/resize.c:376 -#: ../libvips/resample/similarity.c:213 +#: libvips/resample/affine.c:686 libvips/resample/resize.c:368 +#: libvips/resample/similarity.c:162 msgid "Vertical input displacement" msgstr "" -#: ../libvips/resample/shrinkv.c:344 ../libvips/resample/shrinkh.c:246 -msgid "shrink factors should be >= 1" +#: libvips/resample/bicubic.cpp:629 +msgid "bicubic interpolation (Catmull-Rom)" msgstr "" -#: ../libvips/resample/shrinkv.c:424 ../libvips/resample/reducev.cpp:895 -msgid "shrink an image vertically" +#: libvips/resample/interpolate.c:185 +msgid "VIPS interpolators" msgstr "" -#: ../libvips/resample/shrinkv.c:430 ../libvips/resample/reduce.c:141 -#: ../libvips/resample/shrink.c:137 ../libvips/resample/reducev.cpp:901 -msgid "Vshrink" +#: libvips/resample/interpolate.c:361 +msgid "nearest-neighbour interpolation" msgstr "" -#: ../libvips/resample/shrinkv.c:431 ../libvips/resample/shrinkv.c:440 -#: ../libvips/resample/reduce.c:142 ../libvips/resample/reduce.c:172 -#: ../libvips/resample/shrink.c:138 ../libvips/resample/shrink.c:161 -#: ../libvips/resample/reducev.cpp:902 ../libvips/resample/reducev.cpp:925 -msgid "Vertical shrink factor" +#: libvips/resample/interpolate.c:579 +msgid "bilinear interpolation" msgstr "" -#: ../libvips/resample/shrinkv.c:439 ../libvips/resample/reduce.c:171 -#: ../libvips/resample/shrink.c:160 ../libvips/resample/reducev.cpp:924 -msgid "Yshrink" +#: libvips/resample/lbb.cpp:872 +msgid "reduced halo bicubic" msgstr "" -#: ../libvips/resample/mapim.c:408 -msgid "resample with an mapim image" +#: libvips/resample/mapim.c:551 +msgid "resample with a map image" msgstr "" -#: ../libvips/resample/mapim.c:413 +#: libvips/resample/mapim.c:556 msgid "Index pixels with this" msgstr "" -#: ../libvips/resample/resize.c:331 -msgid "resize an image" -msgstr "" - -#: ../libvips/resample/resize.c:337 -msgid "Scale factor" -msgstr "" - -#: ../libvips/resample/resize.c:338 -msgid "Scale image by this factor" +#: libvips/resample/nohalo.cpp:1551 +msgid "edge sharpening resampler with halo reduction" msgstr "" -#: ../libvips/resample/resize.c:344 -msgid "Vertical scale factor" +#: libvips/resample/quadratic.c:269 +msgid "coefficient matrix must have width 2" msgstr "" -#: ../libvips/resample/resize.c:345 -msgid "Vertical scale image by this factor" +#: libvips/resample/quadratic.c:291 +msgid "coefficient matrix must have height 1, 3, 4 or 6" msgstr "" -#: ../libvips/resample/resize.c:351 ../libvips/resample/reduce.c:148 -#: ../libvips/resample/reduceh.cpp:575 ../libvips/resample/reducev.cpp:908 -msgid "Kernel" +#: libvips/resample/quadratic.c:341 +msgid "resample an image with a quadratic transform" msgstr "" -#: ../libvips/resample/resize.c:352 ../libvips/resample/reduce.c:149 -#: ../libvips/resample/reduceh.cpp:576 ../libvips/resample/reducev.cpp:909 -msgid "Resampling kernel" +#: libvips/resample/quadratic.c:345 +msgid "Coeff" msgstr "" -#: ../libvips/resample/resize.c:358 ../libvips/resample/reduce.c:155 -#: ../libvips/resample/reduceh.cpp:582 ../libvips/resample/reducev.cpp:915 -msgid "Centre" +#: libvips/resample/quadratic.c:346 +msgid "Coefficient matrix" msgstr "" -#: ../libvips/resample/resize.c:359 ../libvips/resample/reduce.c:156 -#: ../libvips/resample/reduceh.cpp:583 ../libvips/resample/reducev.cpp:916 -msgid "Use centre sampling convention" +#: libvips/resample/quadratic.c:352 +msgid "Interpolate values with this" msgstr "" -#: ../libvips/resample/reduce.c:128 +#: libvips/resample/reduce.c:199 msgid "reduce an image" msgstr "" -#: ../libvips/resample/reduce.c:134 ../libvips/resample/shrinkh.c:326 -#: ../libvips/resample/shrink.c:144 ../libvips/resample/reduceh.cpp:568 +#: libvips/resample/reduce.c:205 libvips/resample/reduceh.cpp:586 +#: libvips/resample/shrink.c:149 libvips/resample/shrinkh.c:353 msgid "Hshrink" msgstr "" -#: ../libvips/resample/reduce.c:135 ../libvips/resample/reduce.c:165 -#: ../libvips/resample/shrinkh.c:327 ../libvips/resample/shrinkh.c:336 -#: ../libvips/resample/shrink.c:145 ../libvips/resample/shrink.c:154 -#: ../libvips/resample/reduceh.cpp:569 ../libvips/resample/reduceh.cpp:592 +#: libvips/resample/reduce.c:206 libvips/resample/reduce.c:236 +#: libvips/resample/reduceh.cpp:587 libvips/resample/reduceh.cpp:610 +#: libvips/resample/shrink.c:150 libvips/resample/shrink.c:166 +#: libvips/resample/shrinkh.c:354 libvips/resample/shrinkh.c:370 msgid "Horizontal shrink factor" msgstr "" -#: ../libvips/resample/reduce.c:164 ../libvips/resample/shrinkh.c:335 -#: ../libvips/resample/shrink.c:153 ../libvips/resample/reduceh.cpp:591 -msgid "Xshrink" -msgstr "" - -#: ../libvips/resample/shrinkh.c:320 ../libvips/resample/reduceh.cpp:562 -msgid "shrink an image horizontally" -msgstr "" - -#: ../libvips/resample/resample.c:128 -msgid "resample operations" -msgstr "" - -#: ../libvips/resample/quadratic.c:270 -msgid "coefficient matrix must have width 2" -msgstr "" - -#: ../libvips/resample/quadratic.c:292 -msgid "coefficient matrix must have height 1, 3, 4 or 6" -msgstr "" - -#: ../libvips/resample/quadratic.c:344 -msgid "resample an image with a quadratic transform" +#: libvips/resample/reduce.c:212 libvips/resample/reducev.cpp:1070 +#: libvips/resample/shrink.c:142 libvips/resample/shrinkv.c:427 +msgid "Vshrink" msgstr "" -#: ../libvips/resample/quadratic.c:348 -msgid "Coeff" +#: libvips/resample/reduce.c:213 libvips/resample/reduce.c:243 +#: libvips/resample/reducev.cpp:1071 libvips/resample/reducev.cpp:1094 +#: libvips/resample/shrink.c:143 libvips/resample/shrink.c:173 +#: libvips/resample/shrinkv.c:428 libvips/resample/shrinkv.c:444 +msgid "Vertical shrink factor" msgstr "" -#: ../libvips/resample/quadratic.c:349 -msgid "Coefficient matrix" +#: libvips/resample/reduce.c:219 libvips/resample/reduceh.cpp:593 +#: libvips/resample/reducev.cpp:1077 libvips/resample/resize.c:343 +msgid "Kernel" msgstr "" -#: ../libvips/resample/quadratic.c:355 -msgid "Interpolate values with this" +#: libvips/resample/reduce.c:220 libvips/resample/reduceh.cpp:594 +#: libvips/resample/reducev.cpp:1078 libvips/resample/resize.c:344 +msgid "Resampling kernel" msgstr "" -#: ../libvips/resample/thumbnail.c:436 -#, c-format -msgid "unable to import with embedded profile: %s" +#: libvips/resample/reduce.c:226 libvips/resample/reduceh.cpp:600 +#: libvips/resample/reducev.cpp:1084 libvips/resample/resize.c:350 +msgid "Gap" msgstr "" -#: ../libvips/resample/thumbnail.c:516 -msgid "thumbnail generation" +#: libvips/resample/reduce.c:227 libvips/resample/reduceh.cpp:601 +#: libvips/resample/reducev.cpp:1085 libvips/resample/resize.c:351 +msgid "Reducing gap" msgstr "" -#: ../libvips/resample/thumbnail.c:526 -msgid "Target width" +#: libvips/resample/reduce.c:235 libvips/resample/reduceh.cpp:609 +#: libvips/resample/shrink.c:165 libvips/resample/shrinkh.c:369 +msgid "Xshrink" msgstr "" -#: ../libvips/resample/thumbnail.c:527 -msgid "Size to this width" +#: libvips/resample/reduce.c:242 libvips/resample/reducev.cpp:1093 +#: libvips/resample/shrink.c:172 libvips/resample/shrinkv.c:443 +msgid "Yshrink" msgstr "" -#: ../libvips/resample/thumbnail.c:533 -msgid "Target height" +#: libvips/resample/reduce.c:251 libvips/resample/reduceh.cpp:618 +#: libvips/resample/reducev.cpp:1102 libvips/resample/resize.c:384 +msgid "Centre" msgstr "" -#: ../libvips/resample/thumbnail.c:534 -msgid "Size to this height" +#: libvips/resample/reduce.c:252 libvips/resample/reduceh.cpp:619 +#: libvips/resample/reducev.cpp:1103 libvips/resample/resize.c:385 +msgid "Use centre sampling convention" msgstr "" -#: ../libvips/resample/thumbnail.c:540 -msgid "size" +#: libvips/resample/reduceh.cpp:414 libvips/resample/reducev.cpp:848 +msgid "reduce factor should be >= 1.0" msgstr "" -#: ../libvips/resample/thumbnail.c:541 -msgid "Only upsize, only downsize, or both" +#: libvips/resample/reduceh.cpp:437 libvips/resample/reducev.cpp:870 +msgid "reduce gap should be >= 1.0" msgstr "" -#: ../libvips/resample/thumbnail.c:547 -msgid "Auto rotate" +#: libvips/resample/reduceh.cpp:467 libvips/resample/reducev.cpp:900 +msgid "reduce factor too large" msgstr "" -#: ../libvips/resample/thumbnail.c:548 -msgid "Use orientation tags to rotate image upright" +#: libvips/resample/reduceh.cpp:580 libvips/resample/shrinkh.c:347 +msgid "shrink an image horizontally" msgstr "" -#: ../libvips/resample/thumbnail.c:554 -msgid "Crop" +#: libvips/resample/reducev.cpp:1064 libvips/resample/shrinkv.c:421 +msgid "shrink an image vertically" msgstr "" -#: ../libvips/resample/thumbnail.c:555 -msgid "Reduce to fill target rectangle, then crop" +#: libvips/resample/resample.c:136 +msgid "resample operations" msgstr "" -#: ../libvips/resample/thumbnail.c:561 -msgid "Linear" +#: libvips/resample/resize.c:323 +msgid "resize an image" msgstr "" -#: ../libvips/resample/thumbnail.c:562 -msgid "Reduce in linear light" +#: libvips/resample/resize.c:329 +msgid "Scale factor" msgstr "" -#: ../libvips/resample/thumbnail.c:568 -msgid "Import profile" +#: libvips/resample/resize.c:330 +msgid "Scale image by this factor" msgstr "" -#: ../libvips/resample/thumbnail.c:569 -msgid "Fallback import profile" +#: libvips/resample/resize.c:336 +msgid "Vertical scale factor" msgstr "" -#: ../libvips/resample/thumbnail.c:575 -msgid "Export profile" +#: libvips/resample/resize.c:337 +msgid "Vertical scale image by this factor" msgstr "" -#: ../libvips/resample/thumbnail.c:576 -msgid "Fallback export profile" +#: libvips/resample/shrink.c:133 +msgid "shrink an image" msgstr "" -#: ../libvips/resample/thumbnail.c:663 -msgid "generate thumbnail from file" +#: libvips/resample/shrink.c:156 libvips/resample/shrinkh.c:360 +#: libvips/resample/shrinkv.c:434 +msgid "Ceil" msgstr "" -#: ../libvips/resample/thumbnail.c:670 -msgid "Filename to read from" +#: libvips/resample/shrink.c:157 libvips/resample/shrinkh.c:361 +#: libvips/resample/shrinkv.c:435 +msgid "Round-up output dimensions" msgstr "" -#: ../libvips/resample/thumbnail.c:830 -msgid "generate thumbnail from buffer" +#: libvips/resample/shrinkh.c:283 libvips/resample/shrinkv.c:327 +msgid "shrink factors should be >= 1" msgstr "" -#: ../libvips/resample/shrink.c:128 -msgid "shrink an image" +#: libvips/resample/similarity.c:123 +msgid "base similarity transform" msgstr "" -#: ../libvips/resample/similarity.c:167 +#: libvips/resample/similarity.c:197 msgid "similarity transform of an image" msgstr "" -#: ../libvips/resample/similarity.c:172 +#: libvips/resample/similarity.c:201 msgid "Scale by this factor" msgstr "" -#: ../libvips/resample/similarity.c:179 -msgid "Rotate anticlockwise by this many degrees" -msgstr "" - -#: ../libvips/resample/interpolate.c:183 -msgid "VIPS interpolators" +#: libvips/resample/similarity.c:208 libvips/resample/similarity.c:277 +msgid "Rotate clockwise by this many degrees" msgstr "" -#: ../libvips/resample/interpolate.c:359 -msgid "nearest-neighbour interpolation" +#: libvips/resample/similarity.c:273 +msgid "rotate an image by a number of degrees" msgstr "" -#: ../libvips/resample/interpolate.c:556 -msgid "bilinear interpolation" +#: libvips/resample/thumbnail.c:959 +msgid "thumbnail generation" msgstr "" -#: ../libvips/video/im_video_test.c:52 -msgid "error requested" +#: libvips/resample/thumbnail.c:974 +msgid "Target width" msgstr "" -#: ../tools/vips.c:154 -#, c-format -msgid "'%s' is not the name of a vips class" +#: libvips/resample/thumbnail.c:975 +msgid "Size to this width" msgstr "" -#: ../tools/vips.c:170 -msgid "list objects" +#: libvips/resample/thumbnail.c:981 +msgid "Target height" msgstr "" -#: ../tools/vips.c:171 -msgid "BASE-NAME" +#: libvips/resample/thumbnail.c:982 +msgid "Size to this height" msgstr "" -#: ../tools/vips.c:173 -msgid "load PLUGIN" +#: libvips/resample/thumbnail.c:989 +msgid "Only upsize, only downsize, or both" msgstr "" -#: ../tools/vips.c:174 -msgid "PLUGIN" +#: libvips/resample/thumbnail.c:995 +msgid "No rotate" msgstr "" -#: ../tools/vips.c:176 -msgid "print version" +#: libvips/resample/thumbnail.c:996 +msgid "Don't use orientation tags to rotate image upright" msgstr "" -#: ../tools/vips.c:219 -#, c-format -msgid "no package or function \"%s\"" +#: libvips/resample/thumbnail.c:1002 +msgid "Crop" msgstr "" -#: ../tools/vips.c:1000 -msgid "list classes|packages|all|package-name|operation-name" +#: libvips/resample/thumbnail.c:1003 +msgid "Reduce to fill target rectangle, then crop" msgstr "" -#: ../tools/vips.c:1002 -msgid "generate headers for C++ binding" +#: libvips/resample/thumbnail.c:1009 +msgid "Linear" msgstr "" -#: ../tools/vips.c:1004 -msgid "generate bodies for C++ binding" +#: libvips/resample/thumbnail.c:1010 +msgid "Reduce in linear light" msgstr "" -#: ../tools/vips.c:1006 -msgid "generate links for vips/bin" +#: libvips/resample/thumbnail.c:1016 +msgid "Import profile" msgstr "" -#: ../tools/vips.c:1008 -msgid "list possible actions" +#: libvips/resample/thumbnail.c:1017 +msgid "Fallback import profile" msgstr "" -#: ../tools/vips.c:1027 -msgid "execute vips operation OPER" +#: libvips/resample/thumbnail.c:1023 +msgid "Export profile" msgstr "" -#: ../tools/vips.c:1070 -msgid "Operation help" +#: libvips/resample/thumbnail.c:1024 +msgid "Fallback export profile" msgstr "" -#: ../tools/vips.c:1116 -msgid "[ACTION] [OPTIONS] [PARAMETERS] - VIPS driver program" +#: libvips/resample/thumbnail.c:1050 +msgid "Auto rotate" msgstr "" -#: ../tools/vips.c:1300 -#, c-format -msgid "unknown action \"%s\"" +#: libvips/resample/thumbnail.c:1051 +msgid "Use orientation tags to rotate image upright" msgstr "" -#: ../tools/vipsedit.c:83 -msgid "tag file as big or little-endian" +#: libvips/resample/thumbnail.c:1192 +msgid "generate thumbnail from file" msgstr "" -#: ../tools/vipsedit.c:85 -msgid "set width to N pixels" +#: libvips/resample/thumbnail.c:1199 +msgid "Filename to read from" msgstr "" -#: ../tools/vipsedit.c:87 -msgid "set height to N pixels" +#: libvips/resample/thumbnail.c:1439 +msgid "generate thumbnail from buffer" msgstr "" -#: ../tools/vipsedit.c:89 -msgid "set Bands to N" -msgstr "" +#: libvips/resample/thumbnail.c:1452 libvips/resample/thumbnail.c:1665 +#, fuzzy +msgid "Extra options" +msgstr "colour operations" -#: ../tools/vipsedit.c:91 -msgid "set BandFmt to F (eg. uchar, float)" +#: libvips/resample/thumbnail.c:1453 libvips/resample/thumbnail.c:1666 +msgid "Options that are passed on to the underlying loader" msgstr "" -#: ../tools/vipsedit.c:93 -msgid "set interpretation to I (eg. xyz)" +#: libvips/resample/thumbnail.c:1652 +msgid "generate thumbnail from source" msgstr "" -#: ../tools/vipsedit.c:95 -msgid "set Coding to C (eg. labq)" +#: libvips/resample/thumbnail.c:1776 +msgid "generate thumbnail from image" msgstr "" -#: ../tools/vipsedit.c:97 -msgid "set Xres to R pixels/mm" +#: libvips/resample/vsqbs.cpp:378 +msgid "B-Splines with antialiasing smoothing" msgstr "" -#: ../tools/vipsedit.c:99 -msgid "set Yres to R pixels/mm" +#: tools/vips.c:166 +#, c-format +msgid "'%s' is not the name of a vips class" msgstr "" -#: ../tools/vipsedit.c:101 -msgid "set Xoffset to N pixels" +#: tools/vips.c:282 +#, c-format +msgid "'%s' is not the name of a vips operation" msgstr "" -#: ../tools/vipsedit.c:103 -msgid "set Yoffset to N pixels" +#: tools/vips.c:355 +#, c-format +msgid "no package or function \"%s\"" msgstr "" -#: ../tools/vipsedit.c:105 -msgid "replace extension block with stdin" +#: tools/vips.c:584 +msgid "execute vips operation OPER" msgstr "" -#: ../tools/vipsedit.c:107 -msgid "set Xsize to N (deprecated, use width)" +#: tools/vips.c:627 +msgid "Operation help" msgstr "" -#: ../tools/vipsedit.c:109 -msgid "set Ysize to N (deprecated, use height)" +#: tools/vips.c:706 +msgid "[ACTION] [OPTIONS] [PARAMETERS] - VIPS driver program" msgstr "" -#: ../tools/vipsedit.c:111 -msgid "set Type to T (deprecated, use interpretation)" +#: tools/vips.c:916 +#, c-format +msgid "unknown action \"%s\"" msgstr "" -#: ../tools/vipsedit.c:122 +#: tools/vipsedit.c:129 #, c-format msgid "'%s' is not a positive integer" msgstr "" -#: ../tools/vipsedit.c:135 +#: tools/vipsedit.c:142 msgid "unable to start VIPS" msgstr "" -#: ../tools/vipsedit.c:147 +#: tools/vipsedit.c:165 msgid "vipsedit - edit vips file header" msgstr "" -#: ../tools/vipsedit.c:175 +#: tools/vipsedit.c:193 #, c-format msgid "usage: %s [OPTION...] vips-file\n" msgstr "" -#: ../tools/vipsedit.c:182 +#: tools/vipsedit.c:200 #, c-format msgid "could not open image %s" msgstr "" -#: ../tools/vipsedit.c:185 +#: tools/vipsedit.c:206 #, c-format msgid "could not read VIPS header for %s" msgstr "" -#: ../tools/vipsedit.c:194 +#: tools/vipsedit.c:216 #, c-format msgid "bad endian-ness %s, should be 'big' or 'little'" msgstr "" -#: ../tools/vipsedit.c:207 +#: tools/vipsedit.c:230 #, c-format msgid "bad format %s" msgstr "" -#: ../tools/vipsedit.c:215 +#: tools/vipsedit.c:244 #, c-format msgid "bad interpretation %s" msgstr "" -#: ../tools/vipsedit.c:223 +#: tools/vipsedit.c:254 #, c-format msgid "bad coding %s" msgstr "" -#: ../tools/vipsedit.c:236 +#: tools/vipsedit.c:268 #, c-format msgid "could not seek on %s" msgstr "" -#: ../tools/vipsedit.c:239 +#: tools/vipsedit.c:271 #, c-format msgid "could not write to %s" msgstr "" -#: ../tools/vipsedit.c:246 +#: tools/vipsedit.c:278 msgid "could not get ext data" msgstr "" -#: ../tools/vipsedit.c:255 +#: tools/vipsedit.c:287 msgid "could not set extension" msgstr "" -#: ../tools/vipsheader.c:88 -msgid "show all fields" -msgstr "" - -#: ../tools/vipsheader.c:90 -msgid "" -"print value of FIELD (\"getext\" reads extension block, \"Hist\" reads image " -"history)" -msgstr "" - -#: ../tools/vipsheader.c:181 +#: tools/vipsheader.c:221 msgid "- print image header" msgstr "" -#: ../tools/vipsthumbnail.c:136 -msgid "shrink to SIZE or to WIDTHxHEIGHT" -msgstr "" - -#: ../tools/vipsthumbnail.c:137 -msgid "SIZE" -msgstr "" - -#: ../tools/vipsthumbnail.c:140 -msgid "set output to FORMAT" -msgstr "" - -#: ../tools/vipsthumbnail.c:141 ../tools/vipsthumbnail.c:145 -msgid "FORMAT" -msgstr "" - -#: ../tools/vipsthumbnail.c:144 -msgid "set output format string to FORMAT" -msgstr "" - -#: ../tools/vipsthumbnail.c:148 -msgid "export with PROFILE" +#: tools/vipsthumbnail.c:447 +msgid "bad geometry spec" msgstr "" -#: ../tools/vipsthumbnail.c:149 ../tools/vipsthumbnail.c:153 -msgid "PROFILE" -msgstr "" - -#: ../tools/vipsthumbnail.c:152 -msgid "import untagged images with PROFILE" -msgstr "" - -#: ../tools/vipsthumbnail.c:156 -msgid "process in linear space" -msgstr "" - -#: ../tools/vipsthumbnail.c:159 -msgid "crop exactly to SIZE" -msgstr "" - -#: ../tools/vipsthumbnail.c:162 -msgid "auto-rotate" -msgstr "" - -#: ../tools/vipsthumbnail.c:165 -msgid "delete profile from exported image" -msgstr "" - -#: ../tools/vipsthumbnail.c:169 ../tools/vipsthumbnail.c:172 -#: ../tools/vipsthumbnail.c:175 ../tools/vipsthumbnail.c:178 -#: ../tools/vipsthumbnail.c:181 -msgid "(deprecated, does nothing)" -msgstr "" - -#: ../tools/vipsthumbnail.c:375 +#: tools/vipsthumbnail.c:516 msgid "- thumbnail generator" msgstr "" -#: ../libvips/resample/reduceh.cpp:457 -msgid "reduce factors should be >= 1" -msgstr "" - -#: ../libvips/resample/reduceh.cpp:471 ../libvips/resample/reducev.cpp:850 -msgid "reduce factor too large" -msgstr "" - -#: ../libvips/resample/bicubic.cpp:639 -msgid "bicubic interpolation (Catmull-Rom)" -msgstr "" - -#: ../libvips/resample/vsqbs.cpp:405 -msgid "B-Splines with antialiasing smoothing" -msgstr "" - -#: ../libvips/resample/nohalo.cpp:1586 -msgid "edge sharpening resampler with halo reduction" -msgstr "" - -#: ../libvips/resample/lbb.cpp:865 -msgid "reduced halo bicubic" -msgstr "" - -#: ../libvips/resample/reducev.cpp:839 -msgid "reduce factor should be >= 1" -msgstr "" +#~ msgid "Neither global nor local color map" +#~ msgstr "Neither global nor local colour map" diff --git a/tools/vips.c b/tools/vips.c index d3af6c35e2..377ddc090e 100644 --- a/tools/vips.c +++ b/tools/vips.c @@ -775,7 +775,7 @@ main(int argc, char **argv) #endif /*ENABLE_DEPRECATED*/ #else /*!ENABLE_MODULES*/ g_warning("plugin load disabled: " - "libvips built without modules support"); + "libvips built without modules support"); #endif /*ENABLE_MODULES*/ } diff --git a/tools/vipsthumbnail.c b/tools/vipsthumbnail.c index f94258ba62..3ff8c38a2f 100644 --- a/tools/vipsthumbnail.c +++ b/tools/vipsthumbnail.c @@ -547,7 +547,7 @@ main(int argc, char **argv) #ifndef HAVE_EXIF if (rotate_image) g_warning("auto-rotate disabled: " - "libvips built without exif support"); + "libvips built without exif support"); #endif /*!HAVE_EXIF*/ result = 0; From 0bf64e9b123da13eee4c81e19d5f1b9c7bce8277 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 31 Jan 2025 18:59:55 +0000 Subject: [PATCH 055/174] fix matrixload sniff for some matrix files (#4372) matrixload is_a could fail to detect files like this: ``` 2 2 0 0 1 1 ``` The header parser was not stopping at EOL and thought that this file had scale 0, which it would then reject. --- ChangeLog | 1 + libvips/foreign/matrixload.c | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index ae0098ca47..e08152e76e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,7 @@ - fill_nearest: fix a leak - colour: use suggested rendering intent as fallback [kleisauke] - morph: fix Orc path with large masks [kleisauke] +- matrixload: fix file format detect for some matrix types 10/10/24 8.16.0 diff --git a/libvips/foreign/matrixload.c b/libvips/foreign/matrixload.c index 651e5e9bfe..e27917176a 100644 --- a/libvips/foreign/matrixload.c +++ b/libvips/foreign/matrixload.c @@ -119,13 +119,15 @@ parse_matrix_header(char *line, char *p, *q; int i; - for (i = 0, p = line; - (q = vips_break_token(p, " \t")) && - i < 4; - i++, p = q) + /* Stop at newline. + */ + if ((p = strchr(line, '\r')) || + ((p = strchr(line, '\n')))) + *p = '\0'; + + for (i = 0, p = line; (q = vips_break_token(p, " \t")) && i < 4; i++, p = q) if (vips_strtod(p, &header[i])) { - vips_error("matload", - _("bad number \"%s\""), p); + vips_error("matload", _("bad number \"%s\""), p); return -1; } @@ -152,8 +154,7 @@ parse_matrix_header(char *line, *width > 100000 || *height <= 0 || *height > 100000) { - vips_error("mask2vips", - "%s", _("width / height out of range")); + vips_error("mask2vips", "%s", _("width / height out of range")); return -1; } if (header[2] == 0.0) { @@ -426,14 +427,12 @@ vips_foreign_load_matrix_source_is_a_source(VipsSource *source) double offset; int result; - if ((bytes_read = vips_source_sniff_at_most(source, - &data, 79)) <= 0) + if ((bytes_read = vips_source_sniff_at_most(source, &data, 79)) <= 0) return FALSE; g_strlcpy(line, (const char *) data, 80); vips_error_freeze(); - result = parse_matrix_header(line, - &width, &height, &scale, &offset); + result = parse_matrix_header(line, &width, &height, &scale, &offset); vips_error_thaw(); return result == 0; From 45315458c05ae70f34810932c78adda4593bbce6 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 31 Jan 2025 19:00:31 +0000 Subject: [PATCH 056/174] fix invertlut in some cases (#4373) If the measurements filled the entire x range, we were not writing the final value. For example: ``` 2 2 0 0 1 1 ``` ``` $ vips invertlut linear.mat x2.v $ vips getpoint x2.v 255 0 -nan ``` With this PR you get 1, as expected. --- ChangeLog | 1 + libvips/create/invertlut.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e08152e76e..2e9350d650 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,7 @@ - fill_nearest: fix a leak - colour: use suggested rendering intent as fallback [kleisauke] - morph: fix Orc path with large masks [kleisauke] +- invertlut: fix final value in some cases - matrixload: fix file format detect for some matrix types 10/10/24 8.16.0 diff --git a/libvips/create/invertlut.c b/libvips/create/invertlut.c index ff24aab7eb..02a89baa4c 100644 --- a/libvips/create/invertlut.c +++ b/libvips/create/invertlut.c @@ -212,7 +212,7 @@ vips_invertlut_build_create(VipsInvertlut *lut) /* Interpolate the data sections. */ - for (k = first; k < last; k++) { + for (k = first; k <= last; k++) { /* Where we're at in the [0,1] range. */ double ki = (double) k / (lut->size - 1); From b9e3074e6e0830f1af940e017d36e52c2d9b7b36 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 1 Feb 2025 13:01:17 +0000 Subject: [PATCH 057/174] add matrixmultiply (#4371) * add matrixmultiply needed for nip4 compat mode * fix matrixload sniff for some matrix files (#4372) matrixload is_a could fail to detect files like this: ``` 2 2 0 0 1 1 ``` The header parser was not stopping at EOL and thought that this file had scale 0, which it would then reject. * fix invertlut in some cases (#4373) If the measurements filled the entire x range, we were not writing the final value. For example: ``` 2 2 0 0 1 1 ``` ``` $ vips invertlut linear.mat x2.v $ vips getpoint x2.v 255 0 -nan ``` With this PR you get 1, as expected. --- ChangeLog | 1 + libvips/include/vips/mosaicing.h | 4 + libvips/mosaicing/matrixinvert.c | 2 +- libvips/mosaicing/matrixmultiply.c | 196 +++++++++++++++++++++++++++++ libvips/mosaicing/meson.build | 1 + libvips/mosaicing/mosaicing.c | 2 + 6 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 libvips/mosaicing/matrixmultiply.c diff --git a/ChangeLog b/ChangeLog index 7c5ff57b69..2debbc47b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ - tiffload: add support for unlimited flag (requires libtiff 4.7.0+) [lovell] - much more reliable operation caching - colour: add support for auto-selecting the rendering intent [kleisauke] +- add matrixmultiply 8.16.1 diff --git a/libvips/include/vips/mosaicing.h b/libvips/include/vips/mosaicing.h index 28388a55c4..0c794c9b8c 100644 --- a/libvips/include/vips/mosaicing.h +++ b/libvips/include/vips/mosaicing.h @@ -72,6 +72,10 @@ VIPS_API int vips_matrixinvert(VipsImage *m, VipsImage **out, ...) G_GNUC_NULL_TERMINATED; +VIPS_API +int vips_matrixmultiply(VipsImage *left, VipsImage *right, VipsImage **out, ...) + G_GNUC_NULL_TERMINATED; + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/mosaicing/matrixinvert.c b/libvips/mosaicing/matrixinvert.c index 22bbb1cc4a..818824e552 100644 --- a/libvips/mosaicing/matrixinvert.c +++ b/libvips/mosaicing/matrixinvert.c @@ -436,7 +436,7 @@ vips_matrixinvert_class_init(VipsMatrixinvertClass *class) gobject_class->get_property = vips_object_get_property; vobject_class->nickname = "matrixinvert"; - vobject_class->description = _("invert an matrix"); + vobject_class->description = _("invert a matrix"); vobject_class->build = vips_matrixinvert_build; VIPS_ARG_IMAGE(class, "in", 0, diff --git a/libvips/mosaicing/matrixmultiply.c b/libvips/mosaicing/matrixmultiply.c new file mode 100644 index 0000000000..b95e62336a --- /dev/null +++ b/libvips/mosaicing/matrixmultiply.c @@ -0,0 +1,196 @@ +/* Multiply two matrices. + * + * Copyright: 1990, K. Martinez and J. Cupitt + * + * 23/10/10 + * - gtk-doc + * 31/1/25 + * - wrapped as a class + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include + +#include + +/* Our state. + */ +typedef struct _VipsMatrixmultiply { + VipsOperation parent_instance; + + VipsImage *left; + VipsImage *right; + VipsImage *out; + + VipsImage *mat1; + VipsImage *mat2; + +} VipsMatrixmultiply; + +typedef VipsOperationClass VipsMatrixmultiplyClass; + +G_DEFINE_TYPE(VipsMatrixmultiply, vips_matrixmultiply, VIPS_TYPE_OPERATION); + +static void +vips_matrixmultiply_dispose(GObject *gobject) +{ + VipsMatrixmultiply *matrix = (VipsMatrixmultiply *) gobject; + + VIPS_UNREF(matrix->mat1); + VIPS_UNREF(matrix->mat2); + + G_OBJECT_CLASS(vips_matrixmultiply_parent_class)->dispose(gobject); +} + +static int +vips_matrixmultiply_build(VipsObject *object) +{ + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); + VipsMatrixmultiply *matrix = (VipsMatrixmultiply *) object; + + if (VIPS_OBJECT_CLASS(vips_matrixmultiply_parent_class)->build(object)) + return -1; + + if (vips_check_matrix(class->nickname, matrix->left, &matrix->mat1) || + vips_check_matrix(class->nickname, matrix->right, &matrix->mat2)) + return -1; + + if (matrix->mat1->Xsize != matrix->mat2->Ysize) { + vips_error(class->nickname, "%s", _("bad sizes")); + return -1; + } + + g_object_set(matrix, + "out", vips_image_new_matrix(matrix->mat2->Xsize, matrix->mat1->Ysize), + NULL); + + /* Multiply. + */ + double *out; + double *s1; + + s1 = VIPS_MATRIX(matrix->mat1, 0, 0); + out = VIPS_MATRIX(matrix->out, 0, 0); + for (int yc = 0; yc < matrix->mat1->Ysize; yc++) { + double *s2 = VIPS_MATRIX(matrix->mat2, 0, 0); + + for (int col = 0; col < matrix->mat2->Xsize; col++) { + /* Get ready to sweep a row. + */ + double *a = s1; + double *b = s2; + + double sum; + + sum = 0.0; + for (int xc = 0; xc < matrix->mat1->Xsize; xc++) { + sum += *a++ * *b; + b += matrix->mat2->Xsize; + } + + *out++ = sum; + s2 += 1; + } + + s1 += matrix->mat1->Xsize; + } + + return 0; +} + +static void +vips_matrixmultiply_class_init(VipsMatrixmultiplyClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(class); + VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS(class); + + gobject_class->dispose = vips_matrixmultiply_dispose; + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + vobject_class->nickname = "matrixmultiply"; + vobject_class->description = _("multiply two matrices"); + vobject_class->build = vips_matrixmultiply_build; + + VIPS_ARG_IMAGE(class, "left", 1, + _("Left"), + _("First matrix to multiply"), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET(VipsMatrixmultiply, left)); + + VIPS_ARG_IMAGE(class, "right", 2, + _("Right"), + _("Second matrix to multiply"), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET(VipsMatrixmultiply, right)); + + VIPS_ARG_IMAGE(class, "out", 3, + _("Output"), + _("Output matrix"), + VIPS_ARGUMENT_REQUIRED_OUTPUT, + G_STRUCT_OFFSET(VipsMatrixmultiply, out)); +} + +static void +vips_matrixmultiply_init(VipsMatrixmultiply *matrix) +{ +} + +/** + * vips_matrixmultiply: (method) + * @left: input matrix + * @right: input matrix + * @out: (out): output matrix + * @...: %NULL-terminated list of optional named arguments + * + * Multiplies two matrix images. + * + * The scale and offset members of @left and @right are ignored. + * + * See also: vips_matrixinvert(). + * + * Returns: 0 on success, -1 on error + */ +int +vips_matrixmultiply(VipsImage *left, VipsImage *right, VipsImage **out, ...) +{ + va_list ap; + int result; + + va_start(ap, out); + result = vips_call_split("matrixmultiply", ap, left, right, out); + va_end(ap); + + return result; +} diff --git a/libvips/mosaicing/meson.build b/libvips/mosaicing/meson.build index 224866465a..b82bb49e32 100644 --- a/libvips/mosaicing/meson.build +++ b/libvips/mosaicing/meson.build @@ -6,6 +6,7 @@ mosaicing_sources = files( 'mosaic1.c', 'chkpair.c', 'matrixinvert.c', + 'matrixmultiply.c', 'global_balance.c', 'lrmerge.c', 'tbmerge.c', diff --git a/libvips/mosaicing/mosaicing.c b/libvips/mosaicing/mosaicing.c index cc738b4208..eabbbba42e 100644 --- a/libvips/mosaicing/mosaicing.c +++ b/libvips/mosaicing/mosaicing.c @@ -97,11 +97,13 @@ vips_mosaicing_operation_init(void) extern GType vips_match_get_type(void); extern GType vips_globalbalance_get_type(void); extern GType vips_matrixinvert_get_type(void); + extern GType vips_matrixmultiply_get_type(void); vips_merge_get_type(); vips_mosaic_get_type(); vips_mosaic1_get_type(); vips_matrixinvert_get_type(); + vips_matrixmultiply_get_type(); vips_match_get_type(); vips_globalbalance_get_type(); } From beddac12972a0dbd9664995d51a7910e38dd10e2 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 7 Feb 2025 08:44:30 +0100 Subject: [PATCH 058/174] Fix typo in ChangeLog (#4378) --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2e9350d650..1b8ad61b34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,7 +13,7 @@ - heifsave: set image orientation using irot and imir transformations [lovell] - XYZ2Yxy: guard against divide by zero - fix MSVC compile error [na-trium-144] -- exif: ensure enumerated entries can to converted to string values [lovell] +- exif: ensure enumerated entries can be converted to string values [lovell] - gifsave: add support for eval callback, ensure correct return code [lovell] - tiffsave: honor disc threshold during pyramid save [kleisauke] - fill_nearest: fix a leak From 1eefd533c8a40897743bb8a00cd8416951253c3c Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 10 Feb 2025 10:00:37 +0100 Subject: [PATCH 059/174] Simplify Meson build definition (#4381) * Ensure consistent `ENABLE_*` macro checks * Inline if-statements in Meson build definition * Prefer use of `cc.get_define()` * Align config macro definitions --- libvips/iofuncs/image.c | 4 +- libvips/iofuncs/init.c | 10 +- libvips/iofuncs/thread.c | 2 +- libvips/iofuncs/vector.cpp | 2 +- meson.build | 299 +++++++++++++------------------------ tools/vips.c | 22 +-- 6 files changed, 120 insertions(+), 219 deletions(-) diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 5081c9d886..dba2089554 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -803,7 +803,7 @@ vips_image_add_progress(VipsImage *image) { if (vips__progress || g_getenv("VIPS_PROGRESS") -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED || g_getenv("IM_PROGRESS") #endif ) { @@ -2528,7 +2528,7 @@ vips_get_disc_threshold(void) threshold = 100 * 1024 * 1024; if ((env = g_getenv("VIPS_DISC_THRESHOLD")) -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED || (env = g_getenv("IM_DISC_THRESHOLD")) #endif ) diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 97ef911b2d..cf95ef9128 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -481,7 +481,7 @@ vips_init(const char *argv0) (void) set_stacksize(min_stack_size); if (g_getenv("VIPS_INFO") -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED || g_getenv("IM_INFO") #endif ) @@ -564,7 +564,7 @@ vips_init(const char *argv0) vips__meta_init_types(); vips__interpolate_init(); -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED im__format_init(); #endif @@ -604,7 +604,7 @@ vips_init(const char *argv0) vips_load_plugins("%s/vips-modules-%d.%d", libdir, VIPS_MAJOR_VERSION, VIPS_MINOR_VERSION); -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED /* We had vips8 plugins for a while. */ vips_load_plugins("%s/vips-plugins-%d.%d", @@ -646,7 +646,7 @@ vips_init(const char *argv0) * env var hack as a workaround. */ if (g_getenv("VIPS_WARNING") -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED || g_getenv("IM_WARNING") #endif ) @@ -726,7 +726,7 @@ vips_shutdown(void) vips_cache_drop_all(); -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED im_close_plugins(); #endif diff --git a/libvips/iofuncs/thread.c b/libvips/iofuncs/thread.c index 80a43f38de..5fbad04aca 100644 --- a/libvips/iofuncs/thread.c +++ b/libvips/iofuncs/thread.c @@ -198,7 +198,7 @@ vips__concurrency_get_default(void) nthr = vips__concurrency; else if ( ((str = g_getenv("VIPS_CONCURRENCY")) -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED || (str = g_getenv("IM_CONCURRENCY")) #endif ) && diff --git a/libvips/iofuncs/vector.cpp b/libvips/iofuncs/vector.cpp index 2c1802ce52..a0f92e760c 100644 --- a/libvips/iofuncs/vector.cpp +++ b/libvips/iofuncs/vector.cpp @@ -87,7 +87,7 @@ vips__vector_init(void) /* Look for the deprecated IM_NOVECTOR environment variable as well. */ if (g_getenv("VIPS_NOVECTOR") -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED || g_getenv("IM_NOVECTOR") #endif ) diff --git a/meson.build b/meson.build index 2bbb169401..1476a49ed2 100644 --- a/meson.build +++ b/meson.build @@ -36,15 +36,15 @@ i18n = import('i18n') # if we're optimising (eg. release mode) we turn off cast checks and g_asserts if get_option('optimization') not in ['0', 'g'] - add_project_arguments('-DG_DISABLE_CAST_CHECKS', language : ['cpp', 'c']) - add_project_arguments('-DG_DISABLE_CHECKS', language : ['cpp', 'c']) - add_project_arguments('-DG_DISABLE_ASSERT', language : ['cpp', 'c']) + add_project_arguments('-DG_DISABLE_CAST_CHECKS', language: ['cpp', 'c']) + add_project_arguments('-DG_DISABLE_CHECKS', language: ['cpp', 'c']) + add_project_arguments('-DG_DISABLE_ASSERT', language: ['cpp', 'c']) endif # in debug mode we automatically enable leak checks # also true for 'debugoptimized' if get_option('debug') - add_project_arguments('-DDEBUG_LEAK', language : ['cpp', 'c']) + add_project_arguments('-DDEBUG_LEAK', language: ['cpp', 'c']) endif host_os = host_machine.system() @@ -52,7 +52,7 @@ cc = meson.get_compiler('c') cpp = meson.get_compiler('cpp') # Prevent use of void* pointer arithmetic to support MSVC -add_project_arguments(cc.get_supported_arguments('-Werror=pointer-arith'), language : ['cpp', 'c']) +add_project_arguments(cc.get_supported_arguments('-Werror=pointer-arith'), language: ['cpp', 'c']) # libFuzzer related things fuzzing_engine = get_option('fuzzing_engine') @@ -61,7 +61,7 @@ if fuzzing_engine == 'libfuzzer' error('fuzzing_engine libfuzzer requires "-fsanitize=fuzzer"') endif fuzzer_args = ['-fsanitize=fuzzer-no-link', '-fsanitize=fuzzer'] - add_project_arguments(cc.first_supported_argument(fuzzer_args), language : ['cpp', 'c']) + add_project_arguments(cc.first_supported_argument(fuzzer_args), language: ['cpp', 'c']) endif glib_dep = dependency('glib-2.0', version: '>=2.52') @@ -115,9 +115,7 @@ module_dir = lib_dir / 'vips-modules-@0@.@1@'.format(version_major, version_mino cfg_var = configuration_data() cfg_var.set_quoted('G_LOG_DOMAIN', 'VIPS') -if modules_enabled - cfg_var.set('ENABLE_MODULES', '1') -endif +cfg_var.set('ENABLE_MODULES', modules_enabled) # Detect and set symbol visibility if get_option('default_library') == 'shared' and host_os in ['windows', 'cygwin'] @@ -152,10 +150,9 @@ h( v4f B ) } ''' -if cpp.compiles(vector_arithmetic_check, name: 'Has vector arithmetic', dependencies: m_dep) and \ - cpp.compiles(signed_constants_check, name: 'Has signed constants in vector templates', dependencies: m_dep) - cfg_var.set('HAVE_VECTOR_ARITH', '1') -endif +have_vector_artih = cpp.compiles(vector_arithmetic_check, name: 'Has vector arithmetic', dependencies: m_dep) and \ + cpp.compiles(signed_constants_check, name: 'Has signed constants in vector templates', dependencies: m_dep) +cfg_var.set('HAVE_VECTOR_ARITH', have_vector_artih) # HAVE_TARGET_CLONES target_clones_check = ''' @@ -175,38 +172,32 @@ if meson.can_run_host_binaries() else have_target_clones = cc.links(target_clones_check, args: '-Werror', name: 'Has target_clones attribute') endif -if have_target_clones - cfg_var.set('HAVE_TARGET_CLONES', '1') -endif +cfg_var.set('HAVE_TARGET_CLONES', have_target_clones) func_names = [ '_aligned_malloc', 'posix_memalign', 'memalign' ] foreach func_name : func_names - if cc.has_function(func_name) - cfg_var.set('HAVE_' + func_name.to_upper(), '1') - endif + cfg_var.set('HAVE_' + func_name.to_upper(), cc.has_function(func_name)) endforeach -if cc.has_function('pthread_setattr_default_np', args: '-D_GNU_SOURCE', prefix: '#include ', dependencies: thread_dep) - cfg_var.set('HAVE_PTHREAD_DEFAULT_NP', '1') -endif +cfg_var.set('HAVE_PTHREAD_DEFAULT_NP', cc.has_function('pthread_setattr_default_np', args: '-D_GNU_SOURCE', prefix: '#include ', dependencies: thread_dep)) # needed by rsvg and others zlib_dep = dependency('zlib', version: '>=0.4', required: get_option('zlib')) if zlib_dep.found() external_deps += zlib_dep - cfg_var.set('HAVE_ZLIB', '1') + cfg_var.set('HAVE_ZLIB', true) endif libarchive_dep = dependency('libarchive', version: '>=3.0.0', required: get_option('archive')) if libarchive_dep.found() external_deps += libarchive_dep - cfg_var.set('HAVE_LIBARCHIVE', '1') + cfg_var.set('HAVE_LIBARCHIVE', true) endif fftw_dep = dependency('fftw3', required: get_option('fftw')) if fftw_dep.found() external_deps += fftw_dep - cfg_var.set('HAVE_FFTW', '1') + cfg_var.set('HAVE_FFTW', true) endif # TODO: simplify this when requiring meson>=0.60.0 @@ -220,7 +211,7 @@ magick_module = false if magick_found magick_module = modules_enabled and not get_option('magick-module').disabled() if magick_module - cfg_var.set('MAGICK_MODULE', '1') + cfg_var.set('MAGICK_MODULE', true) module_deps += magick_dep else external_deps += magick_dep @@ -231,50 +222,37 @@ if magick_found # GM uses magick_include = magick7 ? '#include ' : '#include ' if magick7 - cfg_var.set('HAVE_MAGICK7', '1') + cfg_var.set('HAVE_MAGICK7', true) else # come here for imagemagick6, and graphicsmagick1.x, which also uses # the im6 API - cfg_var.set('HAVE_MAGICK6', '1') - if cc.has_member('struct _ImageInfo', 'number_scenes', prefix: magick_include, dependencies: magick_dep) - cfg_var.set('HAVE_NUMBER_SCENES', '1') - endif + cfg_var.set('HAVE_MAGICK6', true) + cfg_var.set('HAVE_NUMBER_SCENES', cc.has_member('struct _ImageInfo', 'number_scenes', prefix: magick_include, dependencies: magick_dep)) func_names = [ 'InheritException', 'AcquireExceptionInfo', 'SetImageProperty', 'SetImageExtent', 'AcquireImage', 'GetVirtualPixels', 'ResetImageProfileIterator', 'ResetImageAttributeIterator', 'ResetImagePropertyIterator', 'MagickCoreGenesis', 'SetImageOption', 'BlobToStringInfo', 'OptimizePlusImageLayers', 'OptimizeImageTransparency', 'GetMagicInfo' ] foreach func_name : func_names - if cc.has_function(func_name, prefix: magick_include, dependencies: magick_dep) - cfg_var.set('HAVE_' + func_name.to_upper(), '1') - endif + cfg_var.set('HAVE_' + func_name.to_upper(), cc.has_function(func_name, prefix: magick_include, dependencies: magick_dep)) endforeach - if cc.compiles(magick_include + '\nColorspaceType colorspace = CMYColorspace;', name: 'Has CMYColorspace', dependencies: magick_dep) - cfg_var.set('HAVE_CMYCOLORSPACE', '1') - endif - if cc.compiles(magick_include + '\nColorspaceType colorspace = HCLpColorspace;', name: 'Has HCLpColorspace', dependencies: magick_dep) - cfg_var.set('HAVE_HCLPCOLORSPACE', '1') - endif + cfg_var.set('HAVE_CMYCOLORSPACE', cc.compiles(magick_include + '\nColorspaceType colorspace = CMYColorspace;', name: 'Has CMYColorspace', dependencies: magick_dep)) + cfg_var.set('HAVE_HCLPCOLORSPACE', cc.compiles(magick_include + '\nColorspaceType colorspace = HCLpColorspace;', name: 'Has HCLpColorspace', dependencies: magick_dep)) # GetImageMagick() takes two args under GM, three under IM - if cc.compiles(magick_include + '\nint main() {(void)GetImageMagick(NULL, 0, NULL);}', name: 'GetImageMagick takes three arguments', dependencies: magick_dep) - cfg_var.set('HAVE_GETIMAGEMAGICK3', '1') - endif + cfg_var.set('HAVE_GETIMAGEMAGICK3', cc.compiles(magick_include + '\nint main() {(void)GetImageMagick(NULL, 0, NULL);}', name: 'GetImageMagick takes three arguments', dependencies: magick_dep)) endif - if 'load' in get_option('magick-features') - cfg_var.set('ENABLE_MAGICKLOAD', '1') - endif + magick_features = [ 'load', 'save' ] + foreach feature : magick_features + cfg_var.set('ENABLE_MAGICK' + feature.to_upper(), feature in get_option('magick-features')) + endforeach + if 'save' in get_option('magick-features') - cfg_var.set('ENABLE_MAGICKSAVE', '1') - if cc.has_function('ImportImagePixels', prefix: magick_include, dependencies: magick_dep) - cfg_var.set('HAVE_IMPORTIMAGEPIXELS', '1') - endif - if cc.has_function('ImagesToBlob', prefix: magick_include, dependencies: magick_dep) - cfg_var.set('HAVE_IMAGESTOBLOB', '1') - endif + cfg_var.set('HAVE_IMPORTIMAGEPIXELS', cc.has_function('ImportImagePixels', prefix: magick_include, dependencies: magick_dep)) + cfg_var.set('HAVE_IMAGESTOBLOB', cc.has_function('ImagesToBlob', prefix: magick_include, dependencies: magick_dep)) endif endif cfitsio_dep = dependency('cfitsio', required: get_option('cfitsio')) if cfitsio_dep.found() external_deps += cfitsio_dep - cfg_var.set('HAVE_CFITSIO', '1') + cfg_var.set('HAVE_CFITSIO', true) endif # quant package we use @@ -283,7 +261,7 @@ quantisation_package = disabler() imagequant_dep = dependency('imagequant', required: get_option('imagequant')) if imagequant_dep.found() external_deps += imagequant_dep - cfg_var.set('HAVE_IMAGEQUANT', '1') + cfg_var.set('HAVE_IMAGEQUANT', true) quantisation_package = imagequant_dep endif @@ -293,7 +271,7 @@ if not quantisation_package.found() quantizr_dep = dependency('quantizr', required: get_option('quantizr')) if quantizr_dep.found() external_deps += quantizr_dep - cfg_var.set('HAVE_QUANTIZR', '1') + cfg_var.set('HAVE_QUANTIZR', true) quantisation_package = quantizr_dep endif endif @@ -303,49 +281,35 @@ if quantisation_package.found() cgif_dep = dependency('cgif', version: '>=0.2.0', required: get_option('cgif')) if cgif_dep.found() external_deps += cgif_dep - cfg_var.set('HAVE_CGIF', '1') - if cc.compiles('#include \nint i = CGIF_ATTR_NO_LOOP;', name: 'Has CGIF_ATTR_NO_LOOP', dependencies: cgif_dep) - cfg_var.set('HAVE_CGIF_ATTR_NO_LOOP', '1') - endif - if cc.compiles('#include \nint i = CGIF_FRAME_ATTR_INTERLACED;', name: 'Has CGIF_FRAME_ATTR_INTERLACED', dependencies: cgif_dep) - cfg_var.set('HAVE_CGIF_FRAME_ATTR_INTERLACED', '1') - endif - if cc.compiles('#include \nint i = CGIF_GEN_KEEP_IDENT_FRAMES;', name: 'Has CGIF_GEN_KEEP_IDENT_FRAMES', dependencies: cgif_dep) - cfg_var.set('HAVE_CGIF_GEN_KEEP_IDENT_FRAMES', '1') - endif + cfg_var.set('HAVE_CGIF', true) + cfg_var.set('HAVE_CGIF_ATTR_NO_LOOP', cc.get_define('CGIF_ATTR_NO_LOOP', prefix: '#include ', dependencies: cgif_dep) != '') + cfg_var.set('HAVE_CGIF_FRAME_ATTR_INTERLACED', cc.get_define('CGIF_FRAME_ATTR_INTERLACED', prefix: '#include ', dependencies: cgif_dep) != '') + cfg_var.set('HAVE_CGIF_GEN_KEEP_IDENT_FRAMES', cc.get_define('CGIF_GEN_KEEP_IDENT_FRAMES', prefix: '#include ', dependencies: cgif_dep) != '') endif endif libexif_dep = dependency('libexif', version: '>=0.6', required: get_option('exif')) if libexif_dep.found() external_deps += libexif_dep - cfg_var.set('HAVE_EXIF', '1') + cfg_var.set('HAVE_EXIF', true) # some libexif packages need include , some just # how annoying - if cc.has_header('exif-data.h', dependencies: libexif_dep) - # libexif includes don't need libexif prefix - cfg_var.set('UNTAGGED_EXIF', '1') - endif + # libexif includes don't need libexif prefix + cfg_var.set('UNTAGGED_EXIF', cc.has_header('exif-data.h', dependencies: libexif_dep)) # 0.6.22 adds a couple of EXIF 2.3 ASCII tags - if libexif_dep.version().version_compare('>=0.6.22') - cfg_var.set('HAVE_EXIF_0_6_22', '1') - endif + cfg_var.set('HAVE_EXIF_0_6_22', libexif_dep.version().version_compare('>=0.6.22')) # 0.6.23 adds some OffsetTime* and GPS* ASCII tags - if libexif_dep.version().version_compare('>=0.6.23') - cfg_var.set('HAVE_EXIF_0_6_23', '1') - endif + cfg_var.set('HAVE_EXIF_0_6_23', libexif_dep.version().version_compare('>=0.6.23')) endif libjpeg_dep = dependency('libjpeg', required: get_option('jpeg')) if libjpeg_dep.found() external_deps += libjpeg_dep - cfg_var.set('HAVE_JPEG', '1') + cfg_var.set('HAVE_JPEG', true) # features like trellis quant are exposed as extension parameters ... # mozjpeg 3.2 and later have #define JPEG_C_PARAM_SUPPORTED, but we must # work with earlier versions - if cc.has_function('jpeg_c_bool_param_supported', prefix: '#include \n#include ', dependencies: libjpeg_dep) - cfg_var.set('HAVE_JPEG_EXT_PARAMS', '1') - endif + cfg_var.set('HAVE_JPEG_EXT_PARAMS', cc.has_function('jpeg_c_bool_param_supported', prefix: '#include \n#include ', dependencies: libjpeg_dep)) endif # png package we use @@ -362,7 +326,7 @@ if not spng_dep.found() endif if not get_option('spng').disabled() and spng_dep.found() external_deps += spng_dep - cfg_var.set('HAVE_SPNG', '1') + cfg_var.set('HAVE_SPNG', true) png_package = spng_dep endif @@ -371,10 +335,8 @@ if not png_package.found() png_dep = dependency('libpng', version: '>=1.2.9', required: get_option('png')) if png_dep.found() external_deps += png_dep - cfg_var.set('HAVE_PNG', '1') - if cc.has_function('png_set_chunk_malloc_max', prefix: '#include ', dependencies: png_dep) - cfg_var.set('HAVE_PNG_SET_CHUNK_MALLOC_MAX', '1') - endif + cfg_var.set('HAVE_PNG', true) + cfg_var.set('HAVE_PNG_SET_CHUNK_MALLOC_MAX', cc.has_function('png_set_chunk_malloc_max', prefix: '#include ', dependencies: png_dep)) png_package = png_dep endif endif @@ -387,13 +349,13 @@ if libwebp_dep.found() external_deps += libwebp_dep external_deps += dependency('libwebpmux', version: '>=0.6') external_deps += dependency('libwebpdemux', version: '>=0.6') - cfg_var.set('HAVE_LIBWEBP', '1') + cfg_var.set('HAVE_LIBWEBP', true) endif pangocairo_dep = dependency('pangocairo', version: '>=1.32.6', required: get_option('pangocairo')) if pangocairo_dep.found() external_deps += pangocairo_dep - cfg_var.set('HAVE_PANGOCAIRO', '1') + cfg_var.set('HAVE_PANGOCAIRO', true) endif # text rendering with fontconfig requires pangoft2 @@ -403,25 +365,19 @@ fontconfig_found = pangoft2_dep.found() and fontconfig_dep.found() and pangocair if fontconfig_found external_deps += pangoft2_dep external_deps += fontconfig_dep - cfg_var.set('HAVE_FONTCONFIG', '1') + cfg_var.set('HAVE_FONTCONFIG', true) endif libtiff_dep = dependency('libtiff-4', required: get_option('tiff')) if libtiff_dep.found() external_deps += libtiff_dep - cfg_var.set('HAVE_TIFF', '1') + cfg_var.set('HAVE_TIFF', true) # ZSTD and WEBP in TIFF added in libtiff 4.0.10 - if cc.get_define('COMPRESSION_WEBP', prefix: '#include ', dependencies: libtiff_dep) != '' - cfg_var.set('HAVE_TIFF_COMPRESSION_WEBP', '1') - endif + cfg_var.set('HAVE_TIFF_COMPRESSION_WEBP', cc.get_define('COMPRESSION_WEBP', prefix: '#include ', dependencies: libtiff_dep) != '') # TIFFOpenOptions added in libtiff 4.5.0 - if cc.has_function('TIFFOpenOptionsAlloc', prefix: '#include ', dependencies: libtiff_dep) - cfg_var.set('HAVE_TIFF_OPEN_OPTIONS', '1') - endif + cfg_var.set('HAVE_TIFF_OPEN_OPTIONS', cc.has_function('TIFFOpenOptionsAlloc', prefix: '#include ', dependencies: libtiff_dep)) # TIFFOpenOptionsSetMaxCumulatedMemAlloc added in libtiff 4.7.0 - if cc.has_function('TIFFOpenOptionsSetMaxCumulatedMemAlloc', prefix: '#include ', dependencies: libtiff_dep) - cfg_var.set('HAVE_TIFF_OPEN_OPTIONS_SET_MAX_CUMULATED_MEM_ALLOC', '1') - endif + cfg_var.set('HAVE_TIFF_OPEN_OPTIONS_SET_MAX_CUMULATED_MEM_ALLOC', cc.has_function('TIFFOpenOptionsSetMaxCumulatedMemAlloc', prefix: '#include ', dependencies: libtiff_dep)) endif # 2.40.3 so we get the UNLIMITED open flag @@ -431,7 +387,7 @@ librsvg_found = librsvg_dep.found() and cairo_dep.found() if librsvg_found external_deps += librsvg_dep external_deps += cairo_dep - cfg_var.set('HAVE_RSVG', '1') + cfg_var.set('HAVE_RSVG', true) endif openslide_dep = dependency('openslide', version: '>=3.3.0', required: get_option('openslide')) @@ -439,46 +395,41 @@ openslide_module = false if openslide_dep.found() openslide_module = modules_enabled and not get_option('openslide-module').disabled() if openslide_module - cfg_var.set('OPENSLIDE_MODULE', '1') + cfg_var.set('OPENSLIDE_MODULE', true) module_deps += openslide_dep else external_deps += openslide_dep endif - cfg_var.set('HAVE_OPENSLIDE', '1') - if openslide_dep.version().version_compare('>=3.4.0') - cfg_var.set('HAVE_OPENSLIDE_3_4', '1') - endif - - if cc.has_function('openslide_get_icc_profile_size', dependencies: openslide_dep) - cfg_var.set('HAVE_OPENSLIDE_ICC', '1') - endif + cfg_var.set('HAVE_OPENSLIDE', true) + cfg_var.set('HAVE_OPENSLIDE_3_4', openslide_dep.version().version_compare('>=3.4.0')) + cfg_var.set('HAVE_OPENSLIDE_ICC', cc.has_function('openslide_get_icc_profile_size', dependencies: openslide_dep)) endif matio_dep = dependency('matio', required: get_option('matio')) if matio_dep.found() external_deps += matio_dep - cfg_var.set('HAVE_MATIO', '1') + cfg_var.set('HAVE_MATIO', true) endif # lcms ... refuse to use lcms1 lcms_dep = dependency('lcms2', required: get_option('lcms')) if lcms_dep.found() external_deps += lcms_dep - cfg_var.set('HAVE_LCMS2', '1') + cfg_var.set('HAVE_LCMS2', true) endif # require 1.2.2 since 1.2.1 has a broken ImfCloseTiledInputFile() openexr_dep = dependency('OpenEXR', version: '>=1.2.2', required: get_option('openexr')) if openexr_dep.found() external_deps += openexr_dep - cfg_var.set('HAVE_OPENEXR', '1') + cfg_var.set('HAVE_OPENEXR', true) endif # 2.4 is the first one to have working threading and tiling libopenjp2_dep = dependency('libopenjp2', version: '>=2.4', required: get_option('openjpeg')) if libopenjp2_dep.found() external_deps += libopenjp2_dep - cfg_var.set('HAVE_LIBOPENJP2', '1') + cfg_var.set('HAVE_LIBOPENJP2', true) endif # simd package we use @@ -489,11 +440,9 @@ simd_package = disabler() libhwy_dep = dependency('libhwy', version: '>=1.0.5', required: get_option('highway')) if libhwy_dep.found() external_deps += libhwy_dep - cfg_var.set('HAVE_HWY', '1') + cfg_var.set('HAVE_HWY', true) # 1.1.0 adds `InterleaveWhole{Lower,Upper}` and `Dup128VecFromValues` - if libhwy_dep.version().version_compare('>=1.1.0') - cfg_var.set('HAVE_HWY_1_1_0', '1') - endif + cfg_var.set('HAVE_HWY_1_1_0', libhwy_dep.version().version_compare('>=1.1.0')) # Always disable SSSE3 since it is rare to have SSSE3 but not SSE4 disabled_targets = ['HWY_SSSE3'] # Optionally, build without AVX512 support (helps to reduce binary size at the cost of performance) @@ -510,12 +459,10 @@ if not simd_package.found() orc_dep = dependency('orc-0.4', version: '>=0.4.11', required: get_option('orc')) if orc_dep.found() external_deps += orc_dep - cfg_var.set('HAVE_ORC', '1') + cfg_var.set('HAVE_ORC', true) # orc 0.4.30+ works with cf-protection, but 0.4.30 has a bug with multiple # definitions of OrcTargetPowerPCFlags, so insist on 0.4.31 - if orc_dep.version().version_compare('>=0.4.31') - cfg_var.set('HAVE_ORC_CF_PROTECTION', '1') - endif + cfg_var.set('HAVE_ORC_CF_PROTECTION', orc_dep.version().version_compare('>=0.4.31')) simd_package = orc_dep endif endif @@ -528,7 +475,7 @@ pdf_loader = disabler() pdfium_dep = dependency('pdfium', version: '>=4200', required: get_option('pdfium')) if pdfium_dep.found() external_deps += pdfium_dep - cfg_var.set('HAVE_PDFIUM', '1') + cfg_var.set('HAVE_PDFIUM', true) pdf_loader = pdfium_dep endif @@ -537,49 +484,30 @@ libheif_module = false if libheif_dep.found() libheif_module = modules_enabled and not get_option('heif-module').disabled() if libheif_module - cfg_var.set('HEIF_MODULE', '1') + cfg_var.set('HEIF_MODULE', true) module_deps += libheif_dep else external_deps += libheif_dep endif - cfg_var.set('HAVE_HEIF', '1') + cfg_var.set('HAVE_HEIF', true) # added in 1.6.0 - if cpp.has_function('heif_image_handle_get_raw_color_profile', prefix: '#include ', dependencies: libheif_dep) - cfg_var.set('HAVE_HEIF_COLOR_PROFILE', '1') - endif - if cpp.has_function('heif_context_set_maximum_image_size_limit', prefix: '#include ', dependencies: libheif_dep) - cfg_var.set('HAVE_HEIF_SET_MAX_IMAGE_SIZE_LIMIT', '1') - endif + cfg_var.set('HAVE_HEIF_COLOR_PROFILE', cpp.has_function('heif_image_handle_get_raw_color_profile', prefix: '#include ', dependencies: libheif_dep)) + cfg_var.set('HAVE_HEIF_SET_MAX_IMAGE_SIZE_LIMIT', cpp.has_function('heif_context_set_maximum_image_size_limit', prefix: '#include ', dependencies: libheif_dep)) # added in 1.7.0 - if cpp.has_member('struct heif_decoding_options', 'convert_hdr_to_8bit', prefix: '#include ', dependencies: libheif_dep) - cfg_var.set('HAVE_HEIF_DECODING_OPTIONS_CONVERT_HDR_TO_8BIT', '1') - endif + cfg_var.set('HAVE_HEIF_DECODING_OPTIONS_CONVERT_HDR_TO_8BIT', cpp.has_member('struct heif_decoding_options', 'convert_hdr_to_8bit', prefix: '#include ', dependencies: libheif_dep)) # heif_main_brand added in 1.4.0, but heif_avif appeared in 1.7 ... just check # the libheif version number since testing for enums is annoying - if libheif_dep.version().version_compare('>=1.7.0') - cfg_var.set('HAVE_HEIF_AVIF', '1') - endif + cfg_var.set('HAVE_HEIF_AVIF', libheif_dep.version().version_compare('>=1.7.0')) # added in 1.10.0 - if cpp.has_function('heif_encoder_parameter_get_valid_integer_values', prefix: '#include ', dependencies: libheif_dep) - cfg_var.set('HAVE_HEIF_ENCODER_PARAMETER_GET_VALID_INTEGER_VALUES', '1') - endif + cfg_var.set('HAVE_HEIF_ENCODER_PARAMETER_GET_VALID_INTEGER_VALUES', cpp.has_function('heif_encoder_parameter_get_valid_integer_values', prefix: '#include ', dependencies: libheif_dep)) # added in 1.11.0 - if cpp.has_member('struct heif_encoding_options', 'output_nclx_profile', prefix: '#include ', dependencies: libheif_dep) - cfg_var.set('HAVE_HEIF_ENCODING_OPTIONS_OUTPUT_NCLX_PROFILE', '1') - endif - + cfg_var.set('HAVE_HEIF_ENCODING_OPTIONS_OUTPUT_NCLX_PROFILE', cpp.has_member('struct heif_encoding_options', 'output_nclx_profile', prefix: '#include ', dependencies: libheif_dep)) # heif_init added in 1.13.0 - if libheif_dep.version().version_compare('>=1.13.0') - cfg_var.set('HAVE_HEIF_INIT', '1') - endif + cfg_var.set('HAVE_HEIF_INIT', libheif_dep.version().version_compare('>=1.13.0')) # heif_encoding_options.image_orientation added in 1.14.0 - if cpp.has_member('struct heif_encoding_options', 'image_orientation', prefix: '#include ', dependencies: libheif_dep) - cfg_var.set('HAVE_HEIF_ENCODING_OPTIONS_IMAGE_ORIENTATION', '1') - endif + cfg_var.set('HAVE_HEIF_ENCODING_OPTIONS_IMAGE_ORIENTATION', cpp.has_member('struct heif_encoding_options', 'image_orientation', prefix: '#include ', dependencies: libheif_dep)) # heif_error_success added in 1.17.0 - if libheif_dep.version().version_compare('>=1.17.0') - cfg_var.set('HAVE_HEIF_ERROR_SUCCESS', '1') - endif + cfg_var.set('HAVE_HEIF_ERROR_SUCCESS', libheif_dep.version().version_compare('>=1.17.0')) endif libjxl_dep = dependency('libjxl', version: '>=0.6', required: get_option('jpeg-xl')) @@ -589,20 +517,16 @@ libjxl_module = false if libjxl_found libjxl_module = modules_enabled and not get_option('jpeg-xl-module').disabled() if libjxl_module - cfg_var.set('LIBJXL_MODULE', '1') + cfg_var.set('LIBJXL_MODULE', true) module_deps += libjxl_dep module_deps += libjxl_threads_dep else external_deps += libjxl_dep external_deps += libjxl_threads_dep endif - cfg_var.set('HAVE_LIBJXL', '1') - if libjxl_dep.version().version_compare('>=0.7') - cfg_var.set('HAVE_LIBJXL_0_7', '1') - endif - if libjxl_dep.version().version_compare('>=0.9') - cfg_var.set('HAVE_LIBJXL_0_9', '1') - endif + cfg_var.set('HAVE_LIBJXL', true) + cfg_var.set('HAVE_LIBJXL_0_7', libjxl_dep.version().version_compare('>=0.7')) + cfg_var.set('HAVE_LIBJXL_0_9', libjxl_dep.version().version_compare('>=0.9')) endif # only if pdfium not found @@ -615,14 +539,14 @@ if not pdf_loader.found() if libpoppler_dep.found() and cairo_dep.found() libpoppler_module = modules_enabled and not get_option('poppler-module').disabled() if libpoppler_module - cfg_var.set('POPPLER_MODULE', '1') + cfg_var.set('POPPLER_MODULE', true) module_deps += libpoppler_dep module_deps += cairo_dep else external_deps += libpoppler_dep external_deps += cairo_dep endif - cfg_var.set('HAVE_POPPLER', '1') + cfg_var.set('HAVE_POPPLER', true) pdf_loader = libpoppler_dep endif endif @@ -665,55 +589,32 @@ endif libnifti_found = not get_option('nifti').disabled() and libnifti_dep.found() if libnifti_found external_deps += libnifti_dep - cfg_var.set('HAVE_NIFTI', '1') + cfg_var.set('HAVE_NIFTI', true) endif -if cc.has_header('sys/file.h') - cfg_var.set('HAVE_SYS_FILE_H', '1') -endif -if cc.has_header('sys/param.h') - cfg_var.set('HAVE_SYS_PARAM_H', '1') -endif -if cc.has_header('sys/mman.h') - cfg_var.set('HAVE_SYS_MMAN_H', '1') -endif -if cc.has_header('unistd.h') - cfg_var.set('HAVE_UNISTD_H', '1') -endif -if cc.has_header('io.h') - cfg_var.set('HAVE_IO_H', '1') -endif -if cc.has_header('direct.h') - cfg_var.set('HAVE_DIRECT_H', '1') -endif -if get_option('deprecated') - cfg_var.set('ENABLE_DEPRECATED', '1') -endif -if get_option('nsgif') - cfg_var.set('HAVE_NSGIF', '1') -endif -if get_option('ppm') - cfg_var.set('HAVE_PPM', '1') -endif -if get_option('analyze') - cfg_var.set('HAVE_ANALYZE', '1') -endif -if get_option('radiance') - cfg_var.set('HAVE_RADIANCE', '1') -endif +headers = [ 'sys/file.h', 'sys/param.h', 'sys/mman.h', 'unistd.h', 'io.h', 'direct.h' ] +foreach name : headers + cfg_var.set('HAVE_' + name.underscorify().to_upper(), cc.has_header(name)) +endforeach + +cfg_var.set('ENABLE_DEPRECATED', get_option('deprecated')) +cfg_var.set('HAVE_NSGIF', get_option('nsgif')) +cfg_var.set('HAVE_PPM', get_option('ppm')) +cfg_var.set('HAVE_ANALYZE', get_option('analyze')) +cfg_var.set('HAVE_RADIANCE', get_option('radiance')) gettext_domain = 'vips@0@.@1@'.format(version_major, version_minor) cfg_var.set_quoted('GETTEXT_PACKAGE', gettext_domain) cfg_var.set_quoted('VIPS_PREFIX', prefix_dir) cfg_var.set_quoted('VIPS_LIBDIR', lib_dir) if cc.has_function('ngettext') - cfg_var.set('ENABLE_NLS', 1) + cfg_var.set('ENABLE_NLS', true) have_bind_textdomain_codeset = cc.has_function('bind_textdomain_codeset') else libintl_dep = cc.find_library('intl', required: false) if libintl_dep.found() other_deps += libintl_dep - cfg_var.set('ENABLE_NLS', 1) + cfg_var.set('ENABLE_NLS', true) have_bind_textdomain_codeset = cc.has_function('bind_textdomain_codeset', prefix: '#include ', dependencies: libintl_dep) else have_bind_textdomain_codeset = false @@ -741,7 +642,7 @@ config_file = configure_file( config_dep = declare_dependency( sources: config_file, include_directories: include_directories('.'), - compile_args: '-DHAVE_CONFIG_H=1', + compile_args: '-DHAVE_CONFIG_H', ) libvips_deps = [config_dep] + external_deps + other_deps diff --git a/tools/vips.c b/tools/vips.c index 377ddc090e..a8fa16c43d 100644 --- a/tools/vips.c +++ b/tools/vips.c @@ -312,7 +312,7 @@ static GOptionEntry main_option[] = { { NULL } }; -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED typedef void *(*map_name_fn)(im_function *); /* Loop over a package. @@ -379,7 +379,7 @@ list_function(im_function *func) static int print_list(int argc, char **argv) { -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED if (!argv[0] || strcmp(argv[0], "packages") == 0) im_map_packages((VSListMap2Fn) list_package, NULL); else if (strcmp(argv[0], "classes") == 0) @@ -394,7 +394,7 @@ print_list(int argc, char **argv) list_class, NULL); } else { -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED if (map_name(argv[0], list_function)) vips_error_exit("unknown package \"%s\"", argv[0]); #else @@ -405,7 +405,7 @@ print_list(int argc, char **argv) return 0; } -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED /* Print "ln -s" lines for this package. */ static void * @@ -457,7 +457,7 @@ isvips(const char *name) return vips_isprefix("vips", name); } -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED /* Print a usage string from an im_function descriptor. */ static void @@ -552,13 +552,13 @@ static GOptionEntry empty_options[] = { }; static ActionEntry actions[] = { -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED { "list", N_("list classes|packages|all|package-name|operation-name"), #else { "list", N_("list classes|all|operation-name"), #endif &empty_options[0], print_list }, -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED { "links", N_("generate links for vips/bin"), &empty_options[0], print_links }, #endif @@ -661,7 +661,7 @@ main(int argc, char **argv) GOptionGroup *main_group; GOptionGroup *group; VipsOperation *operation; -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED im_function *fn; #endif int i, j; @@ -760,8 +760,8 @@ main(int argc, char **argv) ; if (main_option_plugin) { -#if ENABLE_MODULES -#if ENABLE_DEPRECATED +#ifdef ENABLE_MODULES +#ifdef ENABLE_DEPRECATED if (!im_load_plugin(main_option_plugin)) vips_error_exit(NULL); #else /*!ENABLE_DEPRECATED*/ @@ -843,7 +843,7 @@ main(int argc, char **argv) break; } -#if ENABLE_DEPRECATED +#ifdef ENABLE_DEPRECATED /* Could be a vips7 im_function. We need to test for vips7 first, * since we don't want to use the vips7 compat wrappers in vips8 * unless we have to. They don't support all args types. From 3a7903dcd7f203d37bf5077c72b56820adfd4374 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 11 Feb 2025 12:33:09 +0100 Subject: [PATCH 060/174] Fix two compiler warnings (#4382) --- libvips/create/text.c | 5 +++++ libvips/foreign/jxlload.c | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libvips/create/text.c b/libvips/create/text.c index db380d4cc3..9ee75cb7d9 100644 --- a/libvips/create/text.c +++ b/libvips/create/text.c @@ -92,6 +92,11 @@ #include #ifdef HAVE_FONTCONFIG +/* ftconfig.h also appears to define HAVE_UNISTD_H. + */ +#ifdef HAVE_UNISTD_H +#undef HAVE_UNISTD_H +#endif #include #include #endif diff --git a/libvips/foreign/jxlload.c b/libvips/foreign/jxlload.c index dad4b6f1d9..5899042ca9 100644 --- a/libvips/foreign/jxlload.c +++ b/libvips/foreign/jxlload.c @@ -636,8 +636,6 @@ vips_foreign_load_jxl_generate(VipsRegion *out_region, static int vips_foreign_load_jxl_fix_exif(VipsForeignLoadJxl *jxl) { - VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(jxl); - if (!jxl->exif_data || vips_isprefix("Exif", (char *) jxl->exif_data)) return 0; From ae14d974fe15fb788850db28cb28c318244e9763 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Tue, 11 Feb 2025 11:52:49 +0000 Subject: [PATCH 061/174] radload: improve sanity check of colour-related headers (#4384) Ensure PRIMARIES and COLORCORR have expected number of components --- ChangeLog | 1 + libvips/foreign/radiance.c | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b8ad61b34..79bff1e643 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,7 @@ - morph: fix Orc path with large masks [kleisauke] - invertlut: fix final value in some cases - matrixload: fix file format detect for some matrix types +- radload: improve sanity check of colour-related headers [lovell] 10/10/24 8.16.0 diff --git a/libvips/foreign/radiance.c b/libvips/foreign/radiance.c index 3039d56191..828ce3c2ba 100644 --- a/libvips/foreign/radiance.c +++ b/libvips/foreign/radiance.c @@ -229,8 +229,8 @@ typedef float RGBPRIMS[4][2]; /* (x,y) chromaticities for RGBW */ #define COLCORSTR "COLORCORR=" #define LCOLCORSTR 10 #define iscolcor(hl) (!strncmp(hl, COLCORSTR, LCOLCORSTR)) -#define colcorval(cc, hl) sscanf((hl) + LCOLCORSTR, "%f %f %f", \ - &(cc)[RED], &(cc)[GRN], &(cc)[BLU]) +#define colcorval(cc, hl) (sscanf((hl) + LCOLCORSTR, "%f %f %f", \ + &(cc)[RED], &(cc)[GRN], &(cc)[BLU]) == 3) #define MINELEN 8 /* minimum scanline length for encoding */ #define MAXELEN 0x7fff /* maximum scanline length for encoding */ @@ -643,7 +643,8 @@ rad2vips_process_line(char *line, Read *read) COLOR cc; int i; - (void) colcorval(cc, line); + if (!colcorval(cc, line)) + return -1; for (i = 0; i < 3; i++) read->colcor[i] *= cc[i]; } @@ -651,7 +652,8 @@ rad2vips_process_line(char *line, Read *read) read->aspect *= aspectval(line); } else if (isprims(line)) { - (void) primsval(read->prims, line); + if (!primsval(read->prims, line)) + return -1; } return 0; From 83b2d7bdfd4d4337a9e1d0951f3b10ad9718645a Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Tue, 11 Feb 2025 19:57:16 +0000 Subject: [PATCH 062/174] svgload: add support for custom CSS via stylesheet option (#4376) --- ChangeLog | 1 + libvips/foreign/svgload.c | 33 +++++++++++++++++++++++++++++++++ meson.build | 2 ++ test/test-suite/test_foreign.py | 6 ++++++ 4 files changed, 42 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2debbc47b6..87960cb640 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ - much more reliable operation caching - colour: add support for auto-selecting the rendering intent [kleisauke] - add matrixmultiply +- svgload: add support for custom CSS via stylesheet option [lovell] 8.16.1 diff --git a/libvips/foreign/svgload.c b/libvips/foreign/svgload.c index 76c21990ed..ed1b92e6dc 100644 --- a/libvips/foreign/svgload.c +++ b/libvips/foreign/svgload.c @@ -119,6 +119,10 @@ typedef struct _VipsForeignLoadSvg { */ gboolean unlimited; + /* Custom CSS. + */ + const char *stylesheet; + RsvgHandle *page; } VipsForeignLoadSvg; @@ -601,6 +605,21 @@ vips_foreign_load_svg_generate(VipsRegion *out_region, cr = cairo_create(surface); cairo_surface_destroy(surface); +#ifdef HAVE_RSVG_HANDLE_SET_STYLESHEET + if (svg->stylesheet && g_utf8_validate(svg->stylesheet, -1, NULL)) { + GError *error = NULL; + if (!rsvg_handle_set_stylesheet(svg->page, + (const guint8 *) svg->stylesheet, + g_utf8_strlen(svg->stylesheet, -1), &error)) { + cairo_destroy(cr); + vips_operation_invalidate(VIPS_OPERATION(svg)); + vips_error(class->nickname, "Invalid custom CSS"); + vips_g_error(&error); + return -1; + } + } +#endif + /* rsvg is single-threaded, but we don't need to lock since we're * running inside a non-threaded tilecache. */ @@ -735,6 +754,13 @@ vips_foreign_load_svg_class_init(VipsForeignLoadSvgClass *class) G_STRUCT_OFFSET(VipsForeignLoadSvg, unlimited), FALSE); #endif + + VIPS_ARG_STRING(class, "stylesheet", 24, + _("Stylesheet"), + _("Custom CSS"), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET(VipsForeignLoadSvg, stylesheet), + NULL); } static void @@ -1019,6 +1045,7 @@ vips_foreign_load_svg_buffer_init(VipsForeignLoadSvgBuffer *buffer) * * @dpi: %gdouble, render at this DPI * * @scale: %gdouble, scale render by this factor * * @unlimited: %gboolean, allow SVGs of any size + * * @stylesheet: %gchararray, custom CSS * * Render a SVG file into a VIPS image. Rendering uses the librsvg library * and should be fast. @@ -1032,6 +1059,10 @@ vips_foreign_load_svg_buffer_init(VipsForeignLoadSvgBuffer *buffer) * SVGs larger than 10MB are normally blocked for security. Set @unlimited to * allow SVGs of any size. * + * A UTF-8 string containing custom CSS can be provided via @stylesheet. + * During the CSS cascade, the specified stylesheet will be applied with a + * User Origin. This feature requires librsvg 2.48.0 or later. + * * See also: vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. @@ -1061,6 +1092,7 @@ vips_svgload(const char *filename, VipsImage **out, ...) * * @dpi: %gdouble, render at this DPI * * @scale: %gdouble, scale render by this factor * * @unlimited: %gboolean, allow SVGs of any size + * * @stylesheet: %gchararray, custom CSS * * Read a SVG-formatted memory block into a VIPS image. Exactly as * vips_svgload(), but read from a memory buffer. @@ -1103,6 +1135,7 @@ vips_svgload_buffer(void *buf, size_t len, VipsImage **out, ...) * * @dpi: %gdouble, render at this DPI * * @scale: %gdouble, scale render by this factor * * @unlimited: %gboolean, allow SVGs of any size + * * @stylesheet: %gchararray, custom CSS * * Exactly as vips_svgload(), but read from a string. This function takes a * copy of the string. diff --git a/meson.build b/meson.build index 1476a49ed2..81807c1072 100644 --- a/meson.build +++ b/meson.build @@ -388,6 +388,8 @@ if librsvg_found external_deps += librsvg_dep external_deps += cairo_dep cfg_var.set('HAVE_RSVG', true) + # rsvg_handle_set_stylesheet added in librsvg 2.48.0 + cfg_var.set('HAVE_RSVG_HANDLE_SET_STYLESHEET', cc.has_function('rsvg_handle_set_stylesheet', dependencies: librsvg_dep)) endif openslide_dep = dependency('openslide', version: '>=3.3.0', required: get_option('openslide')) diff --git a/test/test-suite/test_foreign.py b/test/test-suite/test_foreign.py index 87dc50cebd..bfa85db321 100644 --- a/test/test-suite/test_foreign.py +++ b/test/test-suite/test_foreign.py @@ -1200,6 +1200,12 @@ def svg_valid(im): assert im.width == 10 assert im.height == 10 + # Custom CSS stylesheet + im = pyvips.Image.new_from_file(SVG_FILE) + assert im.avg() < 5 + im = pyvips.Image.new_from_file(SVG_FILE, stylesheet=b'path{stroke:#f00;stroke-width:1em;}') + assert im.avg() > 5 + def test_csv(self): self.save_load("%s.csv", self.mono) From e0854707282ec68d6e20dafe0b781752aa6705c4 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 12 Feb 2025 10:43:24 +0100 Subject: [PATCH 063/174] shrink{h,v}: improve performance using Highway (#4383) * Implement shrinkv using highway ops * Implement shrinkh using highway ops --- ChangeLog | 1 + libvips/resample/meson.build | 2 + libvips/resample/presample.h | 5 + libvips/resample/shrinkh.c | 85 ++++++++++++- libvips/resample/shrinkh_hwy.cpp | 129 +++++++++++++++++++ libvips/resample/shrinkv.c | 88 ++++++++++++- libvips/resample/shrinkv_hwy.cpp | 204 +++++++++++++++++++++++++++++++ 7 files changed, 512 insertions(+), 2 deletions(-) create mode 100644 libvips/resample/shrinkh_hwy.cpp create mode 100644 libvips/resample/shrinkv_hwy.cpp diff --git a/ChangeLog b/ChangeLog index 87960cb640..84ab6ca1d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ - much more reliable operation caching - colour: add support for auto-selecting the rendering intent [kleisauke] - add matrixmultiply +- improve performance of vips_shrink() [kleisauke] - svgload: add support for custom CSS via stylesheet option [lovell] 8.16.1 diff --git a/libvips/resample/meson.build b/libvips/resample/meson.build index dfeb95605f..22095df620 100644 --- a/libvips/resample/meson.build +++ b/libvips/resample/meson.build @@ -8,7 +8,9 @@ resample_sources = files( 'resize.c', 'shrink.c', 'shrinkh.c', + 'shrinkh_hwy.cpp', 'shrinkv.c', + 'shrinkv_hwy.cpp', 'reduce.c', 'reduceh.cpp', 'reduceh_hwy.cpp', diff --git a/libvips/resample/presample.h b/libvips/resample/presample.h index b2799beaf7..56c436e9ff 100644 --- a/libvips/resample/presample.h +++ b/libvips/resample/presample.h @@ -78,6 +78,11 @@ void vips_reduceh_uchar_hwy(VipsPel *pout, VipsPel *pin, void vips_reducev_uchar_hwy(VipsPel *pout, VipsPel *pin, int n, int ne, int lskip, const short *restrict k); +void vips_shrinkh_uchar_hwy(VipsPel *pout, VipsPel *pin, + int width, int hshrink, int bands); +void vips_shrinkv_uchar_hwy(VipsPel *pout, VipsPel *pin, + int ne, int vshrink, int lskip); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/resample/shrinkh.c b/libvips/resample/shrinkh.c index 574a44cf59..4ff9706b44 100644 --- a/libvips/resample/shrinkh.c +++ b/libvips/resample/shrinkh.c @@ -55,6 +55,7 @@ #include #include +#include #include #include @@ -262,6 +263,73 @@ vips_shrinkh_gen(VipsRegion *out_region, return 0; } +#ifdef HAVE_HWY +static int +vips_shrinkh_uchar_vector_gen(VipsRegion *out_region, + void *seq, void *a, void *b, gboolean *stop) +{ + /* How do we chunk up the image? We don't want to prepare the whole of + * the input region corresponding to *r since it could be huge. + * + * Reading a line at a time could cause a lot of overcomputation, depending + * on what's upstream from us. In SMALLTILE, output scanlines could be + * quite small. + * + * Use fatstrip height as a compromise. + */ + const int dy = vips__fatstrip_height; + + VipsImage *in = (VipsImage *) a; + VipsShrinkh *shrink = (VipsShrinkh *) b; + VipsRegion *ir = (VipsRegion *) seq; + VipsRect *r = &out_region->valid; + const int bands = in->Bands; + + int y, y1; + +#ifdef DEBUG + printf("vips_shrinkh_uchar_vector_gen: generating %d x %d at %d x %d\n", + r->width, r->height, r->left, r->top); +#endif /*DEBUG*/ + + for (y = 0; y < r->height; y += dy) { + int chunk_height = VIPS_MIN(dy, r->height - y); + + VipsRect s; + + s.left = r->left * shrink->hshrink; + s.top = r->top + y; + s.width = r->width * shrink->hshrink; + s.height = chunk_height; +#ifdef DEBUG + printf("vips_shrinkh_uchar_vector_gen: requesting %d lines from %d\n", + s.height, s.top); +#endif /*DEBUG*/ + if (vips_region_prepare(ir, &s)) + return -1; + + VIPS_GATE_START("vips_shrinkh_uchar_vector_gen: work"); + + // each output line + for (y1 = 0; y1 < chunk_height; y1++) { + // top of this line in the output + int top = r->top + y + y1; + + VipsPel *q = VIPS_REGION_ADDR(out_region, r->left, top); + VipsPel *p = VIPS_REGION_ADDR(ir, s.left, top); + + vips_shrinkh_uchar_hwy(q, p, r->width, shrink->hshrink, bands); + } + + VIPS_GATE_STOP("vips_shrinkh_uchar_vector_gen: work"); + } + + VIPS_COUNT_PIXELS(out_region, "vips_shrinkh_uchar_vector_gen"); + + return 0; +} +#endif /*HAVE_HWY*/ + static int vips_shrinkh_build(VipsObject *object) { @@ -272,6 +340,7 @@ vips_shrinkh_build(VipsObject *object) vips_object_local_array(object, 2); VipsImage *in; + VipsGenerateFn generate; if (VIPS_OBJECT_CLASS(vips_shrinkh_parent_class)->build(object)) return -1; @@ -298,6 +367,20 @@ vips_shrinkh_build(VipsObject *object) return -1; in = t[1]; + /* For uchar input, try to make a vector path. + */ +#ifdef HAVE_HWY + if (in->BandFmt == VIPS_FORMAT_UCHAR && + vips_vector_isenabled()) { + generate = vips_shrinkh_uchar_vector_gen; + g_info("shrinkh: using vector path"); + } + else +#endif /*HAVE_HWY*/ + /* Default to the C path. + */ + generate = vips_shrinkh_gen; + if (vips_image_pipelinev(resample->out, VIPS_DEMAND_STYLE_THINSTRIP, in, NULL)) return -1; @@ -324,7 +407,7 @@ vips_shrinkh_build(VipsObject *object) #endif /*DEBUG*/ if (vips_image_generate(resample->out, - vips_start_one, vips_shrinkh_gen, vips_stop_one, + vips_start_one, generate, vips_stop_one, in, shrink)) return -1; diff --git a/libvips/resample/shrinkh_hwy.cpp b/libvips/resample/shrinkh_hwy.cpp new file mode 100644 index 0000000000..41df4b1320 --- /dev/null +++ b/libvips/resample/shrinkh_hwy.cpp @@ -0,0 +1,129 @@ +/* 15/11/24 kleisauke + * - from shrinkv_hwy.cpp + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "presample.h" + +#ifdef HAVE_HWY + +#undef HWY_TARGET_INCLUDE +#define HWY_TARGET_INCLUDE "libvips/resample/shrinkh_hwy.cpp" +#include +#include + +namespace HWY_NAMESPACE { + +using namespace hwy::HWY_NAMESPACE; + +using DU32 = ScalableTag; +constexpr Rebind du8x32; +constexpr DU32 du32; + +constexpr int64_t max_uint32 = 1LL << 32; +constexpr int32_t max_bits = 1 << 8; + +HWY_ATTR void +vips_shrinkh_uchar_hwy(VipsPel *pout, VipsPel *pin, + int32_t width, int32_t hshrink, int32_t bands) +{ +#if HWY_TARGET != HWY_SCALAR + const auto multiplier = Set(du32, max_uint32 / (max_bits * hshrink)); + const auto amend = Set(du32, hshrink / 2); + + int32_t ix = 0; + + for (int32_t x = 0; x < width; ++x) { + auto *HWY_RESTRICT p = (uint8_t *) pin + ix * bands; + auto *HWY_RESTRICT q = (uint8_t *) pout + x * bands; + + auto sum0 = amend; + + int32_t xx = 0; + for (; xx + 2 <= hshrink; xx += 2) { + auto pix0 = PromoteTo(du32, LoadU(du8x32, p)); + p += bands; + auto pix1 = PromoteTo(du32, LoadU(du8x32, p)); + p += bands; + + pix0 = Add(pix0, pix1); + sum0 = Add(sum0, pix0); + } + for (; xx < hshrink; ++xx) { + auto pix0 = PromoteTo(du32, LoadU(du8x32, p)); + p += bands; + + sum0 = Add(sum0, pix0); + } + + sum0 = Mul(sum0, multiplier); + + /* The final 32->8 conversion. + */ + sum0 = ShiftRight<24>(sum0); + + auto demoted = DemoteTo(du8x32, sum0); + StoreU(demoted, du8x32, q); + + ix += hshrink; + } +#endif +} + +} /*namespace HWY_NAMESPACE*/ + +#if HWY_ONCE +HWY_EXPORT(vips_shrinkh_uchar_hwy); + +void +vips_shrinkh_uchar_hwy(VipsPel *pout, VipsPel *pin, + int width, int hshrink, int bands) +{ + /* clang-format off */ + HWY_DYNAMIC_DISPATCH(vips_shrinkh_uchar_hwy)(pout, pin, + width, hshrink, bands); + /* clang-format on */ +} +#endif /*HWY_ONCE*/ + +#endif /*HAVE_HWY*/ diff --git a/libvips/resample/shrinkv.c b/libvips/resample/shrinkv.c index a6691cd56d..148d1555b9 100644 --- a/libvips/resample/shrinkv.c +++ b/libvips/resample/shrinkv.c @@ -94,6 +94,7 @@ #include #include +#include #include #include @@ -307,6 +308,76 @@ vips_shrinkv_gen(VipsRegion *out_region, return 0; } +#ifdef HAVE_HWY +static int +vips_shrinkv_uchar_vector_gen(VipsRegion *out_region, + void *seq, void *a, void *b, gboolean *stop) +{ + VipsImage *in = (VipsImage *) a; + VipsShrinkv *shrink = (VipsShrinkv *) b; + VipsRegion *ir = (VipsRegion *) seq; + VipsRect *r = &out_region->valid; + const int bands = in->Bands; + int ne = r->width * bands; + + /* How do we chunk up the output image? We don't want to prepare the + * whole of the input region corresponding to *r since it could be huge. + * + * We also don't want to fetch a line at a time, since that can make + * upstream coordinate changes very expensive. + * + * Instead, aim for a minimum of tile_height on the input image. + */ + int input_target = VIPS_MAX(shrink->vshrink, r->height); + int dy = input_target / shrink->vshrink; + + int y, y1; + +#ifdef DEBUG + printf("vips_shrinkv_uchar_vector_gen: generating %d x %d at %d x %d\n", + r->width, r->height, r->left, r->top); +#endif /*DEBUG*/ + + for (y = 0; y < r->height; y += dy) { + int chunk_height = VIPS_MIN(dy, r->height - y); + + VipsRect s; + + s.left = r->left; + s.top = (r->top + y) * shrink->vshrink; + s.width = r->width; + s.height = chunk_height * shrink->vshrink; +#ifdef DEBUG + printf("vips_shrinkv_uchar_vector_gen: requesting %d lines from %d\n", + s.height, s.top); +#endif /*DEBUG*/ + if (vips_region_prepare(ir, &s)) + return -1; + + VIPS_GATE_START("vips_shrinkv_uchar_vector_gen: work"); + + const int lskip = VIPS_REGION_LSKIP(ir); + + // each output line + for (y1 = 0; y1 < chunk_height; y1++) { + // top of this line in the output + int top = r->top + y + y1; + + VipsPel *q = VIPS_REGION_ADDR(out_region, r->left, top); + VipsPel *p = VIPS_REGION_ADDR(ir, r->left, top * shrink->vshrink); + + vips_shrinkv_uchar_hwy(q, p, ne, shrink->vshrink, lskip); + } + + VIPS_GATE_STOP("vips_shrinkv_uchar_vector_gen: work"); + } + + VIPS_COUNT_PIXELS(out_region, "vips_shrinkv_uchar_vector_gen"); + + return 0; +} +#endif /*HAVE_HWY*/ + static int vips_shrinkv_build(VipsObject *object) { @@ -316,6 +387,7 @@ vips_shrinkv_build(VipsObject *object) VipsImage **t = (VipsImage **) vips_object_local_array(object, 4); VipsImage *in; + VipsGenerateFn generate; if (VIPS_OBJECT_CLASS(vips_shrinkv_parent_class)->build(object)) return -1; @@ -342,6 +414,20 @@ vips_shrinkv_build(VipsObject *object) return -1; in = t[1]; + /* For uchar input, try to make a vector path. + */ +#ifdef HAVE_HWY + if (in->BandFmt == VIPS_FORMAT_UCHAR && + vips_vector_isenabled()) { + generate = vips_shrinkv_uchar_vector_gen; + g_info("shrinkv: using vector path"); + } + else +#endif /*HAVE_HWY*/ + /* Default to the C path. + */ + generate = vips_shrinkv_gen; + /* SMALLTILE or we'll need huge input areas for our output. In seq * mode, the linecache above will keep us sequential. */ @@ -373,7 +459,7 @@ vips_shrinkv_build(VipsObject *object) #endif /*DEBUG*/ if (vips_image_generate(t[2], - vips_start_one, vips_shrinkv_gen, vips_stop_one, + vips_start_one, generate, vips_stop_one, in, shrink)) return -1; diff --git a/libvips/resample/shrinkv_hwy.cpp b/libvips/resample/shrinkv_hwy.cpp new file mode 100644 index 0000000000..fad6387008 --- /dev/null +++ b/libvips/resample/shrinkv_hwy.cpp @@ -0,0 +1,204 @@ +/* 14/11/24 kleisauke + * - from reducev_hwy.cpp + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "presample.h" + +#ifdef HAVE_HWY + +#undef HWY_TARGET_INCLUDE +#define HWY_TARGET_INCLUDE "libvips/resample/shrinkv_hwy.cpp" +#include +#include + +namespace HWY_NAMESPACE { + +using namespace hwy::HWY_NAMESPACE; + +using DU32 = ScalableTag; +using DU16 = ScalableTag; +constexpr Rebind du8x16; +#if HWY_ARCH_RVV || (HWY_ARCH_ARM_A64 && HWY_TARGET <= HWY_SVE) +constexpr Rebind du8x32; +#endif +constexpr DU16 du16; +constexpr DU32 du32; + +constexpr int64_t max_uint32 = 1LL << 32; +constexpr int32_t max_bits = 1 << 8; + +#if defined(HAVE_HWY_1_1_0) && \ + (HWY_ARCH_RVV || (HWY_ARCH_ARM_A64 && HWY_TARGET <= HWY_SVE)) +#define InterleaveLower InterleaveWholeLower +#define InterleaveUpper InterleaveWholeUpper +#endif + +HWY_ATTR void +vips_shrinkv_uchar_hwy(VipsPel *pout, VipsPel *pin, + int32_t ne, int32_t vshrink, int32_t lskip) +{ +#if HWY_TARGET != HWY_SCALAR + const auto l1 = lskip / sizeof(uint8_t); + +#if !defined(HAVE_HWY_1_1_0) && \ + (HWY_ARCH_RVV || (HWY_ARCH_ARM_A64 && HWY_TARGET <= HWY_SVE)) + /* Ensure we do not cross 128-bit block boundaries on RVV/SVE. + */ + const int32_t N = 8; +#else + const int32_t N = Lanes(du16); +#endif + + const uint32_t multiplier = max_uint32 / (max_bits * vshrink); + const uint32_t amend = vshrink / 2; + + const auto zero = Zero(du16); + const auto multiplier_v = Set(du32, multiplier); + const auto amend_v = Set(du32, amend); + + /* Main loop: unrolled. + */ + int32_t x = 0; + for (; x + N <= ne; x += N) { + auto *HWY_RESTRICT p = (uint8_t *) pin + x; + auto *HWY_RESTRICT q = (uint8_t *) pout + x; + + auto sum0 = amend_v; + auto sum1 = amend_v; + + int32_t yy = 0; + for (; yy + 2 <= vshrink; yy += 2) { + auto pix0 = PromoteTo(du16, LoadU(du8x16, p)); + p += l1; + auto pix1 = PromoteTo(du16, LoadU(du8x16, p)); + p += l1; + + pix0 = Add(pix0, pix1); + + sum0 = Add(sum0, BitCast(du32, InterleaveLower(du16, pix0, zero))); + sum1 = Add(sum1, BitCast(du32, InterleaveUpper(du16, pix0, zero))); + } + for (; yy < vshrink; ++yy) { + auto pix0 = PromoteTo(du16, LoadU(du8x16, p)); + p += l1; + + sum0 = Add(sum0, BitCast(du32, InterleaveLower(du16, pix0, zero))); + sum1 = Add(sum1, BitCast(du32, InterleaveUpper(du16, pix0, zero))); + } + + sum0 = Mul(sum0, multiplier_v); + sum1 = Mul(sum1, multiplier_v); + + /* The final 32->8 conversion. + */ + sum0 = ShiftRight<24>(sum0); + sum1 = ShiftRight<24>(sum1); + +#if HWY_ARCH_RVV || (HWY_ARCH_ARM_A64 && HWY_TARGET <= HWY_SVE) + /* RVV/SVE defines demotion as writing to the upper or lower half + * of each lane, rather than compacting them within a vector. + */ + auto demoted0 = DemoteTo(du8x32, sum0); + auto demoted1 = DemoteTo(du8x32, sum1); + + StoreU(demoted0, du8x32, q + 0 * N / 2); + StoreU(demoted1, du8x32, q + 1 * N / 2); +#else + auto demoted0 = ReorderDemote2To(du16, sum0, sum1); + auto demoted = DemoteTo(du8x16, demoted0); + + StoreU(demoted, du8x16, q); +#endif + } + + /* `ne` was not a multiple of the vector length `N`; + * proceed one by one. + */ + for (; x < ne; ++x) { + auto *HWY_RESTRICT p = (uint8_t *) pin + x; + auto *HWY_RESTRICT q = (uint8_t *) pout + x; + + uint32_t sum = amend; + + int32_t yy = 0; + for (; yy + 2 <= vshrink; yy += 2) { + auto pix0 = *p; + p += l1; + auto pix1 = *p; + p += l1; + + sum += pix0 + pix1; + } + for (; yy < vshrink; ++yy) { + auto pix0 = *p; + p += l1; + + sum += pix0; + } + + *q = (sum * multiplier) >> 24; + } +#endif +} + +#undef InterleaveLower +#undef InterleaveUpper + +} /*namespace HWY_NAMESPACE*/ + +#if HWY_ONCE +HWY_EXPORT(vips_shrinkv_uchar_hwy); + +void +vips_shrinkv_uchar_hwy(VipsPel *pout, VipsPel *pin, + int ne, int vshrink, int lskip) +{ + /* clang-format off */ + HWY_DYNAMIC_DISPATCH(vips_shrinkv_uchar_hwy)(pout, pin, + ne, vshrink, lskip); + /* clang-format on */ +} +#endif /*HWY_ONCE*/ + +#endif /*HAVE_HWY*/ From ee7f8774c2b327e6097babfb7eade0177f98aa5e Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 13 Feb 2025 10:58:35 +0100 Subject: [PATCH 064/174] OSS-Fuzz: disable build of cruft (#4389) --- fuzz/oss_fuzz_build.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fuzz/oss_fuzz_build.sh b/fuzz/oss_fuzz_build.sh index 091ef1252c..6f9435ef9b 100755 --- a/fuzz/oss_fuzz_build.sh +++ b/fuzz/oss_fuzz_build.sh @@ -43,7 +43,7 @@ popd # lcms pushd $SRC/lcms meson setup build --prefix=$WORK --libdir=lib --default-library=static --buildtype=debugoptimized \ - -Djpeg=disabled -Dtiff=disabled + -Dtests=disabled -Djpeg=disabled -Dtiff=disabled meson install -C build --tag devel popd @@ -148,7 +148,8 @@ popd # cgif pushd $SRC/cgif -meson setup build --prefix=$WORK --libdir=lib --default-library=static --buildtype=debugoptimized +meson setup build --prefix=$WORK --libdir=lib --default-library=static --buildtype=debugoptimized \ + -Dexamples=false -Dtests=false meson install -C build --tag devel popd From 7228c33665f78f2ad185f6961297a122ae2be242 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 18 Feb 2025 18:48:45 +0100 Subject: [PATCH 065/174] note "shift" in vips_cast_*() docs --- libvips/conversion/cast.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/libvips/conversion/cast.c b/libvips/conversion/cast.c index fb945d2312..557e2dbdda 100644 --- a/libvips/conversion/cast.c +++ b/libvips/conversion/cast.c @@ -603,6 +603,10 @@ vips_cast(VipsImage *in, VipsImage **out, VipsBandFormat format, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * + * Optional arguments: + * + * * @shift: %gboolean, integer values are shifted + * * Convert @in to #VIPS_FORMAT_UCHAR. See vips_cast(). * * Returns: 0 on success, -1 on error @@ -626,6 +630,10 @@ vips_cast_uchar(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * + * Optional arguments: + * + * * @shift: %gboolean, integer values are shifted + * * Convert @in to #VIPS_FORMAT_CHAR. See vips_cast(). * * Returns: 0 on success, -1 on error @@ -649,6 +657,10 @@ vips_cast_char(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * + * Optional arguments: + * + * * @shift: %gboolean, integer values are shifted + * * Convert @in to #VIPS_FORMAT_USHORT. See vips_cast(). * * Returns: 0 on success, -1 on error @@ -672,6 +684,10 @@ vips_cast_ushort(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * + * Optional arguments: + * + * * @shift: %gboolean, integer values are shifted + * * Convert @in to #VIPS_FORMAT_SHORT. See vips_cast(). * * Returns: 0 on success, -1 on error @@ -695,6 +711,10 @@ vips_cast_short(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * + * Optional arguments: + * + * * @shift: %gboolean, integer values are shifted + * * Convert @in to #VIPS_FORMAT_UINT. See vips_cast(). * * Returns: 0 on success, -1 on error @@ -718,6 +738,10 @@ vips_cast_uint(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * + * Optional arguments: + * + * * @shift: %gboolean, integer values are shifted + * * Convert @in to #VIPS_FORMAT_INT. See vips_cast(). * * Returns: 0 on success, -1 on error From 9ab6784f693de50b00fa535b9efbbe9d2cbf71f2 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Wed, 19 Feb 2025 08:06:38 +0000 Subject: [PATCH 066/174] heifsave: reject multiband images (#4392) --- ChangeLog | 1 + libvips/foreign/heifsave.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 79bff1e643..3dbc4c35d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,7 @@ - invertlut: fix final value in some cases - matrixload: fix file format detect for some matrix types - radload: improve sanity check of colour-related headers [lovell] +- heifsave: reject multiband images [lovell] 10/10/24 8.16.0 diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index ddb1a40c25..589b39f055 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -689,6 +689,15 @@ vips_foreign_save_heif_build(VipsObject *object) return -1; } + /* Reject multiband images. + */ + if (save->ready->Type == VIPS_INTERPRETATION_MULTIBAND) { + vips_error("heifsave", _("Unsupported interpretation: %s"), + vips_enum_nick(VIPS_TYPE_INTERPRETATION, + save->ready->Type)); + return -1; + } + /* Make a heif image the size of a page. We send sink_disc() output * here and write a frame each time it fills. */ From 5ca47efb6d85ff6a15a3909e97e595a528266c7b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 24 Feb 2025 14:43:48 +0100 Subject: [PATCH 067/174] tiny formatting revision --- libvips/mosaicing/global_balance.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/libvips/mosaicing/global_balance.c b/libvips/mosaicing/global_balance.c index 5052e788ec..c3e7152bd6 100644 --- a/libvips/mosaicing/global_balance.c +++ b/libvips/mosaicing/global_balance.c @@ -1495,18 +1495,12 @@ vips__build_mosaic(SymbolTable *st, VipsImage *out, transform_fn tfn, void *a) static int vips__matrixtranspose(VipsImage *in, VipsImage **out) { - int yc, xc; - - /* Allocate output matrix. - */ if (!(*out = vips_image_new_matrix(in->Ysize, in->Xsize))) return -1; - /* Transpose. - */ - for (yc = 0; yc < (*out)->Ysize; ++yc) - for (xc = 0; xc < (*out)->Xsize; ++xc) - *VIPS_MATRIX(*out, xc, yc) = *VIPS_MATRIX(in, yc, xc); + for (int y = 0; y < (*out)->Ysize; y++) + for (int x = 0; x < (*out)->Xsize; x++) + *VIPS_MATRIX(*out, x, y) = *VIPS_MATRIX(in, y, x); return 0; } From 1beb5dd241b27f8fb2608a220db5e51b4e4776cb Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 25 Feb 2025 18:27:06 +0100 Subject: [PATCH 068/174] heifload: prevent possible int overflow for large images (#4399) i.e. when the `unlimited` flag is set (> 16384x16384). --- ChangeLog | 1 + libvips/foreign/heifload.c | 5 ++++- libvips/foreign/heifsave.c | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3dbc4c35d2..796ac7dcb3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,7 @@ - matrixload: fix file format detect for some matrix types - radload: improve sanity check of colour-related headers [lovell] - heifsave: reject multiband images [lovell] +- heifload: prevent possible int overflow for large images [kleisauke] 10/10/24 8.16.0 diff --git a/libvips/foreign/heifload.c b/libvips/foreign/heifload.c index 3872811abf..f65ed5cb61 100644 --- a/libvips/foreign/heifload.c +++ b/libvips/foreign/heifload.c @@ -351,6 +351,9 @@ vips_foreign_load_heif_build(VipsObject *object) heif->ctx = heif_context_alloc(); #ifdef HAVE_HEIF_SET_MAX_IMAGE_SIZE_LIMIT + /* heifsave is limited to a maximum image size of 16384x16384, + * so align the heifload defaults accordingly. + */ heif_context_set_maximum_image_size_limit(heif->ctx, heif->unlimited ? USHRT_MAX : 0x4000); #endif /* HAVE_HEIF_SET_MAX_IMAGE_SIZE_LIMIT */ @@ -993,7 +996,7 @@ vips_foreign_load_heif_generate(VipsRegion *out_region, } memcpy(VIPS_REGION_ADDR(out_region, 0, r->top), - heif->data + heif->stride * line, + heif->data + (size_t) heif->stride * line, VIPS_IMAGE_SIZEOF_LINE(out_region->im)); /* We may need to swap bytes and shift to fill 16 bits. diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index 589b39f055..851812e795 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -471,7 +471,7 @@ vips_foreign_save_heif_write_block(VipsRegion *region, VipsRect *area, int page = (area->top + y) / heif->page_height; int line = (area->top + y) % heif->page_height; VipsPel *p = VIPS_REGION_ADDR(region, 0, area->top + y); - VipsPel *q = heif->data + line * heif->stride; + VipsPel *q = heif->data + (size_t) heif->stride * line; if (vips_foreign_save_heif_pack(heif, q, p, VIPS_REGION_N_ELEMENTS(region))) From df54c2bf6f916e94798c8f46a7f973878293d10b Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Tue, 25 Feb 2025 19:27:26 +0000 Subject: [PATCH 069/174] heifload: ensure unlimited flag removes all security limits where possible (#4398) Requires libheif v1.19.0+ Co-authored-by: Kleis Auke Wolthuizen --- ChangeLog | 1 + libvips/foreign/heifload.c | 5 +++++ meson.build | 2 ++ 3 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 84ab6ca1d4..72902ef3b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ - add matrixmultiply - improve performance of vips_shrink() [kleisauke] - svgload: add support for custom CSS via stylesheet option [lovell] +- heifload: `unlimited` flag removes all limits (requires libheif 1.19.0+) [lovell] 8.16.1 diff --git a/libvips/foreign/heifload.c b/libvips/foreign/heifload.c index d683258461..7b18dd0659 100644 --- a/libvips/foreign/heifload.c +++ b/libvips/foreign/heifload.c @@ -354,6 +354,11 @@ vips_foreign_load_heif_build(VipsObject *object) heif_context_set_maximum_image_size_limit(heif->ctx, heif->unlimited ? USHRT_MAX : 0x4000); #endif /* HAVE_HEIF_SET_MAX_IMAGE_SIZE_LIMIT */ +#ifdef HAVE_HEIF_GET_DISABLED_SECURITY_LIMITS + if (heif->unlimited) + heif_context_set_security_limits(heif->ctx, + heif_get_disabled_security_limits()); +#endif /* HAVE_HEIF_GET_DISABLED_SECURITY_LIMITS */ error = heif_context_read_from_reader(heif->ctx, heif->reader, heif, NULL); if (error.code) { diff --git a/meson.build b/meson.build index 81807c1072..b4603ddb5c 100644 --- a/meson.build +++ b/meson.build @@ -510,6 +510,8 @@ if libheif_dep.found() cfg_var.set('HAVE_HEIF_ENCODING_OPTIONS_IMAGE_ORIENTATION', cpp.has_member('struct heif_encoding_options', 'image_orientation', prefix: '#include ', dependencies: libheif_dep)) # heif_error_success added in 1.17.0 cfg_var.set('HAVE_HEIF_ERROR_SUCCESS', libheif_dep.version().version_compare('>=1.17.0')) + # heif_get_disabled_security_limits added in 1.19.0 + cfg_var.set('HAVE_HEIF_GET_DISABLED_SECURITY_LIMITS', cpp.has_function('heif_get_disabled_security_limits', prefix: '#include ', dependencies: libheif_dep)) endif libjxl_dep = dependency('libjxl', version: '>=0.6', required: get_option('jpeg-xl')) From cce727b4abdb1dca7e6f0ed00989de78255787dc Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 28 Feb 2025 19:51:07 +0100 Subject: [PATCH 070/174] tiffload: add missing read loop (#4403) We weren't looping on `vips_source_read()` in tiffload, which could cause failures when reading from pipes. Resolves: #4400. --- ChangeLog | 1 + libvips/foreign/tiff.c | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 796ac7dcb3..8b5d4bf15e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,7 @@ - radload: improve sanity check of colour-related headers [lovell] - heifsave: reject multiband images [lovell] - heifload: prevent possible int overflow for large images [kleisauke] +- tiffload: add missing read loop [kleisauke] 10/10/24 8.16.0 diff --git a/libvips/foreign/tiff.c b/libvips/foreign/tiff.c index 2cf2761384..6668ba9882 100644 --- a/libvips/foreign/tiff.c +++ b/libvips/foreign/tiff.c @@ -98,7 +98,24 @@ openin_source_read(thandle_t st, tdata_t data, tsize_t size) { VipsSource *source = VIPS_SOURCE(st); - return vips_source_read(source, data, size); + gint64 total_read; + + total_read = 0; + + while (total_read < size) { + gint64 bytes_read; + + bytes_read = vips_source_read(source, data, size - total_read); + if (bytes_read == -1) + return -1; + if (bytes_read == 0) + break; + + total_read += bytes_read; + data = (char *) data + bytes_read; + } + + return total_read; } static tsize_t From 762f5030c82861a8d4b981cb398f81e70d002bd9 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 1 Mar 2025 13:54:36 +0100 Subject: [PATCH 071/174] doc: update CLI summaries (#4404) --- doc/How-it-opens-files.md | 2 +- doc/How-it-opens-files.xml | 2 +- doc/Making-image-pyramids.md | 44 +++++++++++++++++++++-------------- doc/Making-image-pyramids.xml | 42 +++++++++++++++++++-------------- doc/Using-vipsthumbnail.md | 4 ++-- doc/Using-vipsthumbnail.xml | 4 ++-- doc/using-C.xml | 7 +++--- doc/using-command-line.xml | 6 ++--- 8 files changed, 63 insertions(+), 48 deletions(-) diff --git a/doc/How-it-opens-files.md b/doc/How-it-opens-files.md index 329a9fe6b3..160cca2107 100644 --- a/doc/How-it-opens-files.md +++ b/doc/How-it-opens-files.md @@ -105,7 +105,7 @@ bottom-to-top. Unfortunately libjpeg only supports top-to-bottom reading and writing, so libvips must convert `fred.jpg` to a random access format before it can run the flip operation. -However many useful operations do not require true random access.  For +However many useful operations do not require true random access. For example: ```bash diff --git a/doc/How-it-opens-files.xml b/doc/How-it-opens-files.xml index d61930345c..cfcd058e1c 100644 --- a/doc/How-it-opens-files.xml +++ b/doc/How-it-opens-files.xml @@ -82,7 +82,7 @@ $ vips flip fred.jpg jim.jpg vertical In order to write jim.jpg top-to-bottom, it’ll have to read fred.jpg bottom-to-top. Unfortunately libjpeg only supports top-to-bottom reading and writing, so libvips must convert fred.jpg to a random access format before it can run the flip operation. - However many useful operations do not require true random access.  For example: + However many useful operations do not require true random access. For example: $ vips shrink fred.png jim.png 10 10 diff --git a/doc/Making-image-pyramids.md b/doc/Making-image-pyramids.md index 5e423fdff6..f6f99952cd 100644 --- a/doc/Making-image-pyramids.md +++ b/doc/Making-image-pyramids.md @@ -17,7 +17,7 @@ image viewers. It's fast and can generate pyramids for large images using only a small amount of memory. The TIFF writer, `vips_tiffsave()` can also build tiled pyramidal TIFF images, -but that's very simple to use. This page concentrates on the DeepZoom builder. +but that's very simple to use. This page concentrates on the DeepZoom builder. Run dzsave with no arguments to see a summary: @@ -25,15 +25,15 @@ Run dzsave with no arguments to see a summary: $ vips dzsave save image to deepzoom file usage: - dzsave in filename + dzsave in filename [--option-name option-value ...] where: in - Image to save, input VipsImage filename - Filename to save to, input gchararray optional arguments: - basename - Base name to save to, input gchararray + imagename - Image name, input gchararray layout - Directory layout, input VipsForeignDzLayout - default: dz - allowed: dz, zoomify, google, iiif, iiif3 + default enum: dz + allowed enums: dz, zoomify, google, iiif, iiif3 suffix - Filename suffix for tiles, input gchararray overlap - Tile overlap in pixels, input gint default: 1 @@ -44,24 +44,32 @@ optional arguments: centre - Center image in tile, input gboolean default: false depth - Pyramid depth, input VipsForeignDzDepth - default: onepixel - allowed: onepixel, onetile, one + default enum: onepixel + allowed enums: onepixel, onetile, one angle - Rotate image during save, input VipsAngle - default: d0 - allowed: d0, d90, d180, d270 + default enum: d0 + allowed enums: d0, d90, d180, d270 container - Pyramid container type, input VipsForeignDzContainer - default: fs - allowed: fs, zip - properties - Write a properties file to the output directory, input -gboolean - default: false + default enum: fs + allowed enums: fs, zip, szi compression - ZIP deflate compression level, input gint default: 0 min: -1, max: 9 - strip - Strip all metadata from image, input gboolean - default: false + region-shrink - Method to shrink regions, input VipsRegionShrink + default enum: mean + allowed enums: mean, median, mode, max, min, nearest + skip-blanks - Skip tiles which are nearly equal to the background, input gint + default: -1 + min: -1, max: 65535 + id - Resource ID, input gchararray + Q - Q factor, input gint + default: 75 + min: 1, max: 100 + keep - Which metadata to retain, input VipsForeignKeep + default flags: exif:xmp:iptc:icc:other:all + allowed flags: none, exif, xmp, iptc, icc, other, all background - Background value, input VipsArrayDouble -operation flags: sequential nocache +operation flags: sequential nocache ``` You can also call `vips_dzsave()` from any language with a libvips binding, or @@ -78,7 +86,7 @@ $ vips dzsave huge.tif mydz This will create a directory called `mydz_files` containing the image tiles, and write a file called `mydz.dzi` containing the image -metadata.  +metadata. You can use the `--suffix` option to control how tiles are written. For example: diff --git a/doc/Making-image-pyramids.xml b/doc/Making-image-pyramids.xml index 8c2f6510fd..5ba725152d 100644 --- a/doc/Making-image-pyramids.xml +++ b/doc/Making-image-pyramids.xml @@ -24,15 +24,15 @@ $ vips dzsave save image to deepzoom file usage: - dzsave in filename + dzsave in filename [--option-name option-value ...] where: in - Image to save, input VipsImage filename - Filename to save to, input gchararray optional arguments: - basename - Base name to save to, input gchararray + imagename - Image name, input gchararray layout - Directory layout, input VipsForeignDzLayout - default: dz - allowed: dz, zoomify, google, iiif, iiif3 + default enum: dz + allowed enums: dz, zoomify, google, iiif, iiif3 suffix - Filename suffix for tiles, input gchararray overlap - Tile overlap in pixels, input gint default: 1 @@ -43,24 +43,32 @@ optional arguments: centre - Center image in tile, input gboolean default: false depth - Pyramid depth, input VipsForeignDzDepth - default: onepixel - allowed: onepixel, onetile, one + default enum: onepixel + allowed enums: onepixel, onetile, one angle - Rotate image during save, input VipsAngle - default: d0 - allowed: d0, d90, d180, d270 + default enum: d0 + allowed enums: d0, d90, d180, d270 container - Pyramid container type, input VipsForeignDzContainer - default: fs - allowed: fs, zip - properties - Write a properties file to the output directory, input -gboolean - default: false + default enum: fs + allowed enums: fs, zip, szi compression - ZIP deflate compression level, input gint default: 0 min: -1, max: 9 - strip - Strip all metadata from image, input gboolean - default: false + region-shrink - Method to shrink regions, input VipsRegionShrink + default enum: mean + allowed enums: mean, median, mode, max, min, nearest + skip-blanks - Skip tiles which are nearly equal to the background, input gint + default: -1 + min: -1, max: 65535 + id - Resource ID, input gchararray + Q - Q factor, input gint + default: 75 + min: 1, max: 100 + keep - Which metadata to retain, input VipsForeignKeep + default flags: exif:xmp:iptc:icc:other:all + allowed flags: none, exif, xmp, iptc, icc, other, all background - Background value, input VipsArrayDouble -operation flags: sequential nocache +operation flags: sequential nocache You can also call vips_dzsave() from any language with a libvips binding, or by using .dz or .szi as an output file suffix. @@ -74,7 +82,7 @@ operation flags: sequential nocache $ vips dzsave huge.tif mydz - This will create a directory called mydz_files containing the image tiles, and write a file called mydz.dzi containing the image metadata.  + This will create a directory called mydz_files containing the image tiles, and write a file called mydz.dzi containing the image metadata. You can use the --suffix option to control how tiles are written. For example: diff --git a/doc/Using-vipsthumbnail.md b/doc/Using-vipsthumbnail.md index e18481c22e..98266522e3 100644 --- a/doc/Using-vipsthumbnail.md +++ b/doc/Using-vipsthumbnail.md @@ -210,7 +210,7 @@ Check the image write operations to see all the possible options. For example: $ vips jpegsave save image to jpeg file usage: - jpegsave in filename + jpegsave in filename [--option-name option-value ...] where: in - Image to save, input VipsImage filename - Filename to save to, input gchararray @@ -218,7 +218,6 @@ optional arguments: Q - Q factor, input gint default: 75 min: 1, max: 100 - profile - Filename of ICC profile to embed, input gchararray optimize-coding - Compute optimal Huffman coding tables, input gboolean default: false interlace - Generate an interlaced (progressive) jpeg, input gboolean @@ -242,6 +241,7 @@ optional arguments: default flags: exif:xmp:iptc:icc:other:all allowed flags: none, exif, xmp, iptc, icc, other, all background - Background value, input VipsArrayDouble + profile - Filename of ICC profile to embed, input gchararray ``` The `keep` option is especially useful. Many image have very large IPTC, diff --git a/doc/Using-vipsthumbnail.xml b/doc/Using-vipsthumbnail.xml index ef4c9daef0..445f62836b 100644 --- a/doc/Using-vipsthumbnail.xml +++ b/doc/Using-vipsthumbnail.xml @@ -206,7 +206,7 @@ $ vipsthumbnail fred.jpg ../jim.tif -o tn_%s.jpg[Q=90,optimize_coding] $ vips jpegsave save image to jpeg file usage: - jpegsave in filename + jpegsave in filename [--option-name option-value ...] where: in - Image to save, input VipsImage filename - Filename to save to, input gchararray @@ -214,7 +214,6 @@ optional arguments: Q - Q factor, input gint default: 75 min: 1, max: 100 - profile - Filename of ICC profile to embed, input gchararray optimize-coding - Compute optimal Huffman coding tables, input gboolean default: false interlace - Generate an interlaced (progressive) jpeg, input gboolean @@ -238,6 +237,7 @@ optional arguments: default flags: exif:xmp:iptc:icc:other:all allowed flags: none, exif, xmp, iptc, icc, other, all background - Background value, input VipsArrayDouble + profile - Filename of ICC profile to embed, input gchararray The keep option is especially useful. Many image have very large IPTC, ICC or XMP metadata items embedded in them, and removing these can give a large saving. diff --git a/doc/using-C.xml b/doc/using-C.xml index 773ddcdaaf..baf89fdac2 100644 --- a/doc/using-C.xml +++ b/doc/using-C.xml @@ -136,7 +136,7 @@ if (vips_embed(in, &out, x, y, width, height, $ vips embed embed an image in a larger image usage: - embed in out x y width height + embed in out x y width height [--option-name option-value ...] where: in - Input image, input VipsImage out - Output image, output VipsImage @@ -154,10 +154,9 @@ where: min: 1, max: 1000000000 optional arguments: extend - How to generate the extra pixels, input VipsExtend - default: black - allowed: black, copy, repeat, mirror, white, background + default enum: black + allowed enums: black, copy, repeat, mirror, white, background background - Colour for background pixels, input VipsArrayDouble -operation flags: sequential-unbuffered See #VipsOperation for more information on running operations on images. diff --git a/doc/using-command-line.xml b/doc/using-command-line.xml index d0681de076..bff7e22ebc 100644 --- a/doc/using-command-line.xml +++ b/doc/using-command-line.xml @@ -89,15 +89,15 @@ VipsOperation (operation), operations $ vips gamma gamma an image usage: - gamma in out + gamma in out [--option-name option-value ...] where: in - Input image, input VipsImage out - Output image, output VipsImage optional arguments: exponent - Gamma factor, input gdouble - default: 2.4 + default: 0.416667 min: 1e-06, max: 1000 -operation flags: sequential-unbuffered +operation flags: sequential vips_gamma() applies a gamma factor to an image. By From abcb97c0e5c483f8dd8b07d1124e3548c4bb6bfb Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 5 Mar 2025 14:49:51 +0100 Subject: [PATCH 072/174] test: reduce severity of `gifsave_timeout` (#4407) --- test/test_timeout_gifsave.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/test_timeout_gifsave.c b/test/test_timeout_gifsave.c index a47f0cd88e..7fa1253411 100644 --- a/test/test_timeout_gifsave.c +++ b/test/test_timeout_gifsave.c @@ -18,7 +18,6 @@ main(int argc, char **argv) void *buf; size_t len; gboolean is_killed = FALSE; - int ret; if (VIPS_INIT(argv[0])) vips_error_exit(NULL); @@ -36,14 +35,13 @@ main(int argc, char **argv) G_CALLBACK(eval_callback), &is_killed); buf = NULL; - ret = vips_gifsave_buffer(im, &buf, &len, NULL); - if (!ret) - printf("expected error return from vips_gifsave_buffer()\n"); + if (vips_gifsave_buffer(im, &buf, &len, NULL)) + printf("error return from vips_gifsave_buffer()\n"); g_object_unref(im); if (buf) g_free(buf); g_assert(is_killed); - return !ret; + return 0; } From d0b9bf8a6054c909729bc679aee06ea6a3c4fb75 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 8 Mar 2025 14:16:29 +0000 Subject: [PATCH 073/174] Prevent possible use-after-free when debugging via --vips-leak flag (#4411) --- ChangeLog | 1 + libvips/iofuncs/type.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8b5d4bf15e..3b4f347b7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,7 @@ - heifsave: reject multiband images [lovell] - heifload: prevent possible int overflow for large images [kleisauke] - tiffload: add missing read loop [kleisauke] +- prevent possible use-after-free when debugging via `--vips-leak` flag [lovell] 10/10/24 8.16.0 diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index d6797ae661..8c31240a47 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -198,14 +198,14 @@ vips_area_unref(VipsArea *area) VIPS_FREEF(vips_g_mutex_free, area->lock); - g_free(area); - if (vips__leak) { g_mutex_lock(vips__global_lock); vips_area_all = g_slist_remove(vips_area_all, area); g_mutex_unlock(vips__global_lock); } + g_free(area); + #ifdef DEBUG g_mutex_lock(vips__global_lock); printf("vips_area_unref: free .. total = %d\n", From 82c7c05cb02a52750251bb4cc69d67f40568cf98 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sun, 9 Mar 2025 11:13:50 +0000 Subject: [PATCH 074/174] Avoid possible overflow when multiplication result is cast up/down (#4412) --- ChangeLog | 1 + libvips/arithmetic/hist_find_indexed.c | 4 ++-- libvips/arithmetic/project.c | 4 ++-- libvips/colour/LCh2UCS.c | 4 ++-- libvips/conversion/bandfold.c | 2 +- libvips/conversion/bandunfold.c | 2 +- libvips/conversion/composite.cpp | 2 +- libvips/conversion/embed.c | 2 +- libvips/foreign/jp2ksave.c | 2 +- libvips/foreign/nsgifload.c | 2 +- libvips/foreign/tiff2vips.c | 4 ++-- libvips/foreign/vips2tiff.c | 2 +- libvips/foreign/webp2vips.c | 2 +- libvips/foreign/webpsave.c | 2 +- libvips/iofuncs/image.c | 2 +- libvips/iofuncs/sink.c | 2 +- libvips/iofuncs/sinkdisc.c | 2 +- libvips/iofuncs/sinkmemory.c | 2 +- libvips/mosaicing/matrixinvert.c | 2 +- 19 files changed, 23 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3b4f347b7e..5c14bf7d54 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,6 +26,7 @@ - heifload: prevent possible int overflow for large images [kleisauke] - tiffload: add missing read loop [kleisauke] - prevent possible use-after-free when debugging via `--vips-leak` flag [lovell] +- avoid possible overflow when multiplication result is cast up [lovell] 10/10/24 8.16.0 diff --git a/libvips/arithmetic/hist_find_indexed.c b/libvips/arithmetic/hist_find_indexed.c index 9c61ab7684..e6436d7294 100644 --- a/libvips/arithmetic/hist_find_indexed.c +++ b/libvips/arithmetic/hist_find_indexed.c @@ -117,8 +117,8 @@ histogram_new(VipsHistFindIndexed *indexed) !(hist->reg = vips_region_new(indexed->index_ready))) return NULL; - memset(hist->bins, 0, bands * hist->size * sizeof(double)); - memset(hist->init, 0, hist->size * sizeof(int)); + memset(hist->bins, 0, (size_t) bands * hist->size * sizeof(double)); + memset(hist->init, 0, (size_t) hist->size * sizeof(int)); return hist; } diff --git a/libvips/arithmetic/project.c b/libvips/arithmetic/project.c index e2f7f240df..9585cb0426 100644 --- a/libvips/arithmetic/project.c +++ b/libvips/arithmetic/project.c @@ -109,8 +109,8 @@ histogram_new(VipsProject *project) !hist->row_sums) return NULL; - memset(hist->column_sums, 0, psize * in->Xsize); - memset(hist->row_sums, 0, psize * in->Ysize); + memset(hist->column_sums, 0, (size_t) psize * in->Xsize); + memset(hist->row_sums, 0, (size_t) psize * in->Ysize); return hist; } diff --git a/libvips/colour/LCh2UCS.c b/libvips/colour/LCh2UCS.c index eeb2fe669a..1d3fa92873 100644 --- a/libvips/colour/LCh2UCS.c +++ b/libvips/colour/LCh2UCS.c @@ -165,9 +165,9 @@ vips_col_Ch2hcmc(float C, float h) } P = cos(VIPS_RAD(k7 * h + k8)); - D = k4 + k5 * P * pow(VIPS_FABS(P), k6); + D = k4 + k5 * P * powf(fabsf(P), k6); g = C * C * C * C; - f = sqrt(g / (g + 1900.0)); + f = sqrtf(g / (g + 1900.0F)); hcmc = h + D * f; return hcmc; diff --git a/libvips/conversion/bandfold.c b/libvips/conversion/bandfold.c index 707e6d3187..33dbee4323 100644 --- a/libvips/conversion/bandfold.c +++ b/libvips/conversion/bandfold.c @@ -96,7 +96,7 @@ vips_bandfold_gen(VipsRegion *out_region, /* We can't use vips_region_region() since we change pixel * coordinates. */ - memcpy(q, p, psize * r->width); + memcpy(q, p, (size_t) psize * r->width); } return 0; diff --git a/libvips/conversion/bandunfold.c b/libvips/conversion/bandunfold.c index 6bec18c835..cfc4f9df31 100644 --- a/libvips/conversion/bandunfold.c +++ b/libvips/conversion/bandunfold.c @@ -99,7 +99,7 @@ vips_bandunfold_gen(VipsRegion *out_region, /* We can't use vips_region_region() since we change pixel * coordinates. */ - memcpy(q, p, r->width * psize); + memcpy(q, p, (size_t) r->width * psize); } return 0; diff --git a/libvips/conversion/composite.cpp b/libvips/conversion/composite.cpp index 2c5bafd66f..86f83b4c1a 100644 --- a/libvips/conversion/composite.cpp +++ b/libvips/conversion/composite.cpp @@ -899,7 +899,7 @@ vips_composite_base_blend3(VipsCompositeSequence *seq, /* You can't sqrt a vector, so we must loop. */ for (int b = 0; b < 3; b++) { - double g; + float g; if (B[b] <= 0.25) g = ((16 * B[b] - 12) * B[b] + 4) * B[b]; diff --git a/libvips/conversion/embed.c b/libvips/conversion/embed.c index c1cbf181de..5d4b96b0dd 100644 --- a/libvips/conversion/embed.c +++ b/libvips/conversion/embed.c @@ -217,7 +217,7 @@ vips_embed_base_paint_edge(VipsEmbedBase *base, */ for (y = 0; y < todo.height; y++) { q = VIPS_REGION_ADDR(out_region, todo.left, todo.top + y); - memcpy(q, p, bs * todo.width); + memcpy(q, p, (size_t) bs * todo.width); } } diff --git a/libvips/foreign/jp2ksave.c b/libvips/foreign/jp2ksave.c index bbdc2025ae..58205af906 100644 --- a/libvips/foreign/jp2ksave.c +++ b/libvips/foreign/jp2ksave.c @@ -482,7 +482,7 @@ vips_foreign_save_jp2k_sizeof_tile(VipsForeignSaveJp2k *jp2k, VipsRect *tile) (double) tile->height / comp->dy); ; - size += output_width * output_height * sizeof_element; + size += (size_t) output_width * output_height * sizeof_element; } return size; diff --git a/libvips/foreign/nsgifload.c b/libvips/foreign/nsgifload.c index ba24ff2b8c..366a3f6837 100644 --- a/libvips/foreign/nsgifload.c +++ b/libvips/foreign/nsgifload.c @@ -512,7 +512,7 @@ vips_foreign_load_nsgif_generate(VipsRegion *out_region, gif->frame_number = page; } - p = (VipsPel *) gif->bitmap + line * gif->info->width * sizeof(int); + p = (VipsPel *) gif->bitmap + (size_t) line * gif->info->width * sizeof(int); q = VIPS_REGION_ADDR(out_region, 0, r->top + y); if (gif->has_transparency) memcpy(q, p, VIPS_REGION_SIZEOF_LINE(out_region)); diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index 3977031811..dbdfe679f7 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -1659,7 +1659,7 @@ static void rtiff_memcpy_f16_line(Rtiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client) { VipsImage *im = (VipsImage *) client; - size_t len = n * im->Bands; + size_t len = (size_t) n * im->Bands; if (im->BandFmt == VIPS_FORMAT_COMPLEX || im->BandFmt == VIPS_FORMAT_DPCOMPLEX) @@ -2107,7 +2107,7 @@ rtiff_decompress_jpeg_run(Rtiff *rtiff, j_decompress_ptr cinfo, } jpeg_calc_output_dimensions(cinfo); - bytes_per_scanline = cinfo->output_width * bytes_per_pixel; + bytes_per_scanline = (size_t) cinfo->output_width * bytes_per_pixel; /* Double-check tile dimensions. */ diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 9a85861409..afad50b8bc 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -2302,7 +2302,7 @@ wtiff_copy_tiles(Wtiff *wtiff, TIFF *out, TIFF *in) * simpler than searching every page for the largest tile with * TIFFTAG_TILEBYTECOUNTS. */ - tile_size = 2 * wtiff->tls * wtiff->tileh; + tile_size = (tsize_t) 2 * wtiff->tls * wtiff->tileh; buf = vips_malloc(NULL, tile_size); diff --git a/libvips/foreign/webp2vips.c b/libvips/foreign/webp2vips.c index 03cd483c13..2844dae8d4 100644 --- a/libvips/foreign/webp2vips.c +++ b/libvips/foreign/webp2vips.c @@ -305,7 +305,7 @@ vips_image_paint_image(VipsImage *frame, } else memcpy((char *) q, (char *) p, - ovl.width * ps); + (size_t) ovl.width * ps); p += VIPS_IMAGE_SIZEOF_LINE(sub); q += VIPS_IMAGE_SIZEOF_LINE(frame); diff --git a/libvips/foreign/webpsave.c b/libvips/foreign/webpsave.c index 452a77d7cc..4a44954e9f 100644 --- a/libvips/foreign/webpsave.c +++ b/libvips/foreign/webpsave.c @@ -355,7 +355,7 @@ vips_foreign_save_webp_sink_disc(VipsRegion *region, VipsRect *area, void *a) memcpy(webp->frame_bytes + area->width * webp->write_y * save->ready->Bands, VIPS_REGION_ADDR(region, 0, area->top + i), - area->width * save->ready->Bands); + (size_t) area->width * save->ready->Bands); webp->write_y += 1; diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 7794a0bf1c..e6bcc4c05d 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -3241,7 +3241,7 @@ vips_image_write_line(VipsImage *image, int ypos, VipsPel *linebuffer) /* Trigger evaluation callbacks for this image. */ - vips_image_eval(image, ypos * image->Xsize); + vips_image_eval(image, (guint64) ypos * image->Xsize); if (vips_image_iskilled(image)) return -1; diff --git a/libvips/iofuncs/sink.c b/libvips/iofuncs/sink.c index 5ae8ea1e92..80821855fe 100644 --- a/libvips/iofuncs/sink.c +++ b/libvips/iofuncs/sink.c @@ -238,7 +238,7 @@ sink_area_allocate_fn(VipsThreadState *state, void *a, gboolean *stop) /* Add the number of pixels we've just allocated to progress. */ - sink_base->processed += state->pos.width * state->pos.height; + sink_base->processed += (guint64) state->pos.width * state->pos.height; return 0; } diff --git a/libvips/iofuncs/sinkdisc.c b/libvips/iofuncs/sinkdisc.c index 86a2549837..718734fe3e 100644 --- a/libvips/iofuncs/sinkdisc.c +++ b/libvips/iofuncs/sinkdisc.c @@ -410,7 +410,7 @@ wbuffer_allocate_fn(VipsThreadState *state, void *a, gboolean *stop) /* Add the number of pixels we've just allocated to progress. */ - sink_base->processed += state->pos.width * state->pos.height; + sink_base->processed += (guint64) state->pos.width * state->pos.height; return 0; } diff --git a/libvips/iofuncs/sinkmemory.c b/libvips/iofuncs/sinkmemory.c index 7808fc95f6..ba8994f47b 100644 --- a/libvips/iofuncs/sinkmemory.c +++ b/libvips/iofuncs/sinkmemory.c @@ -244,7 +244,7 @@ sink_memory_area_allocate_fn(VipsThreadState *state, void *a, gboolean *stop) /* Add the number of pixels we've just allocated to progress. */ - sink_base->processed += state->pos.width * state->pos.height; + sink_base->processed += (guint64) state->pos.width * state->pos.height; return 0; } diff --git a/libvips/mosaicing/matrixinvert.c b/libvips/mosaicing/matrixinvert.c index 22bbb1cc4a..65303b9fa6 100644 --- a/libvips/mosaicing/matrixinvert.c +++ b/libvips/mosaicing/matrixinvert.c @@ -129,7 +129,7 @@ lu_decomp(VipsImage *mat) /* copy all coefficients and then perform decomposition in-place */ memcpy(VIPS_MATRIX(lu, 0, 0), VIPS_MATRIX(mat, 0, 0), - mat->Xsize * mat->Xsize * sizeof(double)); + (size_t) mat->Xsize * mat->Xsize * sizeof(double)); for (i = 0; i < mat->Xsize; ++i) { row_scale[i] = 0.0; From 7a6eb29c248d43e0a23cd9eb3f5c4a7d6e9ff232 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 10 Mar 2025 12:41:04 +0100 Subject: [PATCH 075/174] Deprecate math macros (#4414) * Deprecate math macros We can simply use the functions from `` instead of conditionally relying on GCC and Clang's `__builtin_*` functions. The likely reason for commit 90c1fb9a9444dde41e3db8fd18c41f83c31c7e5f was due to https://sourceware.org/bugzilla/show_bug.cgi?id=17441, which was resolved in glibc 2.23. * Restore `VIPS_ABS` macro to ensure compat We also need to support floating-point arguments, so we can't use `abs()` here, as it only works with integers. --- libvips/arithmetic/abs.c | 2 +- libvips/arithmetic/deviate.c | 2 +- libvips/arithmetic/divide.c | 2 +- libvips/arithmetic/max.c | 4 ++-- libvips/arithmetic/maxpair.c | 2 +- libvips/arithmetic/measure.c | 4 ++-- libvips/arithmetic/min.c | 4 ++-- libvips/arithmetic/minpair.c | 2 +- libvips/arithmetic/remainder.c | 2 +- libvips/arithmetic/round.c | 6 ++--- libvips/arithmetic/stats.c | 4 ++-- libvips/colour/HSV2sRGB.c | 2 +- libvips/colour/LCh2UCS.c | 2 +- libvips/colour/Lab2LabQ.c | 4 ++-- libvips/colour/LabQ2sRGB.c | 14 +++++------ libvips/colour/UCS2LCh.c | 6 ++--- libvips/colour/dE00.c | 6 ++--- libvips/conversion/unpremultiply.c | 4 ++-- libvips/convolution/conva.c | 6 ++--- libvips/convolution/convasep.c | 2 +- libvips/convolution/convi.c | 20 ++++++++-------- libvips/convolution/edge.c | 2 +- libvips/convolution/sharpen.c | 2 +- libvips/create/buildlut.c | 8 +++---- libvips/create/gaussmat.c | 2 +- libvips/create/logmat.c | 4 ++-- libvips/deprecated/im_vips2mask.c | 10 ++++---- libvips/foreign/cgifsave.c | 2 +- libvips/foreign/dzsave.c | 2 +- libvips/foreign/exif.c | 4 ++-- libvips/foreign/jxlload.c | 4 ++-- libvips/foreign/matrixload.c | 4 ++-- libvips/foreign/pdfiumload.c | 4 ++-- libvips/foreign/popplerload.c | 4 ++-- libvips/foreign/ppmload.c | 4 ++-- libvips/foreign/spngsave.c | 4 ++-- libvips/foreign/vips2jpeg.c | 12 +++++----- libvips/foreign/vips2magick.c | 2 +- libvips/foreign/vipspng.c | 2 +- libvips/foreign/webp2vips.c | 14 +++++------ libvips/histogram/hist_plot.c | 2 +- libvips/include/vips/basic.h | 12 ++++++++++ libvips/include/vips/util.h | 37 ++++++++++-------------------- libvips/mosaicing/im_avgdxdy.c | 4 ++-- libvips/resample/affine.c | 4 ++-- libvips/resample/mapim.c | 4 ++-- libvips/resample/reduceh.cpp | 4 ++-- libvips/resample/reducev.cpp | 10 ++++---- libvips/resample/resize.c | 16 ++++++------- libvips/resample/shrinkh.c | 2 +- libvips/resample/shrinkv.c | 2 +- libvips/resample/templates.h | 8 +++---- libvips/resample/thumbnail.c | 4 ++-- 53 files changed, 149 insertions(+), 150 deletions(-) diff --git a/libvips/arithmetic/abs.c b/libvips/arithmetic/abs.c index 72db08f390..d29f821be3 100644 --- a/libvips/arithmetic/abs.c +++ b/libvips/arithmetic/abs.c @@ -116,7 +116,7 @@ vips_abs_build(VipsObject *object) int x; \ \ for (x = 0; x < sz; x++) \ - q[x] = VIPS_FABS(p[x]); \ + q[x] = fabs(p[x]); \ } /* Complex abs operation: calculate modulus. diff --git a/libvips/arithmetic/deviate.c b/libvips/arithmetic/deviate.c index 836ac77474..b5a05dab8c 100644 --- a/libvips/arithmetic/deviate.c +++ b/libvips/arithmetic/deviate.c @@ -120,7 +120,7 @@ vips_deviate_build(VipsObject *object) s2 = deviate->sum2; g_object_set(object, - "out", sqrt(VIPS_FABS(s2 - (s * s / vals)) / (vals - 1)), + "out", sqrt(fabs(s2 - (s * s / vals)) / (vals - 1)), NULL); return 0; diff --git a/libvips/arithmetic/divide.c b/libvips/arithmetic/divide.c index 26a43263c1..4ae781ebee 100644 --- a/libvips/arithmetic/divide.c +++ b/libvips/arithmetic/divide.c @@ -97,7 +97,7 @@ G_DEFINE_TYPE(VipsDivide, vips_divide, VIPS_TYPE_BINARY); q[0] = 0.0; \ q[1] = 0.0; \ } \ - else if (VIPS_FABS(right[0]) > VIPS_FABS(right[1])) { \ + else if (fabs(right[0]) > fabs(right[1])) { \ double a = right[1] / right[0]; \ double b = right[0] + right[1] * a; \ \ diff --git a/libvips/arithmetic/max.c b/libvips/arithmetic/max.c index cbf0e417fa..bebb749b98 100644 --- a/libvips/arithmetic/max.c +++ b/libvips/arithmetic/max.c @@ -337,7 +337,7 @@ vips_max_stop(VipsStatistic *statistic, void *seq) TYPE m; \ \ for (i = 0; i < sz && values->n < values->size; i++) \ - if (!VIPS_ISNAN(p[i])) \ + if (!isnan(p[i])) \ vips_values_add(values, p[i], x + i / bands, y); \ m = values->value[0]; \ \ @@ -358,7 +358,7 @@ vips_max_stop(VipsStatistic *statistic, void *seq) for (i = 0; i < sz && values->n < values->size; i++) { \ TYPE mod2 = p[0] * p[0] + p[1] * p[1]; \ \ - if (!VIPS_ISNAN(mod2)) \ + if (!isnan(mod2)) \ vips_values_add(values, p[i], x + i / bands, y); \ \ p += 2; \ diff --git a/libvips/arithmetic/maxpair.c b/libvips/arithmetic/maxpair.c index 85112cdb14..052068457c 100644 --- a/libvips/arithmetic/maxpair.c +++ b/libvips/arithmetic/maxpair.c @@ -70,7 +70,7 @@ G_DEFINE_TYPE(VipsMaxpair, vips_maxpair, VIPS_TYPE_BINARY); TYPE *restrict q = (TYPE *) out; \ \ for (int x = 0; x < sz; x++) \ - q[x] = VIPS_FMAX(left[x], right[x]); \ + q[x] = fmax(left[x], right[x]); \ } static void diff --git a/libvips/arithmetic/measure.c b/libvips/arithmetic/measure.c index a035b14b5f..886bd98de7 100644 --- a/libvips/arithmetic/measure.c +++ b/libvips/arithmetic/measure.c @@ -159,8 +159,8 @@ vips_measure_build(VipsObject *object) * averages near zero (can get these if use * measure on IM_TYPE_LAB images). */ - if (dev * 5 > VIPS_FABS(avg) && - VIPS_FABS(avg) > 3) + if (dev * 5 > fabs(avg) && + fabs(avg) > 3) g_warning(_("%s: " "patch %d x %d, " "band %d: " diff --git a/libvips/arithmetic/min.c b/libvips/arithmetic/min.c index 27ccf194c0..e6e3e7d95f 100644 --- a/libvips/arithmetic/min.c +++ b/libvips/arithmetic/min.c @@ -337,7 +337,7 @@ vips_min_stop(VipsStatistic *statistic, void *seq) TYPE m; \ \ for (i = 0; i < sz && values->n < values->size; i++) \ - if (!VIPS_ISNAN(p[i])) \ + if (!isnan(p[i])) \ vips_values_add(values, p[i], x + i / bands, y); \ m = values->value[0]; \ \ @@ -358,7 +358,7 @@ vips_min_stop(VipsStatistic *statistic, void *seq) for (i = 0; i < sz && values->n < values->size; i++) { \ TYPE mod2 = p[0] * p[0] + p[1] * p[1]; \ \ - if (!VIPS_ISNAN(mod2)) \ + if (!isnan(mod2)) \ vips_values_add(values, p[i], x + i / bands, y); \ \ p += 2; \ diff --git a/libvips/arithmetic/minpair.c b/libvips/arithmetic/minpair.c index 6b4c653f20..a274efb159 100644 --- a/libvips/arithmetic/minpair.c +++ b/libvips/arithmetic/minpair.c @@ -70,7 +70,7 @@ G_DEFINE_TYPE(VipsMinpair, vips_minpair, VIPS_TYPE_BINARY); TYPE *restrict q = (TYPE *) out; \ \ for (int x = 0; x < sz; x++) \ - q[x] = VIPS_FMIN(left[x], right[x]); \ + q[x] = fmin(left[x], right[x]); \ } static void diff --git a/libvips/arithmetic/remainder.c b/libvips/arithmetic/remainder.c index 58e8090d12..5d11effdcb 100644 --- a/libvips/arithmetic/remainder.c +++ b/libvips/arithmetic/remainder.c @@ -113,7 +113,7 @@ vips_remainder_build(VipsObject *object) double a = p1[x]; \ double b = p2[x]; \ \ - q[x] = b ? a - b * VIPS_FLOOR(a / b) : -1; \ + q[x] = b ? a - b * floor(a / b) : -1; \ } \ } diff --git a/libvips/arithmetic/round.c b/libvips/arithmetic/round.c index 4dda0a1220..4f8bf7adfe 100644 --- a/libvips/arithmetic/round.c +++ b/libvips/arithmetic/round.c @@ -127,13 +127,13 @@ vips_round_buffer(VipsArithmetic *arithmetic, switch (round->round) { case VIPS_OPERATION_ROUND_RINT: - SWITCH(VIPS_RINT); + SWITCH(rint); break; case VIPS_OPERATION_ROUND_CEIL: - SWITCH(VIPS_CEIL); + SWITCH(ceil); break; case VIPS_OPERATION_ROUND_FLOOR: - SWITCH(VIPS_FLOOR); + SWITCH(floor); break; default: diff --git a/libvips/arithmetic/stats.c b/libvips/arithmetic/stats.c index d85d983a78..0c8428c3a0 100644 --- a/libvips/arithmetic/stats.c +++ b/libvips/arithmetic/stats.c @@ -160,14 +160,14 @@ vips_stats_build(VipsObject *object) row[COL_AVG] = row[COL_SUM] / pels; row[COL_SD] = sqrt( - VIPS_FABS(row[COL_SUM2] - + fabs(row[COL_SUM2] - (row[COL_SUM] * row[COL_SUM] / pels)) / (pels - 1)); } row0[COL_AVG] = row0[COL_SUM] / vals; row0[COL_SD] = sqrt( - VIPS_FABS(row0[COL_SUM2] - + fabs(row0[COL_SUM2] - (row0[COL_SUM] * row0[COL_SUM] / vals)) / (vals - 1)); diff --git a/libvips/colour/HSV2sRGB.c b/libvips/colour/HSV2sRGB.c index 2555609760..51bceb1e23 100644 --- a/libvips/colour/HSV2sRGB.c +++ b/libvips/colour/HSV2sRGB.c @@ -63,7 +63,7 @@ vips_HSV2sRGB_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) float c, x, m; c = p[2] * p[1] / 255.0; - x = c * (1 - VIPS_FABS(fmod(p[0] / SIXTH_OF_CHAR, 2) - 1)); + x = c * (1 - fabs(fmod(p[0] / SIXTH_OF_CHAR, 2) - 1)); m = p[2] - c; if (p[0] < (int) SIXTH_OF_CHAR) { diff --git a/libvips/colour/LCh2UCS.c b/libvips/colour/LCh2UCS.c index eeb2fe669a..99c9f2a7da 100644 --- a/libvips/colour/LCh2UCS.c +++ b/libvips/colour/LCh2UCS.c @@ -165,7 +165,7 @@ vips_col_Ch2hcmc(float C, float h) } P = cos(VIPS_RAD(k7 * h + k8)); - D = k4 + k5 * P * pow(VIPS_FABS(P), k6); + D = k4 + k5 * P * pow(fabs(P), k6); g = C * C * C * C; f = sqrt(g / (g + 1900.0)); hcmc = h + D * f; diff --git a/libvips/colour/Lab2LabQ.c b/libvips/colour/Lab2LabQ.c index 2059b45937..c5bf5aef11 100644 --- a/libvips/colour/Lab2LabQ.c +++ b/libvips/colour/Lab2LabQ.c @@ -103,13 +103,13 @@ vips_Lab2LabQ_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) q[0] = intv >> 2; /* drop bot 2 bits and store */ fval = 8.0 * p[1]; /* do a */ - intv = VIPS_RINT(fval); + intv = rint(fval); intv = VIPS_CLIP(-1024, intv, 1023); lsbs |= (intv & 0x7) << 3; /* 00000111 -> 00111000 */ q[1] = intv >> 3; /* drop bot 3 bits & store */ fval = 8.0 * p[2]; /* do b */ - intv = VIPS_RINT(fval); + intv = rint(fval); intv = VIPS_CLIP(-1024, intv, 1023); lsbs |= (intv & 0x7); q[2] = intv >> 3; diff --git a/libvips/colour/LabQ2sRGB.c b/libvips/colour/LabQ2sRGB.c index 2847efc7c2..f4b6d5cf13 100644 --- a/libvips/colour/LabQ2sRGB.c +++ b/libvips/colour/LabQ2sRGB.c @@ -140,7 +140,7 @@ calcul_tables(int range, int *Y2v, float *v2Y) else v = (1.0 + 0.055) * pow(f, 1.0 / 2.4) - 0.055; - Y2v[i] = VIPS_RINT((range - 1) * v); + Y2v[i] = rint((range - 1) * v); } /* Copy the final element. This is used in the piecewise linear @@ -303,7 +303,7 @@ vips_col_scRGB2sRGB(int range, int *lut, * Don't use isnormal(), it is false for 0.0 and for subnormal * numbers. */ - if (VIPS_ISNAN(R) || VIPS_ISNAN(G) || VIPS_ISNAN(B)) { + if (isnan(R) || isnan(G) || isnan(B)) { *r = 0; *g = 0; *b = 0; @@ -337,19 +337,19 @@ vips_col_scRGB2sRGB(int range, int *lut, CLIP(0, Yf, maxval); Yi = (int) Yf; v = lut[Yi] + (lut[Yi + 1] - lut[Yi]) * (Yf - Yi); - *r = VIPS_RINT(v); + *r = rint(v); Yf = G * maxval; CLIP(0, Yf, maxval); Yi = (int) Yf; v = lut[Yi] + (lut[Yi + 1] - lut[Yi]) * (Yf - Yi); - *g = VIPS_RINT(v); + *g = rint(v); Yf = B * maxval; CLIP(0, Yf, maxval); Yi = (int) Yf; v = lut[Yi] + (lut[Yi + 1] - lut[Yi]) * (Yf - Yi); - *b = VIPS_RINT(v); + *b = rint(v); if (og_ret) *og_ret = og; @@ -399,7 +399,7 @@ vips_col_scRGB2BW(int range, int *lut, float R, float G, float B, /* Y can be Nan. Throw those values out, they will break * our clipping. */ - if (VIPS_ISNAN(Y)) { + if (isnan(Y)) { *g = 0; return -1; @@ -417,7 +417,7 @@ vips_col_scRGB2BW(int range, int *lut, float R, float G, float B, CLIP(0, Yf, maxval); Yi = (int) Yf; v = lut[Yi] + (lut[Yi + 1] - lut[Yi]) * (Yf - Yi); - *g = VIPS_RINT(v); + *g = rint(v); if (og_ret) *og_ret = og; diff --git a/libvips/colour/UCS2LCh.c b/libvips/colour/UCS2LCh.c index bda6630c07..1baf4d297e 100644 --- a/libvips/colour/UCS2LCh.c +++ b/libvips/colour/UCS2LCh.c @@ -151,7 +151,7 @@ vips_col_Lcmc2L(float Lcmc) { int known; - known = VIPS_FLOOR(Lcmc * 10.0); + known = floor(Lcmc * 10.0); known = VIPS_CLIP(0, known, 999); return LI[known] + @@ -173,7 +173,7 @@ vips_col_Ccmc2C(float Ccmc) { int known; - known = VIPS_FLOOR(Ccmc * 10.0); + known = floor(Ccmc * 10.0); known = VIPS_CLIP(0, known, 2999); return CI[known] + @@ -202,7 +202,7 @@ vips_col_Chcmc2h(float C, float hcmc) r = (int) ((C + 1.0) / 2.0); r = VIPS_CLIP(0, r, 99); - known = VIPS_FLOOR(hcmc); + known = floor(hcmc); known = VIPS_CLIP(0, known, 359); return hI[r][known] + diff --git a/libvips/colour/dE00.c b/libvips/colour/dE00.c index 710ba4d0d0..f5eca5072b 100644 --- a/libvips/colour/dE00.c +++ b/libvips/colour/dE00.c @@ -133,9 +133,9 @@ vips_col_dE00(float L1, float a1, float b1, */ double Ldb = (L1d + L2d) / 2; double Cdb = (C1d + C2d) / 2; - double hdb = VIPS_FABS(h1d - h2d) < 180 + double hdb = fabs(h1d - h2d) < 180 ? (h1d + h2d) / 2 - : VIPS_FABS(h1d + h2d - 360) / 2; + : fabs(h1d + h2d - 360) / 2; /* dtheta, RC */ @@ -162,7 +162,7 @@ vips_col_dE00(float L1, float a1, float b1, /* hue difference ... careful! */ - double dhd = VIPS_FABS(h1d - h2d) < 180 + double dhd = fabs(h1d - h2d) < 180 ? h1d - h2d : 360 - (h1d - h2d); diff --git a/libvips/conversion/unpremultiply.c b/libvips/conversion/unpremultiply.c index db489cf1d3..d6f6659668 100644 --- a/libvips/conversion/unpremultiply.c +++ b/libvips/conversion/unpremultiply.c @@ -138,7 +138,7 @@ G_DEFINE_TYPE(VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION); \ for (x = 0; x < width; x++) { \ IN alpha = p[alpha_band]; \ - OUT factor = VIPS_ABS(alpha) < 0.01 ? 0 : max_alpha / alpha; \ + OUT factor = fabs(alpha) < 0.01 ? 0 : max_alpha / alpha; \ \ for (i = 0; i < alpha_band; i++) \ q[i] = factor * p[i]; \ @@ -158,7 +158,7 @@ G_DEFINE_TYPE(VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION); \ for (x = 0; x < width; x++) { \ IN alpha = p[3]; \ - OUT factor = VIPS_ABS(alpha) < 0.01 ? 0 : max_alpha / alpha; \ + OUT factor = fabs(alpha) < 0.01 ? 0 : max_alpha / alpha; \ \ q[0] = factor * p[0]; \ q[1] = factor * p[1]; \ diff --git a/libvips/convolution/conva.c b/libvips/convolution/conva.c index f76027a388..463e91f7e1 100644 --- a/libvips/convolution/conva.c +++ b/libvips/convolution/conva.c @@ -331,9 +331,9 @@ vips_conva_decompose_hlines(VipsConva *conva) * fixed n-lines which includes any negative parts. */ depth = (max - min) / conva->layers; - layers_above = VIPS_CEIL(max / depth); + layers_above = ceil(max / depth); depth = max / layers_above; - layers_below = VIPS_FLOOR(min / depth); + layers_below = floor(min / depth); conva->layers = layers_above - layers_below; // FIXME: Invalidates operation cache VIPS_DEBUG_MSG("vips_conva_decompose_hlines: depth = %g, layers = %d\n", @@ -744,7 +744,7 @@ vips_conva_decompose_boxes(VipsConva *conva) for (z = 0; z < size; z++) sum += fabs(coeff[z]); - conva->divisor = VIPS_RINT(area * scale / sum); + conva->divisor = rint(area * scale / sum); conva->rounding = (conva->divisor + 1) / 2; conva->offset = offset; diff --git a/libvips/convolution/convasep.c b/libvips/convolution/convasep.c index 64c9fa7bcc..a43d219c7c 100644 --- a/libvips/convolution/convasep.c +++ b/libvips/convolution/convasep.c @@ -303,7 +303,7 @@ vips_convasep_decompose(VipsConvasep *convasep) for (z = 0; z < convasep->width; z++) sum += coeff[z]; - convasep->divisor = VIPS_RINT(sum * area / scale); + convasep->divisor = rint(sum * area / scale); if (convasep->divisor == 0) convasep->divisor = 1; convasep->rounding = (convasep->divisor + 1) / 2; diff --git a/libvips/convolution/convi.c b/libvips/convolution/convi.c index 141d7c72ec..f44cc72819 100644 --- a/libvips/convolution/convi.c +++ b/libvips/convolution/convi.c @@ -309,7 +309,7 @@ vips_convi_uchar_vector_gen(VipsRegion *out_region, VipsConvi *convi = (VipsConvi *) b; VipsConvolution *convolution = (VipsConvolution *) convi; VipsImage *M = convolution->M; - int offset = VIPS_RINT(vips_image_get_offset(M)); + int offset = rint(vips_image_get_offset(M)); VipsImage *in = (VipsImage *) a; VipsRegion *ir = seq->ir; const int nnz = convi->nnz; @@ -521,7 +521,7 @@ vips_convi_compile_clip(VipsConvi *convi) { VipsConvolution *convolution = (VipsConvolution *) convi; VipsImage *M = convolution->M; - int offset = VIPS_RINT(vips_image_get_offset(M)); + int offset = rint(vips_image_get_offset(M)); OrcProgram *p; OrcCompileResult result; @@ -755,9 +755,9 @@ vips_convi_gen(VipsRegion *out_region, VipsConvi *convi = (VipsConvi *) b; VipsConvolution *convolution = (VipsConvolution *) convi; VipsImage *M = convolution->M; - int scale = VIPS_RINT(vips_image_get_scale(M)); + int scale = rint(vips_image_get_scale(M)); int rounding = scale / 2; - int offset = VIPS_RINT(vips_image_get_offset(M)); + int offset = rint(vips_image_get_offset(M)); VipsImage *in = (VipsImage *) a; VipsRegion *ir = seq->ir; int *restrict t = convi->coeff; @@ -890,12 +890,12 @@ vips__image_intize(VipsImage *in, VipsImage **out) for (y = 0; y < t->Ysize; y++) for (x = 0; x < t->Xsize; x++) *VIPS_MATRIX(*out, x, y) = - VIPS_RINT(*VIPS_MATRIX(t, x, y)); + rint(*VIPS_MATRIX(t, x, y)); - out_scale = VIPS_RINT(vips_image_get_scale(t)); + out_scale = rint(vips_image_get_scale(t)); if (out_scale == 0) out_scale = 1; - out_offset = VIPS_RINT(vips_image_get_offset(t)); + out_offset = rint(vips_image_get_offset(t)); /* Now convolve a 1 everywhere image with the int version we've made, * what do we get? @@ -908,7 +908,7 @@ vips__image_intize(VipsImage *in, VipsImage **out) /* And adjust the scale to get as close to a match as we can. */ - out_scale = VIPS_RINT(out_scale + (int_result - double_result)); + out_scale = rint(out_scale + (int_result - double_result)); if (out_scale == 0) out_scale = 1; @@ -1023,7 +1023,7 @@ vips_convi_intize(VipsConvi *convi, VipsImage *M) for (i = 0; i < convi->n_point; i++) { /* 128 since this is signed. */ - convi->mant[i] = VIPS_RINT(128 * scaled[i] * pow(2, -shift)); + convi->mant[i] = rint(128 * scaled[i] * pow(2, -shift)); if (convi->mant[i] < -128 || convi->mant[i] > 127) { @@ -1106,7 +1106,7 @@ vips_convi_intize(VipsConvi *convi, VipsImage *M) int_value = VIPS_LSHIFT_INT(int_sum, convi->exp); int_value = VIPS_CLIP(0, int_value, 255); - if (VIPS_ABS(true_value - int_value) > 2) { + if (abs(true_value - int_value) > 2) { g_info("vips_convi_intize: too inaccurate"); return -1; } diff --git a/libvips/convolution/edge.c b/libvips/convolution/edge.c index 5a23502056..c72fedfeaa 100644 --- a/libvips/convolution/edge.c +++ b/libvips/convolution/edge.c @@ -98,7 +98,7 @@ vips_edge_uchar_gen(VipsRegion *out_region, int v2 = 2 * (p2[x] - 128); /* Avoid the sqrt() for uchar. */ - int v = VIPS_ABS(v1) + VIPS_ABS(v2); + int v = abs(v1) + abs(v2); q[x] = v > 255 ? 255 : v; } diff --git a/libvips/convolution/sharpen.c b/libvips/convolution/sharpen.c index ea4f4e2893..87e6f2dfdb 100644 --- a/libvips/convolution/sharpen.c +++ b/libvips/convolution/sharpen.c @@ -253,7 +253,7 @@ vips_sharpen_build(VipsObject *object) if (y > sharpen->y2) y = sharpen->y2; - sharpen->lut[i] = VIPS_RINT(y * 327.67); + sharpen->lut[i] = rint(y * 327.67); } #ifdef DEBUG diff --git a/libvips/create/buildlut.c b/libvips/create/buildlut.c index d2405d61c2..8056a2817a 100644 --- a/libvips/create/buildlut.c +++ b/libvips/create/buildlut.c @@ -129,13 +129,13 @@ vips_buildlut_build_init(VipsBuildlut *lut) /* Allow for being a bit off. */ - if (VIPS_FABS(v - VIPS_RINT(v)) > 0.001) { + if (fabs(v - rint(v)) > 0.001) { vips_error(class->nickname, _("x value row %d not an int"), y); return -1; } - v = VIPS_RINT(v); + v = rint(v); if (v < xlow) xlow = v; @@ -197,8 +197,8 @@ vips_buildlut_build_create(VipsBuildlut *lut) */ for (b = 0; b < bands; b++) { for (i = 0; i < ysize - 1; i++) { - const int x1 = VIPS_RINT(lut->data[i][0]); - const int x2 = VIPS_RINT(lut->data[i + 1][0]); + const int x1 = rint(lut->data[i][0]); + const int x2 = rint(lut->data[i + 1][0]); const int dx = x2 - x1; const double y1 = lut->data[i][b + 1]; const double y2 = lut->data[i + 1][b + 1]; diff --git a/libvips/create/gaussmat.c b/libvips/create/gaussmat.c index 75ccfeed46..0fd167c45c 100644 --- a/libvips/create/gaussmat.c +++ b/libvips/create/gaussmat.c @@ -150,7 +150,7 @@ vips_gaussmat_build(VipsObject *object) double v = exp(-distance / sig2); if (gaussmat->precision != VIPS_PRECISION_FLOAT) - v = VIPS_RINT(20 * v); + v = rint(20 * v); *VIPS_MATRIX(create->out, x, y) = v; sum += v; diff --git a/libvips/create/logmat.c b/libvips/create/logmat.c index 251da27df6..909ab9aebb 100644 --- a/libvips/create/logmat.c +++ b/libvips/create/logmat.c @@ -138,7 +138,7 @@ vips_logmat_build(VipsObject *object) * is less than the min. */ if (val - last >= 0 && - VIPS_FABS(val) < logmat->min_ampl) + fabs(val) < logmat->min_ampl) break; last = val; @@ -171,7 +171,7 @@ vips_logmat_build(VipsObject *object) exp(-distance / (2.0 * sig2)); if (logmat->precision == VIPS_PRECISION_INTEGER) - v = VIPS_RINT(20 * v); + v = rint(20 * v); *VIPS_MATRIX(create->out, x, y) = v; sum += v; diff --git a/libvips/deprecated/im_vips2mask.c b/libvips/deprecated/im_vips2mask.c index a7f4406838..85477457bb 100644 --- a/libvips/deprecated/im_vips2mask.c +++ b/libvips/deprecated/im_vips2mask.c @@ -216,15 +216,15 @@ im_vips2imask(IMAGE *in, const char *filename) * we need RRRGGGBBB. */ out->coeff[x + y * width] = - VIPS_RINT(data[x * height + y]); + rint(data[x * height + y]); else out->coeff[x + y * width] = - VIPS_RINT(data[x + y * width]); + rint(data[x + y * width]); - out->scale = VIPS_RINT(vips_image_get_scale(in)); + out->scale = rint(vips_image_get_scale(in)); if (out->scale == 0) out->scale = 1; - out->offset = VIPS_RINT(vips_image_get_offset(in)); + out->offset = rint(vips_image_get_offset(in)); /* Now convolve a 1 everywhere image with the int version we've made, * what do we get? @@ -237,7 +237,7 @@ im_vips2imask(IMAGE *in, const char *filename) /* And adjust the scale to get as close to a match as we can. */ - out->scale = VIPS_RINT(out->scale + (int_result - double_result)); + out->scale = rint(out->scale + (int_result - double_result)); if (out->scale == 0) out->scale = 1; diff --git a/libvips/foreign/cgifsave.c b/libvips/foreign/cgifsave.c index f73ea50229..fe7a96626c 100644 --- a/libvips/foreign/cgifsave.c +++ b/libvips/foreign/cgifsave.c @@ -667,7 +667,7 @@ vips_foreign_save_cgif_write_frame(VipsForeignSaveCgif *cgif) if (cgif->delay && cgif->page_number < cgif->delay_length) frame_config.delay = - VIPS_RINT(cgif->delay[cgif->page_number] / 10.0); + rint(cgif->delay[cgif->page_number] / 10.0); /* Attach a local palette, if we need one. */ diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index f5f825f18c..7f4fefea0a 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -1288,7 +1288,7 @@ region_tile_equal(VipsRegion *region, VipsRect *rect, for (x = 0; x < rect->width; x++) { for (b = 0; b < bytes; b++) - if (VIPS_ABS(p[b] - ink[b]) > threshold) + if (abs(p[b] - ink[b]) > threshold) return FALSE; p += bytes; diff --git a/libvips/foreign/exif.c b/libvips/foreign/exif.c index 13c00d6dc9..c5454ed2d0 100644 --- a/libvips/foreign/exif.c +++ b/libvips/foreign/exif.c @@ -748,7 +748,7 @@ vips_exif_set_double(ExifData *ed, else old_value = (double) rv.numerator / rv.denominator; - if (VIPS_FABS(old_value - value) > 0.0001) { + if (fabs(old_value - value) > 0.0001) { vips_exif_double_to_rational(value, &rv); VIPS_DEBUG_MSG("vips_exif_set_double: %u / %u\n", @@ -767,7 +767,7 @@ vips_exif_set_double(ExifData *ed, else old_value = (double) srv.numerator / srv.denominator; - if (VIPS_FABS(old_value - value) > 0.0001) { + if (fabs(old_value - value) > 0.0001) { vips_exif_double_to_srational(value, &srv); VIPS_DEBUG_MSG("vips_exif_set_double: %d / %d\n", diff --git a/libvips/foreign/jxlload.c b/libvips/foreign/jxlload.c index 5899042ca9..0d30099c71 100644 --- a/libvips/foreign/jxlload.c +++ b/libvips/foreign/jxlload.c @@ -764,7 +764,7 @@ vips_foreign_load_jxl_set_header(VipsForeignLoadJxl *jxl, VipsImage *out) /* gif uses centiseconds for delays */ - vips_image_set_int(out, "gif-delay", VIPS_RINT(delay[0] / 10.0)); + vips_image_set_int(out, "gif-delay", rint(delay[0] / 10.0)); vips_image_set_int(out, "loop", jxl->info.animation.num_loops); } @@ -993,7 +993,7 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) double tick = (double) jxl->info.animation.tps_denominator / jxl->info.animation.tps_numerator; // this duration in ms - int ms = VIPS_RINT(1000.0 * h.duration * tick); + int ms = rint(1000.0 * h.duration * tick); // h.duration of 0xffffffff is used for multipage JXL ... map // this to -1 in delay int duration = h.duration == 0xffffffff ? -1 : ms; diff --git a/libvips/foreign/matrixload.c b/libvips/foreign/matrixload.c index e27917176a..2a0ea56f28 100644 --- a/libvips/foreign/matrixload.c +++ b/libvips/foreign/matrixload.c @@ -140,8 +140,8 @@ parse_matrix_header(char *line, return -1; } - if (VIPS_FLOOR(header[0]) != header[0] || - VIPS_FLOOR(header[1]) != header[1]) { + if (floor(header[0]) != header[0] || + floor(header[1]) != header[1]) { vips_error("mask2vips", "%s", _("width / height not int")); return -1; } diff --git a/libvips/foreign/pdfiumload.c b/libvips/foreign/pdfiumload.c index 5379460cb8..9c0bd693d2 100644 --- a/libvips/foreign/pdfiumload.c +++ b/libvips/foreign/pdfiumload.c @@ -498,9 +498,9 @@ vips_foreign_load_pdf_header(VipsForeignLoad *load) * does round to nearest. Without this, things like * shrink-on-load will break. */ - pdf->pages[i].width = VIPS_RINT( + pdf->pages[i].width = rint( FPDF_GetPageWidth(pdf->page) * pdf->scale); - pdf->pages[i].height = VIPS_RINT( + pdf->pages[i].height = rint( FPDF_GetPageHeight(pdf->page) * pdf->scale); /* PDFium allows page width or height to be less than 1 (!!). diff --git a/libvips/foreign/popplerload.c b/libvips/foreign/popplerload.c index 79293f9a03..2e5be81c2a 100644 --- a/libvips/foreign/popplerload.c +++ b/libvips/foreign/popplerload.c @@ -357,8 +357,8 @@ vips_foreign_load_pdf_header(VipsForeignLoad *load) * does round to nearest. Without this, things like * shrink-on-load will break. */ - pdf->pages[i].width = VIPS_RINT(width * pdf->total_scale); - pdf->pages[i].height = VIPS_RINT(height * pdf->total_scale); + pdf->pages[i].width = rint(width * pdf->total_scale); + pdf->pages[i].height = rint(height * pdf->total_scale); if (pdf->pages[i].width > pdf->image.width) pdf->image.width = pdf->pages[i].width; diff --git a/libvips/foreign/ppmload.c b/libvips/foreign/ppmload.c index 139cd0dc53..988f2aa07e 100644 --- a/libvips/foreign/ppmload.c +++ b/libvips/foreign/ppmload.c @@ -412,10 +412,10 @@ vips_foreign_load_ppm_set_image_metadata(VipsForeignLoadPpm *ppm, if (ppm->index == 6 || ppm->index == 7) vips_image_set_double(image, - "pfm-scale", VIPS_FABS(ppm->scale)); + "pfm-scale", fabs(ppm->scale)); else vips_image_set_double(image, - "ppm-max-value", VIPS_ABS(ppm->max_value)); + "ppm-max-value", abs(ppm->max_value)); VIPS_SETSTR(image->filename, vips_connection_filename(VIPS_CONNECTION(ppm->sbuf->source))); diff --git a/libvips/foreign/spngsave.c b/libvips/foreign/spngsave.c index 12762117c5..de2884d4e6 100644 --- a/libvips/foreign/spngsave.c +++ b/libvips/foreign/spngsave.c @@ -452,8 +452,8 @@ vips_foreign_save_spng_write(VipsForeignSaveSpng *spng, VipsImage *in) /* Set resolution. spng uses pixels per meter. */ phys.unit_specifier = 1; - phys.ppu_x = VIPS_RINT(in->Xres * 1000.0); - phys.ppu_y = VIPS_RINT(in->Xres * 1000.0); + phys.ppu_x = rint(in->Xres * 1000.0); + phys.ppu_y = rint(in->Xres * 1000.0); spng_set_phys(spng->ctx, &phys); /* Metadata. diff --git a/libvips/foreign/vips2jpeg.c b/libvips/foreign/vips2jpeg.c index 0388d43111..9e5226b864 100644 --- a/libvips/foreign/vips2jpeg.c +++ b/libvips/foreign/vips2jpeg.c @@ -435,18 +435,18 @@ vips_jfif_resolution_from_image(struct jpeg_compress_struct *cinfo, switch (unit) { case 0: - xres = VIPS_RINT(image->Xres); - yres = VIPS_RINT(image->Yres); + xres = rint(image->Xres); + yres = rint(image->Yres); break; case 1: - xres = VIPS_RINT(image->Xres * 25.4); - yres = VIPS_RINT(image->Yres * 25.4); + xres = rint(image->Xres * 25.4); + yres = rint(image->Yres * 25.4); break; case 2: - xres = VIPS_RINT(image->Xres * 10.0); - yres = VIPS_RINT(image->Yres * 10.0); + xres = rint(image->Xres * 10.0); + yres = rint(image->Yres * 10.0); break; default: diff --git a/libvips/foreign/vips2magick.c b/libvips/foreign/vips2magick.c index ed5afbf006..7cd150899f 100644 --- a/libvips/foreign/vips2magick.c +++ b/libvips/foreign/vips2magick.c @@ -166,7 +166,7 @@ vips_foreign_save_magick_next_image(VipsForeignSaveMagick *magick) page_index = magick->position.top / magick->page_height; if (page_index < magick->delays_length) image->delay = - VIPS_RINT(magick->delays[page_index] / 10.0); + rint(magick->delays[page_index] / 10.0); } /* ImageMagick uses iterations like this (at least in gif save): diff --git a/libvips/foreign/vipspng.c b/libvips/foreign/vipspng.c index d3286ad7e5..2dc009ebce 100644 --- a/libvips/foreign/vipspng.c +++ b/libvips/foreign/vipspng.c @@ -1165,7 +1165,7 @@ write_vips(Write *write, /* Set resolution. libpng uses pixels per meter. */ png_set_pHYs(write->pPng, write->pInfo, - VIPS_RINT(in->Xres * 1000), VIPS_RINT(in->Yres * 1000), + rint(in->Xres * 1000), rint(in->Yres * 1000), PNG_RESOLUTION_METER); /* Metadata diff --git a/libvips/foreign/webp2vips.c b/libvips/foreign/webp2vips.c index 03cd483c13..649be565c8 100644 --- a/libvips/foreign/webp2vips.c +++ b/libvips/foreign/webp2vips.c @@ -486,7 +486,7 @@ read_header(Read *read, VipsImage *out) /* webp uses ms for delays, gif uses centiseconds. */ vips_image_set_int(out, "gif-delay", - VIPS_RINT(read->delays[0] / 10.0)); + rint(read->delays[0] / 10.0)); } WebPDemuxReleaseIterator(&iter); @@ -510,8 +510,8 @@ read_header(Read *read, VipsImage *out) /* We round-to-nearest cf. pdfload etc. */ - read->frame_width = VIPS_RINT(read->canvas_width * read->scale); - read->frame_height = VIPS_RINT(read->canvas_height * read->scale); + read->frame_width = rint(read->canvas_width * read->scale); + read->frame_height = rint(read->canvas_height * read->scale); #ifdef DEBUG printf("webp2vips: canvas_width = %d\n", read->canvas_width); @@ -656,10 +656,10 @@ read_next_frame(Read *read) * since we need the same rules as the overall image scale, or we'll * sometimes have missing pixels on edges. */ - area.left = VIPS_RINT(read->iter.x_offset * read->scale); - area.top = VIPS_RINT(read->iter.y_offset * read->scale); - area.width = VIPS_RINT(read->iter.width * read->scale); - area.height = VIPS_RINT(read->iter.height * read->scale); + area.left = rint(read->iter.x_offset * read->scale); + area.top = rint(read->iter.y_offset * read->scale); + area.width = rint(read->iter.width * read->scale); + area.height = rint(read->iter.height * read->scale); /* Dispose from the previous frame. */ diff --git a/libvips/histogram/hist_plot.c b/libvips/histogram/hist_plot.c index 779557d7ef..1e63c03482 100644 --- a/libvips/histogram/hist_plot.c +++ b/libvips/histogram/hist_plot.c @@ -280,7 +280,7 @@ vips_hist_plot_build(VipsObject *object) if (in->BandFmt == VIPS_FORMAT_UCHAR) tsize = 256; else - tsize = VIPS_CEIL(max); + tsize = ceil(max); /* Make sure we don't make a zero height image. */ diff --git a/libvips/include/vips/basic.h b/libvips/include/vips/basic.h index 26c4e3fef7..e229f3ddf1 100644 --- a/libvips/include/vips/basic.h +++ b/libvips/include/vips/basic.h @@ -56,6 +56,18 @@ #define VIPS_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) VIPS_API #endif +#if !defined(VIPS_DISABLE_DEPRECATION_WARNINGS) && \ + (G_GNUC_CHECK_VERSION(4, 6) || \ + __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4)) +#define _VIPS_GNUC_DO_PRAGMA(x) _Pragma(G_STRINGIFY(x)) +#define VIPS_DEPRECATED_MACRO _VIPS_GNUC_DO_PRAGMA(GCC warning "Deprecated pre-processor symbol") +#define VIPS_DEPRECATED_MACRO_FOR(f) \ + _VIPS_GNUC_DO_PRAGMA(GCC warning G_STRINGIFY(Deprecated pre-processor symbol: replace with #f)) +#else +#define VIPS_DEPRECATED_MACRO +#define VIPS_DEPRECATED_MACRO_FOR(f) +#endif + #ifdef __cplusplus extern "C" { #endif /*__cplusplus*/ diff --git a/libvips/include/vips/util.h b/libvips/include/vips/util.h index 201adf9251..a91b065c92 100644 --- a/libvips/include/vips/util.h +++ b/libvips/include/vips/util.h @@ -54,38 +54,25 @@ extern "C" { #define VIPS_MAX(A, B) ((A) > (B) ? (A) : (B)) #define VIPS_MIN(A, B) ((A) < (B) ? (A) : (B)) +#define VIPS_FMAX(A, B) fmax((A), (B)) VIPS_DEPRECATED_MACRO_FOR(fmax) +#define VIPS_FMIN(A, B) fmin((A), (B)) VIPS_DEPRECATED_MACRO_FOR(fmin) + #define VIPS_CLIP(A, V, B) VIPS_MAX((A), VIPS_MIN((B), (V))) -#define VIPS_FCLIP(A, V, B) VIPS_FMAX((A), VIPS_FMIN((B), (V))) +#define VIPS_FCLIP(A, V, B) fmax((A), fmin((B), (V))) #define VIPS_NUMBER(R) ((int) (sizeof(R) / sizeof(R[0]))) -#define VIPS_ABS(X) (((X) >= 0) ? (X) : -(X)) +#define VIPS_ABS(V) (((V) >= 0) ? (V) : -(V)) +#define VIPS_FABS(V) fabs((V)) VIPS_DEPRECATED_MACRO_FOR(fabs) // is something (eg. a pointer) N aligned #define VIPS_ALIGNED(P, N) ((((guint64) (P)) & ((N) - 1)) == 0) -/* The built-in isnan and isinf functions provided by gcc 4+ and clang are - * up to 7x faster than their libc equivalent included from . - */ -#if defined(__clang__) || (__GNUC__ >= 4) -#define VIPS_ISNAN(V) __builtin_isnan(V) -#define VIPS_FLOOR(V) __builtin_floor(V) -#define VIPS_CEIL(V) __builtin_ceil(V) -#define VIPS_RINT(V) __builtin_rint(V) -#define VIPS_ROUND(V) __builtin_round(V) -#define VIPS_FABS(V) __builtin_fabs(V) -#define VIPS_FMAX(A, B) __builtin_fmax(A, B) -#define VIPS_FMIN(A, B) __builtin_fmin(A, B) -#else -#define VIPS_ISNAN(V) isnan(V) -#define VIPS_FLOOR(V) floor(V) -#define VIPS_CEIL(V) ceil(V) -#define VIPS_RINT(V) rint(V) -#define VIPS_ROUND(V) round(V) -#define VIPS_FABS(V) VIPS_ABS(V) -#define VIPS_FMAX(A, B) VIPS_MAX(A, B) -#define VIPS_FMIN(A, B) VIPS_MIN(A, B) -#endif +#define VIPS_ISNAN(V) isnan(V) VIPS_DEPRECATED_MACRO_FOR(isnan) +#define VIPS_FLOOR(V) floor(V) VIPS_DEPRECATED_MACRO_FOR(floor) +#define VIPS_CEIL(V) ceil(V) VIPS_DEPRECATED_MACRO_FOR(ceil) +#define VIPS_RINT(V) rint(V) VIPS_DEPRECATED_MACRO_FOR(rint) +#define VIPS_ROUND(V) round(V) VIPS_DEPRECATED_MACRO_FOR(round) /* Testing status before the function call saves a lot of time. */ @@ -97,7 +84,7 @@ extern "C" { } \ G_STMT_END -/* VIPS_RINT() does "bankers rounding", it rounds to the nearest even integer. +/* rint() does "bankers rounding", it rounds to the nearest even integer. * For things like image geometry, we want strict nearest int. * * If you know it's unsigned, _UINT is a little faster. diff --git a/libvips/mosaicing/im_avgdxdy.c b/libvips/mosaicing/im_avgdxdy.c index 015e1ffd68..e0214c9e4f 100644 --- a/libvips/mosaicing/im_avgdxdy.c +++ b/libvips/mosaicing/im_avgdxdy.c @@ -75,8 +75,8 @@ vips__avgdxdy(TiePoints *points, int *dx, int *dy) sumdy += points->y_secondary[i] - points->y_reference[i]; } - *dx = VIPS_RINT((double) sumdx / (double) points->nopoints); - *dy = VIPS_RINT((double) sumdy / (double) points->nopoints); + *dx = rint((double) sumdx / (double) points->nopoints); + *dy = rint((double) sumdy / (double) points->nopoints); return 0; } diff --git a/libvips/resample/affine.c b/libvips/resample/affine.c index c950db41b3..5e757161d9 100644 --- a/libvips/resample/affine.c +++ b/libvips/resample/affine.c @@ -366,8 +366,8 @@ vips_affine_gen(VipsRegion *out_region, for (x = le; x < ri; x++) { int fx, fy; - fx = VIPS_FLOOR(ix); - fy = VIPS_FLOOR(iy); + fx = floor(ix); + fy = floor(iy); /* Clip against iarea. */ diff --git a/libvips/resample/mapim.c b/libvips/resample/mapim.c index 8f7ebb8ee0..4a5786733e 100644 --- a/libvips/resample/mapim.c +++ b/libvips/resample/mapim.c @@ -285,8 +285,8 @@ vips_mapim_region_minmax(VipsRegion *region, VipsRect *r, VipsRect *bounds) TYPE px = p1[0]; \ TYPE py = p1[1]; \ \ - if (VIPS_ISNAN(px) || \ - VIPS_ISNAN(py) || \ + if (isnan(px) || \ + isnan(py) || \ px < -1 || \ px >= clip_width || \ py < -1 || \ diff --git a/libvips/resample/reduceh.cpp b/libvips/resample/reduceh.cpp index f1f3787b00..d82521d6a8 100644 --- a/libvips/resample/reduceh.cpp +++ b/libvips/resample/reduceh.cpp @@ -441,7 +441,7 @@ vips_reduceh_build(VipsObject *object) /* The int part of our reduce. */ int_hshrink = VIPS_MAX(1, - VIPS_FLOOR((double) in->Xsize / width / reduceh->gap)); + floor((double) in->Xsize / width / reduceh->gap)); if (int_hshrink > 1) { g_info("shrinkh by %d", int_hshrink); @@ -510,7 +510,7 @@ vips_reduceh_build(VipsObject *object) /* Add new pixels around the input so we can interpolate at the edges. */ if (vips_embed(in, &t[2], - VIPS_CEIL(reduceh->n_point / 2.0) - 1, 0, + ceil(reduceh->n_point / 2.0) - 1, 0, in->Xsize + reduceh->n_point, in->Ysize, "extend", VIPS_EXTEND_COPY, nullptr)) diff --git a/libvips/resample/reducev.cpp b/libvips/resample/reducev.cpp index fd98398393..4d68dd51bc 100644 --- a/libvips/resample/reducev.cpp +++ b/libvips/resample/reducev.cpp @@ -762,7 +762,7 @@ vips_reducev_vector_to_fixed_point(double *in, int *out, int n, int scale) fsum = 0.0; for (i = 0; i < n; i++) fsum += in[i]; - target = VIPS_RINT(fsum * scale); + target = rint(fsum * scale); /* As we rint() each scale element, we can get up to 0.5 error. * Therefore, by the end of the mask, we can be off by up to n/2. Our @@ -776,7 +776,7 @@ vips_reducev_vector_to_fixed_point(double *in, int *out, int n, int scale) guess = (high + low) / 2.0; for (i = 0; i < n; i++) - out[i] = VIPS_RINT(in[i] * guess); + out[i] = rint(in[i] * guess); sum = 0; for (i = 0; i < n; i++) @@ -812,7 +812,7 @@ vips_reducev_vector_to_fixed_point(double *in, int *out, int n, int scale) * first abs(extra_error) elements. */ int direction = extra_error > 0 ? 1 : -1; - int n_elements = VIPS_ABS(extra_error); + int n_elements = abs(extra_error); for (i = 0; i < n; i++) out[i] += each_error; @@ -874,7 +874,7 @@ vips_reducev_build(VipsObject *object) /* The int part of our reduce. */ int_vshrink = VIPS_MAX(1, - VIPS_FLOOR((double) in->Ysize / height / reducev->gap)); + floor((double) in->Ysize / height / reducev->gap)); if (int_vshrink > 1) { g_info("shrinkv by %d", int_vshrink); @@ -941,7 +941,7 @@ vips_reducev_build(VipsObject *object) /* Add new pixels around the input so we can interpolate at the edges. */ if (vips_embed(in, &t[2], - 0, VIPS_CEIL(reducev->n_point / 2.0) - 1, + 0, ceil(reducev->n_point / 2.0) - 1, in->Xsize, in->Ysize + reducev->n_point, "extend", VIPS_EXTEND_COPY, nullptr)) diff --git a/libvips/resample/resize.c b/libvips/resample/resize.c index 40cfc65633..0b488e6b92 100644 --- a/libvips/resample/resize.c +++ b/libvips/resample/resize.c @@ -171,17 +171,17 @@ vips_resize_build(VipsObject *object) /* The int part of our scale. */ if (resize->gap < 1.0) { - int_hshrink = VIPS_FLOOR(1.0 / hscale); - int_vshrink = VIPS_FLOOR(1.0 / vscale); + int_hshrink = floor(1.0 / hscale); + int_vshrink = floor(1.0 / vscale); } else { target_width = VIPS_ROUND_UINT(in->Xsize * hscale); target_height = VIPS_ROUND_UINT(in->Ysize * vscale); - int_hshrink = VIPS_FLOOR( + int_hshrink = floor( (double) in->Xsize / target_width / resize->gap); - int_vshrink = VIPS_FLOOR( + int_vshrink = floor( (double) in->Ysize / target_height / resize->gap); } @@ -252,12 +252,12 @@ vips_resize_build(VipsObject *object) vips_object_local(object, interpolate); if (resize->kernel == VIPS_KERNEL_NEAREST && - hscale == VIPS_FLOOR(hscale) && - vscale == VIPS_FLOOR(vscale)) { + hscale == floor(hscale) && + vscale == floor(vscale)) { /* Fast, integral nearest neighbour enlargement */ - if (vips_zoom(in, &t[4], VIPS_FLOOR(hscale), - VIPS_FLOOR(vscale), NULL)) + if (vips_zoom(in, &t[4], floor(hscale), + floor(vscale), NULL)) return -1; in = t[4]; } diff --git a/libvips/resample/shrinkh.c b/libvips/resample/shrinkh.c index 4ff9706b44..ebcdea7aa2 100644 --- a/libvips/resample/shrinkh.c +++ b/libvips/resample/shrinkh.c @@ -392,7 +392,7 @@ vips_shrinkh_build(VipsObject *object) * fractional part), we just see the integer part here. */ resample->out->Xsize = shrink->ceil - ? VIPS_CEIL((double) resample->in->Xsize / shrink->hshrink) + ? ceil((double) resample->in->Xsize / shrink->hshrink) : VIPS_ROUND_UINT((double) resample->in->Xsize / shrink->hshrink); if (resample->out->Xsize <= 0) { vips_error(class->nickname, diff --git a/libvips/resample/shrinkv.c b/libvips/resample/shrinkv.c index 148d1555b9..cb24936233 100644 --- a/libvips/resample/shrinkv.c +++ b/libvips/resample/shrinkv.c @@ -443,7 +443,7 @@ vips_shrinkv_build(VipsObject *object) * fractional part), we just see the integer part here. */ t[2]->Ysize = shrink->ceil - ? VIPS_CEIL((double) resample->in->Ysize / shrink->vshrink) + ? ceil((double) resample->in->Ysize / shrink->vshrink) : VIPS_ROUND_UINT((double) resample->in->Ysize / shrink->vshrink); if (t[2]->Ysize <= 0) { vips_error(class->nickname, diff --git a/libvips/resample/templates.h b/libvips/resample/templates.h index b8c4f9c4f5..ae347dbb52 100644 --- a/libvips/resample/templates.h +++ b/libvips/resample/templates.h @@ -323,7 +323,7 @@ static void inline calculate_coefficients_catmull(double c[4], const double x) */ static double inline cubic_filter(double x, double B, double C) { - const double ax = VIPS_FABS(x); + const double ax = fabs(x); const double ax2 = ax * ax; const double ax3 = ax2 * ax; @@ -361,7 +361,7 @@ static double inline filter(double x); template <> double inline filter(double x) { - x = VIPS_FABS(x); + x = fabs(x); if (x < 1.0) return 1.0 - x; @@ -404,7 +404,7 @@ double inline filter(double x) template <> double inline filter(double x) { - x = VIPS_FABS(x); + x = fabs(x); if (x >= 2.5) return 0.0; @@ -421,7 +421,7 @@ double inline filter(double x) template <> double inline filter(double x) { - x = VIPS_FABS(x); + x = fabs(x); if (x >= 4.5) return 0.0; diff --git a/libvips/resample/thumbnail.c b/libvips/resample/thumbnail.c index dd6de13a76..f8830434ff 100644 --- a/libvips/resample/thumbnail.c +++ b/libvips/resample/thumbnail.c @@ -783,7 +783,7 @@ vips_thumbnail_build(VipsObject *object) * page_height or we'll have pixels straddling page boundaries. */ if (in->Ysize > preshrunk_page_height) { - int target_page_height = VIPS_RINT(preshrunk_page_height / vshrink); + int target_page_height = rint(preshrunk_page_height / vshrink); int target_image_height = target_page_height * thumbnail->n_loaded_pages; @@ -827,7 +827,7 @@ vips_thumbnail_build(VipsObject *object) * accidentally turn into an animated image later. */ if (thumbnail->n_loaded_pages > 1) { - int output_page_height = VIPS_RINT(preshrunk_page_height / vshrink); + int output_page_height = rint(preshrunk_page_height / vshrink); if (vips_copy(in, &t[8], NULL)) return -1; From 8effeb9120ac7e9214973c60d44b98d775749b39 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Tue, 11 Mar 2025 20:52:59 +0000 Subject: [PATCH 076/174] heifsave: improve alpha channel detection (#4394) --- ChangeLog | 1 + libvips/foreign/heifsave.c | 19 +++++-------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index d46e377e0c..8d81352d1f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,7 @@ - improve performance of vips_shrink() [kleisauke] - svgload: add support for custom CSS via stylesheet option [lovell] - heifload: `unlimited` flag removes all limits (requires libheif 1.19.0+) [lovell] +- heifsave: improve alpha channel detection [lovell] 8.16.1 diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index 7479943efc..27cd7fb9a6 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -289,8 +289,7 @@ vips_foreign_save_heif_write_page(VipsForeignSaveHeif *heif, int page) #endif /*HAVE_HEIF_COLOR_PROFILE*/ options = heif_encoding_options_alloc(); - if (vips_image_hasalpha(save->ready)) - options->save_alpha_channel = 1; + options->save_alpha_channel = save->ready->Bands > 3; #ifdef HAVE_HEIF_ENCODING_OPTIONS_OUTPUT_NCLX_PROFILE /* Matrix coefficients have to be identity (CICP x/y/0) in lossless @@ -517,6 +516,7 @@ vips_foreign_save_heif_build(VipsObject *object) char *chroma; const struct heif_encoder_descriptor *out_encoder; const struct heif_encoder_parameter *const *param; + gboolean has_alpha; if (VIPS_OBJECT_CLASS(vips_foreign_save_heif_parent_class)-> build(object)) return -1; @@ -677,21 +677,13 @@ vips_foreign_save_heif_build(VipsObject *object) heif->page_width = save->ready->Xsize; heif->page_height = vips_image_get_page_height(save->ready); heif->n_pages = save->ready->Ysize / heif->page_height; + has_alpha = save->ready->Bands > 3; if (heif->page_width > 16384 || heif->page_height > 16384) { vips_error("heifsave", _("image too large")); return -1; } - /* Reject multiband images. - */ - if (save->ready->Type == VIPS_INTERPRETATION_MULTIBAND) { - vips_error("heifsave", _("Unsupported interpretation: %s"), - vips_enum_nick(VIPS_TYPE_INTERPRETATION, - save->ready->Type)); - return -1; - } - /* Make a heif image the size of a page. We send sink_disc() output * here and write a frame each time it fills. */ @@ -699,12 +691,11 @@ vips_foreign_save_heif_build(VipsObject *object) printf("vips_foreign_save_heif_build:\n"); printf("\twidth = %d\n", heif->page_width); printf("\theight = %d\n", heif->page_height); - printf("\talpha = %d\n", vips_image_hasalpha(save->ready)); + printf("\talpha = %d\n", has_alpha); #endif /*DEBUG*/ error = heif_image_create(heif->page_width, heif->page_height, heif_colorspace_RGB, - vips__heif_chroma(heif->bitdepth, - vips_image_hasalpha(save->ready)), + vips__heif_chroma(heif->bitdepth, has_alpha), &heif->img); if (error.code) { vips__heif_error(&error); From 55e06ac7fe869902cdff0158d0f82acdb154dbdb Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 11 Mar 2025 22:45:53 +0100 Subject: [PATCH 077/174] clang-tidy: avoid narrowing conversions (#4415) Found with clang-tidy 19.1.7. --- libvips/colour/HSV2sRGB.c | 2 +- libvips/colour/LCh2Lab.c | 4 +-- libvips/colour/LCh2UCS.c | 48 ++++++++++++++-------------- libvips/colour/Lab2LCh.c | 4 +-- libvips/colour/Lab2LabQ.c | 8 ++--- libvips/colour/LabQ2Lab.c | 6 ++-- libvips/colour/LabQ2sRGB.c | 58 +++++++++++++++++----------------- libvips/colour/UCS2LCh.c | 4 +-- libvips/colour/XYZ2Lab.c | 10 +++--- libvips/colour/Yxy2XYZ.c | 6 ++-- libvips/colour/dE76.c | 4 +-- libvips/colour/icc_transform.c | 36 ++++++++++----------- libvips/colour/sRGB2HSV.c | 8 ++--- libvips/colour/scRGB2XYZ.c | 20 ++++++------ libvips/create/eye.c | 6 ++-- libvips/create/grey.c | 4 +-- libvips/create/mask.c | 4 +-- libvips/create/perlin.c | 6 ++-- libvips/create/point.c | 4 +-- libvips/create/sdf.c | 18 +++++------ libvips/create/sines.c | 2 +- libvips/create/worley.c | 4 +-- libvips/create/zone.c | 4 +-- libvips/foreign/ppmload.c | 2 +- libvips/foreign/radiance.c | 4 +-- libvips/foreign/tiff2vips.c | 18 +++++------ libvips/morphology/nearest.c | 2 +- 27 files changed, 148 insertions(+), 148 deletions(-) diff --git a/libvips/colour/HSV2sRGB.c b/libvips/colour/HSV2sRGB.c index 51bceb1e23..d7ac299ec8 100644 --- a/libvips/colour/HSV2sRGB.c +++ b/libvips/colour/HSV2sRGB.c @@ -63,7 +63,7 @@ vips_HSV2sRGB_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) float c, x, m; c = p[2] * p[1] / 255.0; - x = c * (1 - fabs(fmod(p[0] / SIXTH_OF_CHAR, 2) - 1)); + x = c * (1 - fabsf(fmodf(p[0] / SIXTH_OF_CHAR, 2) - 1)); m = p[2] - c; if (p[0] < (int) SIXTH_OF_CHAR) { diff --git a/libvips/colour/LCh2Lab.c b/libvips/colour/LCh2Lab.c index 091f4a4e23..c37dd9246a 100644 --- a/libvips/colour/LCh2Lab.c +++ b/libvips/colour/LCh2Lab.c @@ -69,8 +69,8 @@ G_DEFINE_TYPE(VipsLCh2Lab, vips_LCh2Lab, VIPS_TYPE_COLOUR_TRANSFORM); void vips_col_Ch2ab(float C, float h, float *a, float *b) { - *a = C * cos(VIPS_RAD(h)); - *b = C * sin(VIPS_RAD(h)); + *a = C * cosf(VIPS_RAD(h)); + *b = C * sinf(VIPS_RAD(h)); } /* Process a buffer of data. diff --git a/libvips/colour/LCh2UCS.c b/libvips/colour/LCh2UCS.c index 1d3fa92873..7b4685bdf4 100644 --- a/libvips/colour/LCh2UCS.c +++ b/libvips/colour/LCh2UCS.c @@ -92,9 +92,9 @@ vips_col_L2Lcmc(float L) float Lcmc; if (L < 16.0) - Lcmc = 1.744 * L; + Lcmc = 1.744F * L; else - Lcmc = 21.75 * log(L) + 0.3838 * L - 38.54; + Lcmc = 21.75F * logf(L) + 0.3838F * L - 38.54F; return Lcmc; } @@ -112,7 +112,7 @@ vips_col_C2Ccmc(float C) { float Ccmc; - Ccmc = 0.162 * C + 10.92 * log(0.638 + 0.07216 * C) + 4.907; + Ccmc = 0.162F * C + 10.92F * logf(0.638F + 0.07216F * C) + 4.907F; if (Ccmc < 0) Ccmc = 0; @@ -136,35 +136,35 @@ vips_col_Ch2hcmc(float C, float h) float hcmc; if (h < 49.1) { - k4 = 133.87; - k5 = -134.5; - k6 = -.924; - k7 = 1.727; - k8 = 340.0; + k4 = 133.87F; + k5 = -134.5F; + k6 = -.924F; + k7 = 1.727F; + k8 = 340.0F; } else if (h < 110.1) { - k4 = 11.78; - k5 = -12.7; - k6 = -.218; - k7 = 2.12; - k8 = 333.0; + k4 = 11.78F; + k5 = -12.7F; + k6 = -.218F; + k7 = 2.12F; + k8 = 333.0F; } else if (h < 269.6) { - k4 = 13.87; - k5 = 10.93; - k6 = 0.14; - k7 = 1.0; - k8 = -83.0; + k4 = 13.87F; + k5 = 10.93F; + k6 = 0.14F; + k7 = 1.0F; + k8 = -83.0F; } else { - k4 = .14; - k5 = 5.23; - k6 = .17; - k7 = 1.61; - k8 = 233.0; + k4 = .14F; + k5 = 5.23F; + k6 = .17F; + k7 = 1.61F; + k8 = 233.0F; } - P = cos(VIPS_RAD(k7 * h + k8)); + P = cosf(VIPS_RAD(k7 * h + k8)); D = k4 + k5 * P * powf(fabsf(P), k6); g = C * C * C * C; f = sqrtf(g / (g + 1900.0F)); diff --git a/libvips/colour/Lab2LCh.c b/libvips/colour/Lab2LCh.c index f1df78b096..2f34238089 100644 --- a/libvips/colour/Lab2LCh.c +++ b/libvips/colour/Lab2LCh.c @@ -92,7 +92,7 @@ void vips_col_ab2Ch(float a, float b, float *C, float *h) { *h = vips_col_ab2h(a, b); - *C = hypot(a, b); + *C = hypotf(a, b); } static void @@ -111,7 +111,7 @@ vips_Lab2LCh_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) p += 3; - C = sqrt(a * a + b * b); + C = sqrtf(a * a + b * b); h = vips_col_ab2h(a, b); q[0] = L; diff --git a/libvips/colour/Lab2LabQ.c b/libvips/colour/Lab2LabQ.c index c5bf5aef11..7418c434f6 100644 --- a/libvips/colour/Lab2LabQ.c +++ b/libvips/colour/Lab2LabQ.c @@ -102,14 +102,14 @@ vips_Lab2LabQ_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) lsbs = (intv & 0x3) << 6; /* 00000011 -> 11000000 */ q[0] = intv >> 2; /* drop bot 2 bits and store */ - fval = 8.0 * p[1]; /* do a */ - intv = rint(fval); + fval = 8.0F * p[1]; /* do a */ + intv = rintf(fval); intv = VIPS_CLIP(-1024, intv, 1023); lsbs |= (intv & 0x7) << 3; /* 00000111 -> 00111000 */ q[1] = intv >> 3; /* drop bot 3 bits & store */ - fval = 8.0 * p[2]; /* do b */ - intv = rint(fval); + fval = 8.0F * p[2]; /* do b */ + intv = rintf(fval); intv = VIPS_CLIP(-1024, intv, 1023); lsbs |= (intv & 0x7); q[2] = intv >> 3; diff --git a/libvips/colour/LabQ2Lab.c b/libvips/colour/LabQ2Lab.c index 174cde10fc..78cc2e83ea 100644 --- a/libvips/colour/LabQ2Lab.c +++ b/libvips/colour/LabQ2Lab.c @@ -92,17 +92,17 @@ vips_LabQ2Lab_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) */ l = ((unsigned char *) p)[0]; l = (l << 2) | (lsbs >> 6); - q[0] = (float) l * (100.0 / 1023.0); + q[0] = (float) l * (100.0F / 1023.0F); /* Build a. */ l = VIPS_LSHIFT_INT(p[1], 3) | ((lsbs >> 3) & 0x7); - q[1] = (float) l * 0.125; + q[1] = (float) l * 0.125F; /* And b. */ l = VIPS_LSHIFT_INT(p[2], 3) | (lsbs & 0x7); - q[2] = (float) l * 0.125; + q[2] = (float) l * 0.125F; p += 4; q += 3; diff --git a/libvips/colour/LabQ2sRGB.c b/libvips/colour/LabQ2sRGB.c index f4b6d5cf13..a2b153fd2b 100644 --- a/libvips/colour/LabQ2sRGB.c +++ b/libvips/colour/LabQ2sRGB.c @@ -136,11 +136,11 @@ calcul_tables(int range, int *Y2v, float *v2Y) float v; if (f <= 0.0031308) - v = 12.92 * f; + v = 12.92F * f; else - v = (1.0 + 0.055) * pow(f, 1.0 / 2.4) - 0.055; + v = (1.0F + 0.055F) * powf(f, 1.0F / 2.4F) - 0.055F; - Y2v[i] = rint((range - 1) * v); + Y2v[i] = rintf((range - 1) * v); } /* Copy the final element. This is used in the piecewise linear @@ -152,9 +152,9 @@ calcul_tables(int range, int *Y2v, float *v2Y) float f = (float) i / (range - 1); if (f <= 0.04045) - v2Y[i] = f / 12.92; + v2Y[i] = f / 12.92F; else - v2Y[i] = pow((f + 0.055) / (1 + 0.055), 2.4); + v2Y[i] = powf((f + 0.055F) / (1 + 0.055F), 2.4F); } } @@ -231,15 +231,15 @@ vips_col_scRGB2XYZ(float R, float G, float B, float *X, float *Y, float *Z) G *= SCALE; B *= SCALE; - *X = 0.4124 * R + - 0.3576 * G + - 0.1805 * B; - *Y = 0.2126 * R + - 0.7152 * G + - 0.0722 * B; - *Z = 0.0193 * R + - 0.1192 * G + - 0.9505 * B; + *X = 0.4124F * R + + 0.3576F * G + + 0.1805F * B; + *Y = 0.2126F * R + + 0.7152F * G + + 0.0722F * B; + *Z = 0.0193F * R + + 0.1192F * G + + 0.9505F * B; return 0; } @@ -266,15 +266,15 @@ vips_col_XYZ2scRGB(float X, float Y, float Z, float *R, float *G, float *B) /* Use 6 decimal places of precision for the inverse matrix. */ - *R = 3.240625 * X + - -1.537208 * Y + - -0.498629 * Z; - *G = -0.968931 * X + - 1.875756 * Y + - 0.041518 * Z; - *B = 0.055710 * X + - -0.204021 * Y + - 1.056996 * Z; + *R = 3.240625F * X + + -1.537208F * Y + + -0.498629F * Z; + *G = -0.968931F * X + + 1.875756F * Y + + 0.041518F * Z; + *B = 0.055710F * X + + -0.204021F * Y + + 1.056996F * Z; return 0; } @@ -337,19 +337,19 @@ vips_col_scRGB2sRGB(int range, int *lut, CLIP(0, Yf, maxval); Yi = (int) Yf; v = lut[Yi] + (lut[Yi + 1] - lut[Yi]) * (Yf - Yi); - *r = rint(v); + *r = rintf(v); Yf = G * maxval; CLIP(0, Yf, maxval); Yi = (int) Yf; v = lut[Yi] + (lut[Yi + 1] - lut[Yi]) * (Yf - Yi); - *g = rint(v); + *g = rintf(v); Yf = B * maxval; CLIP(0, Yf, maxval); Yi = (int) Yf; v = lut[Yi] + (lut[Yi + 1] - lut[Yi]) * (Yf - Yi); - *b = rint(v); + *b = rintf(v); if (og_ret) *og_ret = og; @@ -394,7 +394,7 @@ vips_col_scRGB2BW(int range, int *lut, float R, float G, float B, /* CIE linear luminance function, see https://en.wikipedia.org/wiki/Grayscale#Colorimetric_(perceptual_luminance-preserving)_conversion_to_grayscale */ - Y = 0.2126 * R + 0.7152 * G + 0.0722 * B; + Y = 0.2126F * R + 0.7152F * G + 0.0722F * B; /* Y can be Nan. Throw those values out, they will break * our clipping. @@ -417,7 +417,7 @@ vips_col_scRGB2BW(int range, int *lut, float R, float G, float B, CLIP(0, Yf, maxval); Yi = (int) Yf; v = lut[Yi] + (lut[Yi + 1] - lut[Yi]) * (Yf - Yi); - *g = rint(v); + *g = rintf(v); if (og_ret) *og_ret = og; @@ -454,7 +454,7 @@ build_tables(void *client) for (b = 0; b < 64; b++) { /* Scale to lab space. */ - float L = (l << 2) * (100.0 / 256.0); + float L = (l << 2) * (100.0F / 256.0F); float A = (signed char) (a << 2); float B = (signed char) (b << 2); float X, Y, Z; diff --git a/libvips/colour/UCS2LCh.c b/libvips/colour/UCS2LCh.c index 1baf4d297e..3a12fab1c8 100644 --- a/libvips/colour/UCS2LCh.c +++ b/libvips/colour/UCS2LCh.c @@ -155,7 +155,7 @@ vips_col_Lcmc2L(float Lcmc) known = VIPS_CLIP(0, known, 999); return LI[known] + - (LI[known + 1] - LI[known]) * (Lcmc * 10.0 - known); + (LI[known + 1] - LI[known]) * (Lcmc * 10.0F - known); } /** @@ -177,7 +177,7 @@ vips_col_Ccmc2C(float Ccmc) known = VIPS_CLIP(0, known, 2999); return CI[known] + - (CI[known + 1] - CI[known]) * (Ccmc * 10.0 - known); + (CI[known + 1] - CI[known]) * (Ccmc * 10.0F - known); } /** diff --git a/libvips/colour/XYZ2Lab.c b/libvips/colour/XYZ2Lab.c index 11be78dfb0..8facaccdea 100644 --- a/libvips/colour/XYZ2Lab.c +++ b/libvips/colour/XYZ2Lab.c @@ -97,9 +97,9 @@ table_init(void *client) float Y = (double) i / QUANT_ELEMENTS; if (Y < 0.008856) - cbrt_table[i] = 7.787 * Y + (16.0 / 116.0); + cbrt_table[i] = 7.787F * Y + (16.0F / 116.0F); else - cbrt_table[i] = cbrt(Y); + cbrt_table[i] = cbrtf(Y); } return NULL; @@ -132,9 +132,9 @@ vips_col_XYZ2Lab_helper(VipsXYZ2Lab *XYZ2Lab, f = nZ - i; cbz = cbrt_table[i] + f * (cbrt_table[i + 1] - cbrt_table[i]); - *L = 116.0 * cby - 16.0; - *a = 500.0 * (cbx - cby); - *b = 200.0 * (cby - cbz); + *L = 116.0F * cby - 16.0F; + *a = 500.0F * (cbx - cby); + *b = 200.0F * (cby - cbz); } /* Process a buffer of data. diff --git a/libvips/colour/Yxy2XYZ.c b/libvips/colour/Yxy2XYZ.c index b2664f6be1..2584a8a00c 100644 --- a/libvips/colour/Yxy2XYZ.c +++ b/libvips/colour/Yxy2XYZ.c @@ -73,11 +73,11 @@ vips_Yxy2XYZ_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) if (x == 0.0 || y == 0.0) { - X = 0.0; - Z = 0.0; + X = 0.0F; + Z = 0.0F; } else { - double total; + float total; total = Y / y; X = x * total; diff --git a/libvips/colour/dE76.c b/libvips/colour/dE76.c index f684579cce..2027e4ce8a 100644 --- a/libvips/colour/dE76.c +++ b/libvips/colour/dE76.c @@ -76,7 +76,7 @@ vips_pythagoras(float L1, float a1, float b1, float L2, float a2, float b2) float da = a1 - a2; float db = b1 - b2; - return sqrt(dL * dL + da * da + db * db); + return sqrtf(dL * dL + da * da + db * db); } /* Find the difference between two buffers of LAB data. @@ -96,7 +96,7 @@ vips__pythagoras_line(VipsColour *colour, float da = p1[1] - p2[1]; float db = p1[2] - p2[2]; - q[x] = sqrt(dL * dL + da * da + db * db); + q[x] = sqrtf(dL * dL + da * da + db * db); p1 += 3; p2 += 3; diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 7723938700..420b77a5f3 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -903,15 +903,15 @@ decode_xyz(guint16 *fixed, float *xyz, int n) * Bradford transformation. * See: https://fujiwaratko.sakura.ne.jp/infosci/colorspace/bradford_e.html */ - xyz[0] = 0.955513 * X + - -0.023073 * Y + - 0.063309 * Z; - xyz[1] = -0.028325 * X + - 1.009942 * Y + - 0.021055 * Z; - xyz[2] = 0.012329 * X + - -0.020536 * Y + - 1.330714 * Z; + xyz[0] = 0.955513F * X + + -0.023073F * Y + + 0.063309F * Z; + xyz[1] = -0.028325F * X + + 1.009942F * Y + + 0.021055F * Z; + xyz[2] = 0.012329F * X + + -0.020536F * Y + + 1.330714F * Z; xyz += 3; fixed += 3; @@ -1067,15 +1067,15 @@ encode_xyz(float *in, float *out, int n) * Bradford transformation. * See: https://fujiwaratko.sakura.ne.jp/infosci/colorspace/bradford_e.html */ - out[0] = 1.047886 * X + - 0.022919 * Y + - -0.050216 * Z; - out[1] = 0.029582 * X + - 0.990484 * Y + - -0.017079 * Z; - out[2] = -0.009252 * X + - 0.015073 * Y + - 0.751678 * Z; + out[0] = 1.047886F * X + + 0.022919F * Y + + -0.050216F * Z; + out[1] = 0.029582F * X + + 0.990484F * Y + + -0.017079F * Z; + out[2] = -0.009252F * X + + 0.015073F * Y + + 0.751678F * Z; in += 3; out += 3; diff --git a/libvips/colour/sRGB2HSV.c b/libvips/colour/sRGB2HSV.c index b3f8d02f43..e3e839333f 100644 --- a/libvips/colour/sRGB2HSV.c +++ b/libvips/colour/sRGB2HSV.c @@ -68,7 +68,7 @@ vips_sRGB2HSV_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) c_max = p[0]; c_min = p[1]; secondary_diff = p[1] - p[2]; - wrap_around_hue = 255.0; + wrap_around_hue = 255.0F; } else { /* Center blue. @@ -76,7 +76,7 @@ vips_sRGB2HSV_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) c_max = p[2]; c_min = VIPS_MIN(p[1], p[0]); secondary_diff = p[0] - p[1]; - wrap_around_hue = 170.0; + wrap_around_hue = 170.0F; } } else { @@ -86,7 +86,7 @@ vips_sRGB2HSV_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) c_max = p[0]; c_min = p[2]; secondary_diff = p[1] - p[2]; - wrap_around_hue = 0.0; + wrap_around_hue = 0.0F; } else { /* Center green @@ -94,7 +94,7 @@ vips_sRGB2HSV_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) c_max = p[1]; c_min = VIPS_MIN(p[2], p[0]); secondary_diff = p[2] - p[0]; - wrap_around_hue = 85.0; + wrap_around_hue = 85.0F; } } diff --git a/libvips/colour/scRGB2XYZ.c b/libvips/colour/scRGB2XYZ.c index fe5b6a187d..a7bee766fa 100644 --- a/libvips/colour/scRGB2XYZ.c +++ b/libvips/colour/scRGB2XYZ.c @@ -79,21 +79,21 @@ vips_scRGB2XYZ_line(float *restrict q, float *restrict p, * as the original is defined in a separate file and is part of * the public API so a compiler will not inline. */ - q[0] = 0.4124 * R + - 0.3576 * G + - 0.1805 * B; - q[1] = 0.2126 * R + - 0.7152 * G + - 0.0722 * B; - q[2] = 0.0193 * R + - 0.1192 * G + - 0.9505 * B; + q[0] = 0.4124F * R + + 0.3576F * G + + 0.1805F * B; + q[1] = 0.2126F * R + + 0.7152F * G + + 0.0722F * B; + q[2] = 0.0193F * R + + 0.1192F * G + + 0.9505F * B; p += 3; q += 3; for (j = 0; j < extra_bands; j++) - q[j] = VIPS_CLIP(0, p[j] * 255.0, 255.0); + q[j] = VIPS_FCLIP(0, p[j] * 255.0, 255.0); p += extra_bands; q += extra_bands; } diff --git a/libvips/create/eye.c b/libvips/create/eye.c index bc67767cad..091c75a070 100644 --- a/libvips/create/eye.c +++ b/libvips/create/eye.c @@ -82,10 +82,10 @@ vips_eye_point(VipsPoint *point, int x, int y) int max_x = VIPS_MAX(point->width - 1, 1); int max_y = VIPS_MAX(point->height - 1, 1); - double c = eye->factor * VIPS_PI / (2 * max_x); - double h = max_y * max_y; + float c = eye->factor * VIPS_PI / (2 * max_x); + float h = max_y * max_y; - return y * y * cos(c * x * x) / h; + return y * y * cosf(c * x * x) / h; } static void diff --git a/libvips/create/grey.c b/libvips/create/grey.c index 4b9b6b1772..6ee420fa89 100644 --- a/libvips/create/grey.c +++ b/libvips/create/grey.c @@ -89,8 +89,8 @@ vips_grey_class_init(VipsGreyClass *class) vobject_class->description = _("make a grey ramp image"); point_class->point = vips_grey_point; - point_class->min = 0.0; - point_class->max = 1.0; + point_class->min = 0.0F; + point_class->max = 1.0F; } static void diff --git a/libvips/create/mask.c b/libvips/create/mask.c index de05b03780..6a75de6f31 100644 --- a/libvips/create/mask.c +++ b/libvips/create/mask.c @@ -114,8 +114,8 @@ vips_mask_class_init(VipsMaskClass *class) vobject_class->description = _("base class for frequency filters"); point_class->point = vips_mask_point; - point_class->min = 0.0; - point_class->max = 1.0; + point_class->min = 0.0F; + point_class->max = 1.0F; point_class->interpretation = VIPS_INTERPRETATION_FOURIER; VIPS_ARG_BOOL(class, "optical", 5, diff --git a/libvips/create/perlin.c b/libvips/create/perlin.c index 0314261928..eb7301bd8a 100644 --- a/libvips/create/perlin.c +++ b/libvips/create/perlin.c @@ -264,10 +264,10 @@ vips_perlin_make_tables(void *client) int i; for (i = 0; i < 256; i++) { - double angle = 2 * VIPS_PI * i / 256.0; + float angle = 2.0F * VIPS_PI * i / 256.0F; - vips_perlin_cos[i] = cos(angle); - vips_perlin_sin[i] = sin(angle); + vips_perlin_cos[i] = cosf(angle); + vips_perlin_sin[i] = sinf(angle); } return NULL; diff --git a/libvips/create/point.c b/libvips/create/point.c index 7ade0d1af9..b052e1b0f0 100644 --- a/libvips/create/point.c +++ b/libvips/create/point.c @@ -133,8 +133,8 @@ vips_point_class_init(VipsPointClass *class) vobject_class->build = vips_point_build; class->point = NULL; - class->min = -1.0; - class->max = 1.0; + class->min = -1.0F; + class->max = 1.0F; class->interpretation = VIPS_INTERPRETATION_MULTIBAND; VIPS_ARG_INT(class, "width", 2, diff --git a/libvips/create/sdf.c b/libvips/create/sdf.c index e659ec5c7e..c5e09d82d3 100644 --- a/libvips/create/sdf.c +++ b/libvips/create/sdf.c @@ -92,7 +92,7 @@ G_DEFINE_TYPE(VipsSdf, vips_sdf, VIPS_TYPE_CREATE); static float vips_sdf_circle(VipsSdf *sdf, int x, int y) { - return hypot(x - sdf->a[0], y - sdf->a[1]) - sdf->r; + return hypotf(x - sdf->a[0], y - sdf->a[1]) - sdf->r; } static float @@ -101,10 +101,10 @@ vips_sdf_box(VipsSdf *sdf, int x, int y) float px = x - sdf->cx; float py = y - sdf->cy; - float dx = fabs(px) - sdf->sx; - float dy = fabs(py) - sdf->sy; + float dx = fabsf(px) - sdf->sx; + float dy = fabsf(py) - sdf->sy; - return hypot(VIPS_MAX(dx, 0), VIPS_MAX(dy, 0)) + + return hypotf(VIPS_MAX(dx, 0), VIPS_MAX(dy, 0)) + VIPS_MIN(VIPS_MAX(dx, dy), 0); } @@ -119,10 +119,10 @@ vips_sdf_rounded_box(VipsSdf *sdf, int x, int y) float r_bottom = px > 0 ? sdf->corners[1] : sdf->corners[3]; float r = py > 0 ? r_top : r_bottom; - float qx = fabs(px) - sdf->sx + r; - float qy = fabs(py) - sdf->sy + r; + float qx = fabsf(px) - sdf->sx + r; + float qy = fabsf(py) - sdf->sy + r; - return hypot(VIPS_MAX(qx, 0), VIPS_MAX(qy, 0)) + + return hypotf(VIPS_MAX(qx, 0), VIPS_MAX(qy, 0)) + VIPS_MIN(VIPS_MAX(qx, qy), 0) - r; } @@ -134,12 +134,12 @@ vips_sdf_line(VipsSdf *sdf, int px, int py) float dot_paba = pax * sdf->dx + pay * sdf->dy; float dot_baba = sdf->dx * sdf->dx + sdf->dy * sdf->dy; - float h = VIPS_CLIP(0, dot_paba / dot_baba, 1); + float h = VIPS_FCLIP(0, dot_paba / dot_baba, 1); float dx = pax - h * sdf->dx; float dy = pay - h * sdf->dy; - return hypot(dx, dy); + return hypotf(dx, dy); } static int diff --git a/libvips/create/sines.c b/libvips/create/sines.c index e342577794..aa13efbc59 100644 --- a/libvips/create/sines.c +++ b/libvips/create/sines.c @@ -81,7 +81,7 @@ vips_sines_point(VipsPoint *point, int x, int y) { VipsSines *sines = (VipsSines *) point; - return cos(sines->c * (x * sines->costheta - y * sines->sintheta)); + return cosf(sines->c * (x * sines->costheta - y * sines->sintheta)); } static int diff --git a/libvips/create/worley.c b/libvips/create/worley.c index 4482589c69..2f9b6a7e99 100644 --- a/libvips/create/worley.c +++ b/libvips/create/worley.c @@ -197,9 +197,9 @@ vips_worley_start(VipsImage *out, void *a, void *b) static float vips_int_hypot(int x, int y) { - /* Faster than hypot() for int args. + /* Faster than hypotf() for int args. */ - return sqrt(x * x + y * y); + return sqrtf(x * x + y * y); } static float diff --git a/libvips/create/zone.c b/libvips/create/zone.c index 4d881ab397..81ceeb2c12 100644 --- a/libvips/create/zone.c +++ b/libvips/create/zone.c @@ -75,9 +75,9 @@ vips_zone_point(VipsPoint *point, int x, int y) int hheight = point->height / 2; int h2 = (x - hwidth) * (x - hwidth); int v2 = (y - hheight) * (y - hheight); - double c = VIPS_PI / zone->width; + float c = VIPS_PI / zone->width; - return cos(c * (v2 + h2)); + return cosf(c * (v2 + h2)); } static void diff --git a/libvips/foreign/ppmload.c b/libvips/foreign/ppmload.c index 988f2aa07e..6292e9f14d 100644 --- a/libvips/foreign/ppmload.c +++ b/libvips/foreign/ppmload.c @@ -764,7 +764,7 @@ vips_foreign_load_ppm_class_init(VipsForeignLoadPpmClass *class) static void vips_foreign_load_ppm_init(VipsForeignLoadPpm *ppm) { - ppm->scale = 1.0; + ppm->scale = 1.0F; } typedef struct _VipsForeignLoadPpmFile { diff --git a/libvips/foreign/radiance.c b/libvips/foreign/radiance.c index 828ce3c2ba..292cfbba73 100644 --- a/libvips/foreign/radiance.c +++ b/libvips/foreign/radiance.c @@ -610,7 +610,7 @@ read_new(VipsSource *source, VipsImage *out) strcpy(read->format, COLRFMT); read->expos = 1.0; for (i = 0; i < 3; i++) - read->colcor[i] = 1.0; + read->colcor[i] = 1.0F; read->aspect = 1.0; read->prims[0][0] = CIE_x_r; read->prims[0][1] = CIE_y_r; @@ -858,7 +858,7 @@ write_new(VipsImage *in, VipsTarget *target) strcpy(write->format, COLRFMT); write->expos = 1.0; for (i = 0; i < 3; i++) - write->colcor[i] = 1.0; + write->colcor[i] = 1.0F; write->aspect = 1.0; write->prims[0][0] = CIE_x_r; write->prims[0][1] = CIE_y_r; diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index fbbf7e467c..2aaae395d0 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -447,11 +447,11 @@ half_2_float(gushort h) case 16: return INFINITY * sign; case -15: - return sign / (float) (1 << 14) * (prec / 1024.0); + return sign / (float) (1 << 14) * (prec / 1024.0F); default: return exp > 0 - ? sign * (float) (1 << exp) * (1.0 + prec / 1024.0) - : sign / (float) (1 << -exp) * (1.0 + prec / 1024.0); + ? sign * (float) (1 << exp) * (1.0F + prec / 1024.0F) + : sign / (float) (1 << -exp) * (1.0F + prec / 1024.0F); } } @@ -520,8 +520,8 @@ get_resolution(TIFF *tiff, VipsImage *out) case RESUNIT_INCH: /* In pixels-per-inch ... convert to mm. */ - x /= 10.0 * 2.54; - y /= 10.0 * 2.54; + x /= 10.0F * 2.54F; + y /= 10.0F * 2.54F; vips_image_set_string(out, VIPS_META_RESOLUTION_UNIT, "in"); break; @@ -529,8 +529,8 @@ get_resolution(TIFF *tiff, VipsImage *out) case RESUNIT_CENTIMETER: /* In pixels-per-centimetre ... convert to mm. */ - x /= 10.0; - y /= 10.0; + x /= 10.0F; + y /= 10.0F; vips_image_set_string(out, VIPS_META_RESOLUTION_UNIT, "cm"); break; @@ -545,8 +545,8 @@ get_resolution(TIFF *tiff, VipsImage *out) /* We used to warn about missing res data, but it happens so * often and is so harmless, why bother. */ - x = 1.0; - y = 1.0; + x = 1.0F; + y = 1.0F; } out->Xres = x; diff --git a/libvips/morphology/nearest.c b/libvips/morphology/nearest.c index e213e1e66e..768a2d87f5 100644 --- a/libvips/morphology/nearest.c +++ b/libvips/morphology/nearest.c @@ -116,7 +116,7 @@ vips_fill_nearest_pixel(Circle *circle, int x, int y, int octant) p = (float *) VIPS_IMAGE_ADDR(circle->nearest->distance, x, y); dx = x - circle->seed->x; dy = y - circle->seed->y; - radius = sqrt(dx * dx + dy * dy); + radius = sqrtf(dx * dx + dy * dy); if (p[0] == 0 || p[0] > radius) { From 0622da8790c94e11e941bdc709ce5130fb35ec52 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 17 Mar 2025 12:53:44 +0000 Subject: [PATCH 078/174] fix an off by 1 error in buf.c a harmless error: we did not always write the terminating "..." on buffer fill --- libvips/iofuncs/buf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libvips/iofuncs/buf.c b/libvips/iofuncs/buf.c index 38c05cb4c0..3e94907bcf 100644 --- a/libvips/iofuncs/buf.c +++ b/libvips/iofuncs/buf.c @@ -417,7 +417,10 @@ vips_buf_vappendf(VipsBuf *buf, const char *fmt, va_list ap) if (buf->full) return FALSE; - avail = buf->mx - buf->i - 4; + // -3 to leave space for "..." + // not -4, since the terminating \0 will already be on the string written + // by g_vsnprintf() + avail = buf->mx - buf->i - 3; p = buf->base + buf->i; (void) g_vsnprintf(p, avail, fmt, ap); buf->i += strlen(p); From 02e954efef070f875f618f35fddc4ce609f74d1b Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 17 Mar 2025 15:18:05 +0100 Subject: [PATCH 079/174] magick6load: merge with magick2vips.c (#4375) --- libvips/foreign/magick2vips.c | 958 ---------------------------------- libvips/foreign/magick6load.c | 797 +++++++++++++++++++++++++++- libvips/foreign/meson.build | 1 - 3 files changed, 779 insertions(+), 977 deletions(-) delete mode 100644 libvips/foreign/magick2vips.c diff --git a/libvips/foreign/magick2vips.c b/libvips/foreign/magick2vips.c deleted file mode 100644 index cb1146d5bd..0000000000 --- a/libvips/foreign/magick2vips.c +++ /dev/null @@ -1,958 +0,0 @@ -/* Read a file using libMagick - * - * 7/1/03 JC - * - from im_tiff2vips - * 3/2/03 JC - * - some InitializeMagick() fail with NULL arg - * 2/11/04 - * - im_magick2vips_header() also checks sensible width/height - * 28/10/05 - * - copy attributes to meta - * - write many-frame images as a big column if all frames have identical - * width/height/bands/depth - * 31/3/06 - * - test for magick attr support - * 8/5/06 - * - set RGB16/GREY16 if appropriate - * 10/8/07 - * - support 32/64 bit imagemagick too - * 21/2/08 - * - use MaxRGB if QuantumRange is missing (thanks Bob) - * - look for MAGICKCORE_HDRI_SUPPORT (thanks Marcel) - * - use image->attributes if GetNextImageAttribute() is missing - * 3/3/09 - * - allow funky bit depths, like 14 (thanks Mikkel) - * 17/3/09 - * - reset dcm:display-range to help DICOM read - * 20/4/09 - * - argh libMagick uses 255 == transparent ... we must invert all - * alpha channels - * 12/5/09 - * - fix signed/unsigned warnings - * 23/7/09 - * - SetImageOption() is optional (to help GM) - * 4/2/10 - * - gtkdoc - * 30/4/10 - * - better number of bands detection with GetImageType() - * - use new API stuff, argh - * 17/12/11 - * - turn into a set of read fns ready to be called from a class - * 11/6/13 - * - add @all_frames option, off by default - * 4/12/14 Lovell - * - add @density option - * 16/2/15 mcuelenaere - * - add blob read - * 26/2/15 - * - close the read down early for a header read ... this saves an - * fd during file read, handy for large numbers of input images - * 14/2/16 - * - add @page option, 0 by default - * 18/4/16 - * - fix @page with graphicsmagick - * 25/11/16 - * - remove @all_frames, add @n - * 23/2/17 - * - try using GetImageChannelDepth() instead of ->depth - * 25/5/18 - * - don't use Ping, it's too unreliable - * 24/7/18 - * - sniff extra filetypes - * 4/1/19 kleisauke - * - we did not chain exceptions correctly, causing a memory leak - * - added wrapper funcs for exception handling - * 4/2/19 - * - add profile (xmp, ipct, etc.) read - * 12/11/21 - * - set "orientation" - * 26/8/22 - * - set "magick-format" - * 13/3/23 MathemanFlo - * - add bits per sample metadata - */ - -/* - - This file is part of VIPS. - - VIPS is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA - - */ - -/* - - These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk - - */ - -/* Turn on debugging output. -#define DEBUG - */ - -#ifdef HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ -#include - -#ifdef ENABLE_MAGICKLOAD - -#ifdef HAVE_MAGICK6 - -#include -#include -#include -#include - -#include -#include - -#include - -#include "pforeign.h" -#include "magick.h" - -/* pre-float Magick used to call this MaxRGB. - */ -#if !defined(QuantumRange) -#define QuantumRange MaxRGB -#endif - -/* And this used to be UseHDRI. - */ -#if MAGICKCORE_HDRI_SUPPORT -#define UseHDRI 1 -#endif - -/* What we track during a read call. - */ -typedef struct _Read { - char *filename; - VipsImage *im; - const void *buf; - size_t len; - int page; - int n; - - Image *image; - ImageInfo *image_info; - ExceptionInfo *exception; - - /* Number of pages in image. - */ - int n_pages; - - /* Number of pages we will read. - */ - int n_frames; - - Image **frames; - int frame_height; - - /* Mutex to serialise calls to libMagick during threaded read. - */ - GMutex *lock; -} Read; - -/* Can be called many times. - */ -static void -read_free(Read *read) -{ -#ifdef DEBUG - printf("magick2vips: read_free: %s\n", read->filename); -#endif /*DEBUG*/ - - VIPS_FREE(read->filename); - VIPS_FREEF(DestroyImageList, read->image); - VIPS_FREEF(DestroyImageInfo, read->image_info); - VIPS_FREE(read->frames); - VIPS_FREEF(magick_destroy_exception, read->exception); - VIPS_FREEF(vips_g_mutex_free, read->lock); -} - -/* Can be called many times. - */ -static int -read_close(VipsImage *im, Read *read) -{ - read_free(read); - - return 0; -} - -static Read * -read_new(const char *filename, VipsImage *im, - const void *buf, const size_t len, - const char *density, int page, int n) -{ - Read *read; - - magick_genesis(); - - /* IM doesn't use the -1 means end-of-file convention, change it to a - * very large number. - */ - if (n == -1) - n = 10000000; - - if (!(read = VIPS_NEW(im, Read))) - return NULL; - read->filename = filename ? g_strdup(filename) : NULL; - read->buf = buf; - read->len = len; - read->page = page; - read->n = n; - read->im = im; - read->image = NULL; - read->image_info = CloneImageInfo(NULL); - read->exception = magick_acquire_exception(); - read->n_pages = 0; - read->n_frames = 0; - read->frames = NULL; - read->frame_height = 0; - read->lock = vips_g_mutex_new(); - - g_signal_connect(im, "close", G_CALLBACK(read_close), read); - - if (!read->image_info) - return NULL; - - if (filename) - g_strlcpy(read->image_info->filename, - filename, MaxTextExtent); - - /* Any extra file format detection. - */ - if (filename) - magick_sniff_file(read->image_info, filename); - if (buf) - magick_sniff_bytes(read->image_info, buf, len); - - /* Canvas resolution for rendering vector formats like SVG. - */ - VIPS_SETSTR(read->image_info->density, density); - - /* When reading DICOM images, we want to ignore any - * window_center/_width setting, since it may put pixels outside the - * 0-65535 range and lose data. - * - * These window settings are attached as vips metadata, so our caller - * can interpret them if it wants. - */ - magick_set_image_option(read->image_info, - "dcm:display-range", "reset"); - - if (read->page > 0) - magick_set_number_scenes(read->image_info, - read->page, read->n); - -#ifdef DEBUG - printf("magick2vips: read_new: %s\n", read->filename); -#endif /*DEBUG*/ - - return read; -} - -static int -get_bands(Image *image) -{ - int bands; - ImageType type = GetImageType(image, &image->exception); - - switch (type) { - case BilevelType: - case GrayscaleType: - bands = 1; - break; - - case GrayscaleMatteType: - /* ImageMagick also has PaletteBilevelMatteType, but GraphicsMagick - * does not. Skip for portability. - */ - bands = 2; - break; - - case PaletteType: - case TrueColorType: - bands = 3; - break; - - case PaletteMatteType: - case TrueColorMatteType: - case ColorSeparationType: - bands = 4; - break; - - case ColorSeparationMatteType: - bands = 5; - break; - - default: - vips_error("magick2vips", _("unsupported image type %d"), - (int) type); - return -1; - } - - return bands; -} - -static int -parse_header(Read *read) -{ - VipsImage *im = read->im; - Image *image = read->image; - - int depth; - Image *p; - int i; - -#ifdef DEBUG - printf("parse_header: filename = %s\n", read->filename); - printf("GetImageChannelDepth(AllChannels) = %zd\n", - GetImageChannelDepth(image, AllChannels, &image->exception)); - printf("GetImageDepth() = %zd\n", - GetImageDepth(image, &image->exception)); - printf("image->depth = %zd\n", image->depth); - printf("GetImageType() = %d\n", - GetImageType(image, &image->exception)); - printf("IsGrayImage() = %d\n", - IsGrayImage(image, &image->exception)); - printf("IsMonochromeImage() = %d\n", - IsMonochromeImage(image, &image->exception)); - printf("IsOpaqueImage() = %d\n", - IsOpaqueImage(image, &image->exception)); - printf("image->columns = %zd\n", image->columns); - printf("image->rows = %zd\n", image->rows); -#endif /*DEBUG*/ - - im->Coding = VIPS_CODING_NONE; - im->Xsize = image->columns; - im->Ysize = image->rows; - read->frame_height = image->rows; - im->Bands = get_bands(image); - if (im->Xsize <= 0 || - im->Ysize <= 0 || - im->Bands <= 0 || - im->Xsize >= VIPS_MAX_COORD || - im->Ysize >= VIPS_MAX_COORD || - im->Bands >= VIPS_MAX_COORD) { - vips_error("magick2vips", - _("bad image dimensions %d x %d pixels, %d bands"), - im->Xsize, im->Ysize, im->Bands); - return -1; - } - - /* Depth can be 'fractional'. - * - * You'd think we should use - * GetImageDepth() but that seems unreliable. 16-bit mono DICOM images - * are reported as depth 1, for example. - * - * Try GetImageChannelDepth(), maybe that works. - */ - depth = GetImageChannelDepth(image, AllChannels, &image->exception); - im->BandFmt = -1; - if (depth >= 1 && depth <= 8) - im->BandFmt = VIPS_FORMAT_UCHAR; - if (depth >= 9 && depth <= 16) - im->BandFmt = VIPS_FORMAT_USHORT; -#ifdef UseHDRI - if (depth == 32) - im->BandFmt = VIPS_FORMAT_FLOAT; - if (depth == 64) - im->BandFmt = VIPS_FORMAT_DOUBLE; -#else /*!UseHDRI*/ - if (depth == 32) - im->BandFmt = VIPS_FORMAT_UINT; -#endif /*UseHDRI*/ - - if (im->BandFmt == -1) { - vips_error("magick2vips", _("unsupported bit depth %d"), - (int) depth); - return -1; - } - - switch (image->units) { - case PixelsPerInchResolution: - im->Xres = image->x_resolution / 25.4; - im->Yres = image->y_resolution / 25.4; - break; - - case PixelsPerCentimeterResolution: - im->Xres = image->x_resolution / 10.0; - im->Yres = image->y_resolution / 10.0; - break; - - default: - im->Xres = 1.0; - im->Yres = 1.0; - break; - } - - // this can be wrong for some GM versions and must be sanity checked (see - // below) - switch (image->colorspace) { - case GRAYColorspace: - if (im->BandFmt == VIPS_FORMAT_USHORT) - im->Type = VIPS_INTERPRETATION_GREY16; - else - im->Type = VIPS_INTERPRETATION_B_W; - break; - - case sRGBColorspace: - case RGBColorspace: - if (im->BandFmt == VIPS_FORMAT_USHORT) - im->Type = VIPS_INTERPRETATION_RGB16; - else - im->Type = VIPS_INTERPRETATION_sRGB; - break; - - case CMYKColorspace: - im->Type = VIPS_INTERPRETATION_CMYK; - break; - - default: - im->Type = VIPS_INTERPRETATION_ERROR; - break; - } - - // revise the interpretation if it seems crazy - im->Type = vips_image_guess_interpretation(im); - - if (vips_image_pipelinev(im, VIPS_DEMAND_STYLE_SMALLTILE, NULL)) - return -1; - - /* Set vips metadata from ImageMagick profiles. - */ - if (magick_set_vips_profile(im, image)) - return -1; - -#ifdef HAVE_RESETIMAGEPROPERTYITERATOR - { - char *key; - - /* This is the most recent imagemagick API, test for this first. - */ - ResetImagePropertyIterator(image); - while ((key = GetNextImageProperty(image))) { - char name_text[256]; - VipsBuf name = VIPS_BUF_STATIC(name_text); - - vips_buf_appendf(&name, "magick-%s", key); - vips_image_set_string(im, - vips_buf_all(&name), GetImageProperty(image, key)); - } - } -#elif defined(HAVE_RESETIMAGEATTRIBUTEITERATOR) - { - const ImageAttribute *attr; - - /* magick6.1-ish and later, deprecated in 6.5ish. - */ - ResetImageAttributeIterator(image); - while ((attr = GetNextImageAttribute(image))) { - char name_text[256]; - VipsBuf name = VIPS_BUF_STATIC(name_text); - - vips_buf_appendf(&name, "magick-%s", attr->key); - vips_image_set_string(im, vips_buf_all(&name), attr->value); - } - } -#else - { - const ImageAttribute *attr; - - /* GraphicsMagick is missing the iterator: we have to loop ourselves. - * ->attributes is marked as private in the header, but there's no - * getter so we have to access it directly. - */ - for (attr = image->attributes; attr; attr = attr->next) { - char name_text[256]; - VipsBuf name = VIPS_BUF_STATIC(name_text); - - vips_buf_appendf(&name, "magick-%s", attr->key); - vips_image_set_string(im, vips_buf_all(&name), attr->value); - } - } -#endif - - /* Something like "BMP". - */ - if (strlen(read->image->magick) > 0) - vips_image_set_string(im, "magick-format", - read->image->magick); - - /* Do we have a set of equal-sized frames? Append them. - - FIXME ... there must be an attribute somewhere from dicom read - which says this is a volumetric image - - */ - read->n_pages = GetImageListLength(image); - read->n_frames = 0; - for (p = image; p; (p = GetNextImageInList(p))) { - int p_depth = - GetImageChannelDepth(p, AllChannels, &p->exception); - - if (p->columns != (unsigned int) im->Xsize || - p->rows != (unsigned int) im->Ysize || - get_bands(p) != im->Bands || - p_depth != depth) { -#ifdef DEBUG - printf("frame %d differs\n", read->n_frames); - printf("%zdx%zd, %d bands\n", - p->columns, p->rows, get_bands(p)); - printf("first frame is %dx%d, %d bands\n", - im->Xsize, im->Ysize, im->Bands); -#endif /*DEBUG*/ - - break; - } - - read->n_frames += 1; - } - if (p) - /* Nope ... just do the first image in the list. - */ - read->n_frames = 1; - -#ifdef DEBUG - printf("will read %d frames\n", read->n_frames); -#endif /*DEBUG*/ - - if (read->n != -1) - read->n_frames = VIPS_MIN(read->n_frames, read->n); - - /* Record frame pointers. - */ - if (!(read->frames = VIPS_ARRAY(NULL, read->n_frames, Image *))) - return -1; - p = image; - for (i = 0; i < read->n_frames; i++) { - read->frames[i] = p; - p = GetNextImageInList(p); - } - - if (read->n_frames > 1) { - vips_image_set_int(im, VIPS_META_PAGE_HEIGHT, im->Ysize); - im->Ysize *= read->n_frames; - } - - vips_image_set_int(im, VIPS_META_N_PAGES, read->n_pages); - - vips_image_set_int(im, VIPS_META_ORIENTATION, - VIPS_CLIP(1, image->orientation, 8)); - - vips_image_set_int(im, VIPS_META_BITS_PER_SAMPLE, depth); - - return 0; -} - -/* Divide by this to get 0 - MAX from a Quantum. Eg. consider QuantumRange == - * 65535, MAX == 255 (a Q16 ImageMagic representing an 8-bit image). Make sure - * this can't be zero (if QuantumRange < MAX) .. can happen if we have a Q8 - * ImageMagick trying to represent a 16-bit image. - */ -#define SCALE(MAX) \ - (QuantumRange < (MAX) \ - ? 1 \ - : ((QuantumRange + 1) / ((MAX) + 1))) - -#define GRAY_LOOP(TYPE, MAX) \ - { \ - TYPE *q = (TYPE *) q8; \ -\ - for (x = 0; x < n; x++) \ - q[x] = pixels[x].green / SCALE(MAX); \ - } - -#define GRAYA_LOOP(TYPE, MAX) \ - { \ - TYPE *q = (TYPE *) q8; \ -\ - for (x = 0; x < n; x++) { \ - q[0] = pixels[x].green / SCALE(MAX); \ - q[1] = MAX - pixels[x].opacity / SCALE(MAX); \ -\ - q += 2; \ - } \ - } - -#define RGB_LOOP(TYPE, MAX) \ - { \ - TYPE *q = (TYPE *) q8; \ -\ - for (x = 0; x < n; x++) { \ - q[0] = pixels[x].red / SCALE(MAX); \ - q[1] = pixels[x].green / SCALE(MAX); \ - q[2] = pixels[x].blue / SCALE(MAX); \ -\ - q += 3; \ - } \ - } - -#define RGBA_LOOP(TYPE, MAX) \ - { \ - TYPE *q = (TYPE *) q8; \ -\ - for (x = 0; x < n; x++) { \ - q[0] = pixels[x].red / SCALE(MAX); \ - q[1] = pixels[x].green / SCALE(MAX); \ - q[2] = pixels[x].blue / SCALE(MAX); \ - q[3] = MAX - pixels[x].opacity / SCALE(MAX); \ -\ - q += 4; \ - } \ - } - -static void -unpack_pixels(VipsImage *im, VipsPel *q8, PixelPacket *pixels, int n) -{ - int x; - - switch (im->Bands) { - case 1: - /* Gray. - */ - switch (im->BandFmt) { - case VIPS_FORMAT_UCHAR: - GRAY_LOOP(unsigned char, 255); - break; - case VIPS_FORMAT_USHORT: - GRAY_LOOP(unsigned short, 65535); - break; - case VIPS_FORMAT_UINT: - GRAY_LOOP(unsigned int, 4294967295UL); - break; - case VIPS_FORMAT_DOUBLE: - GRAY_LOOP(double, QuantumRange); - break; - - default: - g_assert_not_reached(); - } - break; - - case 2: - /* Gray plus alpha. - */ - switch (im->BandFmt) { - case VIPS_FORMAT_UCHAR: - GRAYA_LOOP(unsigned char, 255); - break; - case VIPS_FORMAT_USHORT: - GRAYA_LOOP(unsigned short, 65535); - break; - case VIPS_FORMAT_UINT: - GRAYA_LOOP(unsigned int, 4294967295UL); - break; - case VIPS_FORMAT_DOUBLE: - GRAYA_LOOP(double, QuantumRange); - break; - - default: - g_assert_not_reached(); - } - break; - - case 3: - /* RGB. - */ - switch (im->BandFmt) { - case VIPS_FORMAT_UCHAR: - RGB_LOOP(unsigned char, 255); - break; - case VIPS_FORMAT_USHORT: - RGB_LOOP(unsigned short, 65535); - break; - case VIPS_FORMAT_UINT: - RGB_LOOP(unsigned int, 4294967295UL); - break; - case VIPS_FORMAT_DOUBLE: - RGB_LOOP(double, QuantumRange); - break; - - default: - g_assert_not_reached(); - } - break; - - case 4: - /* RGBA or CMYK. - */ - switch (im->BandFmt) { - case VIPS_FORMAT_UCHAR: - RGBA_LOOP(unsigned char, 255); - break; - case VIPS_FORMAT_USHORT: - RGBA_LOOP(unsigned short, 65535); - break; - case VIPS_FORMAT_UINT: - RGBA_LOOP(unsigned int, 4294967295UL); - break; - case VIPS_FORMAT_DOUBLE: - RGBA_LOOP(double, QuantumRange); - break; - - default: - g_assert_not_reached(); - } - break; - - default: - g_assert_not_reached(); - } -} - -static PixelPacket * -get_pixels(Image *image, int left, int top, int width, int height) -{ - PixelPacket *pixels; - -#ifdef HAVE_GETVIRTUALPIXELS - if (!(pixels = (PixelPacket *) GetVirtualPixels(image, - left, top, width, height, &image->exception))) -#else - if (!(pixels = GetImagePixels(image, left, top, width, height))) -#endif - return NULL; - -/* Can't happen if red/green/blue are doubles. - */ -#ifndef UseHDRI - /* Unpack palette. - */ - if (image->storage_class == PseudoClass) { -#ifdef HAVE_GETVIRTUALPIXELS - IndexPacket *indexes = (IndexPacket *) - GetVirtualIndexQueue(image); -#else - /* Was GetIndexes(), but that's now deprecated. - */ - IndexPacket *indexes = AccessMutableIndexes(image); -#endif - - int i; - - for (i = 0; i < width * height; i++) { - IndexPacket x = indexes[i]; - - if (x < image->colors) { - pixels[i].red = image->colormap[x].red; - pixels[i].green = image->colormap[x].green; - pixels[i].blue = image->colormap[x].blue; - } - } - } -#endif /*UseHDRI*/ - - return pixels; -} - -static int -magick_fill_region(VipsRegion *out, - void *seq, void *a, void *b, gboolean *stop) -{ - Read *read = (Read *) a; - VipsRect *r = &out->valid; - int y; - - for (y = 0; y < r->height; y++) { - int top = r->top + y; - int frame = top / read->frame_height; - int line = top % read->frame_height; - - PixelPacket *pixels; - - vips__worker_lock(read->lock); - - pixels = get_pixels(read->frames[frame], - r->left, line, r->width, 1); - - g_mutex_unlock(read->lock); - - if (!pixels) { - vips_foreign_load_invalidate(read->im); - vips_error("magick2vips", - "%s", _("unable to read pixels")); - return -1; - } - - unpack_pixels(read->im, VIPS_REGION_ADDR(out, r->left, top), - pixels, r->width); - } - - return 0; -} - -int -vips__magick_read(const char *filename, - VipsImage *out, const char *density, int page, int n) -{ - Read *read; - -#ifdef DEBUG - printf("magick2vips: vips__magick_read: %s\n", filename); -#endif /*DEBUG*/ - - if (!(read = read_new(filename, out, NULL, n, density, page, n))) - return -1; - -#ifdef DEBUG - printf("magick2vips: calling ReadImage() ...\n"); -#endif /*DEBUG*/ - - read->image = ReadImage(read->image_info, read->exception); - if (!read->image) { - magick_vips_error("magick2vips", read->exception); - vips_error("magick2vips", - _("unable to read file \"%s\""), filename); - return -1; - } - - if (parse_header(read)) - return -1; - if (vips_image_generate(out, - NULL, magick_fill_region, NULL, read, NULL)) - return -1; - - return 0; -} - -int -vips__magick_read_header(const char *filename, - VipsImage *out, const char *density, int page, int n) -{ - Read *read; - -#ifdef DEBUG - printf("vips__magick_read_header: %s\n", filename); -#endif /*DEBUG*/ - - if (!(read = read_new(filename, out, NULL, 0, density, page, n))) - return -1; - -#ifdef DEBUG - printf("vips__magick_read_header: reading image ...\n"); -#endif /*DEBUG*/ - - /* It would be great if we could PingImage and just read the header, - * but sadly many IM coders do not support ping. The critical one for - * us is DICOM. TGA also has issues. - */ - read->image = ReadImage(read->image_info, read->exception); - if (!read->image) { - magick_vips_error("magick2vips", read->exception); - vips_error("magick2vips", - _("unable to read file \"%s\""), filename); - return -1; - } - - if (parse_header(read)) - return -1; - - if (out->Xsize <= 0 || - out->Ysize <= 0) { - vips_error("magick2vips", "%s", _("bad image size")); - return -1; - } - - /* Just a header read: we can free the read early and save an fd. - */ - read_free(read); - - return 0; -} - -int -vips__magick_read_buffer(const void *buf, const size_t len, - VipsImage *out, const char *density, int page, int n) -{ - Read *read; - -#ifdef DEBUG - printf("magick2vips: vips__magick_read_buffer: %p %zu\n", buf, len); -#endif /*DEBUG*/ - - if (!(read = read_new(NULL, out, buf, len, density, page, n))) - return -1; - -#ifdef DEBUG - printf("magick2vips: calling BlobToImage() ...\n"); -#endif /*DEBUG*/ - - read->image = BlobToImage(read->image_info, - buf, len, read->exception); - if (!read->image) { - magick_vips_error("magick2vips", read->exception); - vips_error("magick2vips", "%s", _("unable to read buffer")); - return -1; - } - - if (parse_header(read)) - return -1; - if (vips_image_generate(out, - NULL, magick_fill_region, NULL, read, NULL)) - return -1; - - return 0; -} - -int -vips__magick_read_buffer_header(const void *buf, const size_t len, - VipsImage *out, const char *density, int page, int n) -{ - Read *read; - -#ifdef DEBUG - printf("vips__magick_read_buffer_header: %p %zu\n", buf, len); -#endif /*DEBUG*/ - - if (!(read = read_new(NULL, out, buf, len, density, page, n))) - return -1; - -#ifdef DEBUG - printf("vips__magick_read_buffer_header: pinging blob ...\n"); -#endif /*DEBUG*/ - - /* It would be great if we could PingBlob and just read the header, - * but sadly many IM coders do not support ping well. The critical one - * for us is DICOM. TGA also has issues. - */ - read->image = BlobToImage(read->image_info, - buf, len, read->exception); - if (!read->image) { - magick_vips_error("magick2vips", read->exception); - vips_error("magick2vips", "%s", _("unable to ping blob")); - return -1; - } - - if (parse_header(read)) - return -1; - - if (out->Xsize <= 0 || - out->Ysize <= 0) { - vips_error("magick2vips", "%s", _("bad image size")); - return -1; - } - - return 0; -} - -#endif /*HAVE_MAGICK6*/ - -#endif /*ENABLE_MAGICKLOAD*/ diff --git a/libvips/foreign/magick6load.c b/libvips/foreign/magick6load.c index 31432087ef..bf1a63ae8e 100644 --- a/libvips/foreign/magick6load.c +++ b/libvips/foreign/magick6load.c @@ -1,19 +1,83 @@ /* load with libMagick * - * 5/12/11 - * - from openslideload.c + * 7/1/03 JC + * - from im_tiff2vips + * 3/2/03 JC + * - some InitializeMagick() fail with NULL arg + * 2/11/04 + * - im_magick2vips_header() also checks sensible width/height + * 28/10/05 + * - copy attributes to meta + * - write many-frame images as a big column if all frames have identical + * width/height/bands/depth + * 31/3/06 + * - test for magick attr support + * 8/5/06 + * - set RGB16/GREY16 if appropriate + * 10/8/07 + * - support 32/64 bit imagemagick too + * 21/2/08 + * - use MaxRGB if QuantumRange is missing (thanks Bob) + * - look for MAGICKCORE_HDRI_SUPPORT (thanks Marcel) + * - use image->attributes if GetNextImageAttribute() is missing + * 3/3/09 + * - allow funky bit depths, like 14 (thanks Mikkel) + * 17/3/09 + * - reset dcm:display-range to help DICOM read + * 20/4/09 + * - argh libMagick uses 255 == transparent ... we must invert all + * alpha channels + * 12/5/09 + * - fix signed/unsigned warnings + * 23/7/09 + * - SetImageOption() is optional (to help GM) + * 4/2/10 + * - gtkdoc + * 30/4/10 + * - better number of bands detection with GetImageType() + * - use new API stuff, argh + * 17/12/11 + * - turn into a set of read fns ready to be called from a class * 17/1/12 * - remove header-only loads * 11/6/13 * - add @all_frames option, off by default + * 4/12/14 Lovell + * - add @density option + * 16/2/15 mcuelenaere + * - add blob read + * 26/2/15 + * - close the read down early for a header read ... this saves an + * fd during file read, handy for large numbers of input images * 14/2/16 * - add @page option, 0 by default + * 18/4/16 + * - fix @page with graphicsmagick * 25/11/16 * - add @n, deprecate @all_frames (just sets n = -1) + * 23/2/17 + * - try using GetImageChannelDepth() instead of ->depth * 8/9/17 * - don't cache magickload + * 25/5/18 + * - don't use Ping, it's too unreliable + * 24/7/18 + * - sniff extra filetypes + * 4/1/19 kleisauke + * - we did not chain exceptions correctly, causing a memory leak + * - added wrapper funcs for exception handling + * 4/2/19 + * - add profile (xmp, ipct, etc.) read * 21/4/21 kleisauke * - include GObject part from magickload.c + * 12/11/21 + * - set "orientation" + * 26/8/22 + * - set "magick-format" + * 13/3/23 MathemanFlo + * - add bits per sample metadata + * 08/11/24 kleisauke + * - merge with magick2vips.c */ /* @@ -55,6 +119,7 @@ #include #include #include +#include #include #include @@ -64,9 +129,23 @@ #ifdef HAVE_MAGICK6 +#include + #include "pforeign.h" #include "magick.h" +/* pre-float Magick used to call this MaxRGB. + */ +#if !defined(QuantumRange) +#define QuantumRange MaxRGB +#endif + +/* And this used to be UseHDRI. + */ +#if MAGICKCORE_HDRI_SUPPORT +#define UseHDRI 1 +#endif + typedef struct _VipsForeignLoadMagick { VipsForeignLoad parent_object; @@ -78,6 +157,22 @@ typedef struct _VipsForeignLoadMagick { int page; /* Load this page (frame) */ int n; /* Load this many pages */ + Image *image; + ImageInfo *image_info; + ExceptionInfo *exception; + + /* Number of pages in image. + */ + int n_pages; + + int n_frames; /* Number of frames we will read */ + Image **frames; /* An Image* for each frame */ + int frame_height; + + /* Mutex to serialise calls to libMagick during threaded read. + */ + GMutex *lock; + } VipsForeignLoadMagick; typedef VipsForeignLoadClass VipsForeignLoadMagickClass; @@ -97,6 +192,75 @@ vips_foreign_load_magick_get_flags(VipsForeignLoad *load) return VIPS_FOREIGN_PARTIAL; } +static void +vips_foreign_load_magick_dispose(GObject *gobject) +{ + VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) gobject; + +#ifdef DEBUG + printf("vips_foreign_load_magick_dispose: %p\n", gobject); +#endif /*DEBUG*/ + + VIPS_FREEF(DestroyImageList, magick->image); + VIPS_FREEF(DestroyImageInfo, magick->image_info); + VIPS_FREE(magick->frames); + VIPS_FREEF(magick_destroy_exception, magick->exception); + VIPS_FREEF(vips_g_mutex_free, magick->lock); + + G_OBJECT_CLASS(vips_foreign_load_magick_parent_class)->dispose(gobject); +} + +static int +vips_foreign_load_magick_build(VipsObject *object) +{ + VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) object; + +#ifdef DEBUG + printf("vips_foreign_load_magick_build: %p\n", object); +#endif /*DEBUG*/ + + magick_genesis(); + + magick->image_info = CloneImageInfo(NULL); + magick->exception = magick_acquire_exception(); + magick->lock = vips_g_mutex_new(); + + if (!magick->image_info) + return -1; + + if (magick->all_frames) + magick->n = -1; // FIXME: Invalidates operation cache + + /* IM doesn't use the -1 means end-of-file convention, change it to a + * very large number. + */ + if (magick->n == -1) + magick->n = 10000000; // FIXME: Invalidates operation cache + + /* Canvas resolution for rendering vector formats like SVG. + */ + VIPS_SETSTR(magick->image_info->density, magick->density); + + /* When reading DICOM images, we want to ignore any + * window_center/_width setting, since it may put pixels outside the + * 0-65535 range and lose data. + * + * These window settings are attached as vips metadata, so our caller + * can interpret them if it wants. + */ + magick_set_image_option(magick->image_info, + "dcm:display-range", "reset"); + + if (magick->page > 0) + magick_set_number_scenes(magick->image_info, + magick->page, magick->n); + + if (VIPS_OBJECT_CLASS(vips_foreign_load_magick_parent_class)->build(object)) + return -1; + + return 0; +} + static void vips_foreign_load_magick_class_init(VipsForeignLoadMagickClass *class) { @@ -106,11 +270,13 @@ vips_foreign_load_magick_class_init(VipsForeignLoadMagickClass *class) VipsForeignClass *foreign_class = (VipsForeignClass *) class; VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; + gobject_class->dispose = vips_foreign_load_magick_dispose; gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; object_class->nickname = "magickload_base"; object_class->description = _("load with ImageMagick"); + object_class->build = vips_foreign_load_magick_build; /* Don't cache magickload: it can gobble up memory and disc. */ @@ -165,6 +331,577 @@ vips_foreign_load_magick_init(VipsForeignLoadMagick *magick) magick->n = 1; } +static int +magick_get_bands(Image *image) +{ + int bands; + ImageType type = GetImageType(image, &image->exception); + + switch (type) { + case BilevelType: + case GrayscaleType: + bands = 1; + break; + + case GrayscaleMatteType: + /* ImageMagick also has PaletteBilevelMatteType, but GraphicsMagick + * does not. Skip for portability. + */ + bands = 2; + break; + + case PaletteType: + case TrueColorType: + bands = 3; + break; + + case PaletteMatteType: + case TrueColorMatteType: + case ColorSeparationType: + bands = 4; + break; + + case ColorSeparationMatteType: + bands = 5; + break; + + default: + vips_error("magick2vips", _("unsupported image type %d"), + (int) type); + return -1; + } + + return bands; +} + +static int +vips_foreign_load_magick_parse(VipsForeignLoadMagick *magick, + Image *image, VipsImage *out) +{ + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(magick); + + int depth; + Image *p; + +#ifdef DEBUG + printf("GetImageChannelDepth(AllChannels) = %zd\n", + GetImageChannelDepth(image, AllChannels, &image->exception)); + printf("GetImageDepth() = %zd\n", + GetImageDepth(image, &image->exception)); + printf("image->depth = %zd\n", image->depth); + printf("GetImageType() = %d\n", + GetImageType(image, &image->exception)); + printf("IsGrayImage() = %d\n", + IsGrayImage(image, &image->exception)); + printf("IsMonochromeImage() = %d\n", + IsMonochromeImage(image, &image->exception)); + printf("IsOpaqueImage() = %d\n", + IsOpaqueImage(image, &image->exception)); + printf("image->columns = %zd\n", image->columns); + printf("image->rows = %zd\n", image->rows); +#endif /*DEBUG*/ + + /* Ysize updated below once we have worked out how many frames to load. + */ + out->Coding = VIPS_CODING_NONE; + out->Xsize = image->columns; + out->Ysize = image->rows; + magick->frame_height = image->rows; + out->Bands = magick_get_bands(image); + if (out->Xsize <= 0 || + out->Ysize <= 0 || + out->Bands <= 0 || + out->Xsize >= VIPS_MAX_COORD || + out->Ysize >= VIPS_MAX_COORD || + out->Bands >= VIPS_MAX_COORD) { + vips_error(class->nickname, + _("bad image dimensions %d x %d pixels, %d bands"), + out->Xsize, out->Ysize, out->Bands); + return -1; + } + + /* Depth can be 'fractional'. You'd think we should use + * GetImageDepth() but that seems unreliable. 16-bit mono DICOM images + * are reported as depth 1, for example. + * + * Try GetImageChannelDepth(), maybe that works. + */ + depth = GetImageChannelDepth(image, AllChannels, &image->exception); + + out->BandFmt = -1; + if (depth >= 1 && depth <= 8) + out->BandFmt = VIPS_FORMAT_UCHAR; + if (depth >= 9 && depth <= 16) + out->BandFmt = VIPS_FORMAT_USHORT; +#ifdef UseHDRI + if (depth == 32) + out->BandFmt = VIPS_FORMAT_FLOAT; + if (depth == 64) + out->BandFmt = VIPS_FORMAT_DOUBLE; +#else /*!UseHDRI*/ + if (depth == 32) + out->BandFmt = VIPS_FORMAT_UINT; +#endif /*UseHDRI*/ + + if (out->BandFmt == -1) { + vips_error(class->nickname, + _("unsupported bit depth %d"), depth); + return -1; + } + + switch (image->units) { + case PixelsPerInchResolution: + out->Xres = image->x_resolution / 25.4; + out->Yres = image->y_resolution / 25.4; + vips_image_set_string(out, VIPS_META_RESOLUTION_UNIT, "in"); + break; + + case PixelsPerCentimeterResolution: + out->Xres = image->x_resolution / 10.0; + out->Yres = image->y_resolution / 10.0; + vips_image_set_string(out, VIPS_META_RESOLUTION_UNIT, "cm"); + break; + + default: + /* Things like GIF have no resolution info. + */ + out->Xres = 1.0; + out->Yres = 1.0; + break; + } + + // this can be wrong for some GM versions and must be sanity checked (see + // below) + switch (image->colorspace) { + case GRAYColorspace: + if (out->BandFmt == VIPS_FORMAT_USHORT) + out->Type = VIPS_INTERPRETATION_GREY16; + else + out->Type = VIPS_INTERPRETATION_B_W; + break; + + case sRGBColorspace: + case RGBColorspace: + if (out->BandFmt == VIPS_FORMAT_USHORT) + out->Type = VIPS_INTERPRETATION_RGB16; + else + out->Type = VIPS_INTERPRETATION_sRGB; + break; + + case CMYKColorspace: + out->Type = VIPS_INTERPRETATION_CMYK; + break; + + default: + out->Type = VIPS_INTERPRETATION_ERROR; + break; + } + + // revise the interpretation if it seems crazy + out->Type = vips_image_guess_interpretation(out); + + if (vips_image_pipelinev(out, VIPS_DEMAND_STYLE_SMALLTILE, NULL)) + return -1; + +#ifdef HAVE_RESETIMAGEPROPERTYITERATOR + { + char *key; + + /* This is the most recent imagemagick API, test for this first. + */ + ResetImagePropertyIterator(image); + while ((key = GetNextImageProperty(image))) { + char name_text[256]; + VipsBuf name = VIPS_BUF_STATIC(name_text); + + vips_buf_appendf(&name, "magick-%s", key); + vips_image_set_string(out, + vips_buf_all(&name), GetImageProperty(image, key)); + } + } +#elif defined(HAVE_RESETIMAGEATTRIBUTEITERATOR) + { + const ImageAttribute *attr; + + /* magick6.1-ish and later, deprecated in 6.5ish. + */ + ResetImageAttributeIterator(image); + while ((attr = GetNextImageAttribute(image))) { + char name_text[256]; + VipsBuf name = VIPS_BUF_STATIC(name_text); + + vips_buf_appendf(&name, "magick-%s", attr->key); + vips_image_set_string(out, vips_buf_all(&name), attr->value); + } + } +#else + { + const ImageAttribute *attr; + + /* GraphicsMagick is missing the iterator: we have to loop ourselves. + * ->attributes is marked as private in the header, but there's no + * getter so we have to access it directly. + */ + for (attr = image->attributes; attr; attr = attr->next) { + char name_text[256]; + VipsBuf name = VIPS_BUF_STATIC(name_text); + + vips_buf_appendf(&name, "magick-%s", attr->key); + vips_image_set_string(out, vips_buf_all(&name), attr->value); + } + } +#endif + + /* Set vips metadata from ImageMagick profiles. + */ + if (magick_set_vips_profile(out, image)) + return -1; + + /* Something like "BMP". + */ + if (strlen(magick->image->magick) > 0) + vips_image_set_string(out, "magick-format", + magick->image->magick); + + magick->n_pages = GetImageListLength(image); +#ifdef DEBUG + printf("image has %d pages\n", magick->n_pages); +#endif /*DEBUG*/ + + /* Do we have a set of equal-sized frames? Append them. + + FIXME ... there must be an attribute somewhere from dicom read + which says this is a volumetric image + + */ + magick->n_frames = 0; + + for (p = image; p; (p = GetNextImageInList(p))) { + int p_depth = + GetImageChannelDepth(p, AllChannels, &p->exception); + + if (p->columns != (unsigned int) out->Xsize || + p->rows != (unsigned int) out->Ysize || + magick_get_bands(p) != out->Bands || + p_depth != depth) { +#ifdef DEBUG + printf("frame %d differs\n", read->n_frames); + printf("%zdx%zd, %d bands\n", + p->columns, p->rows, get_bands(p)); + printf("first frame is %dx%d, %d bands\n", + im->Xsize, im->Ysize, im->Bands); +#endif /*DEBUG*/ + + break; + } + + magick->n_frames += 1; + } + if (p) + /* Nope ... just do the first image in the list. + */ + magick->n_frames = 1; + +#ifdef DEBUG + printf("will read %d frames\n", magick->n_frames); +#endif /*DEBUG*/ + + if (magick->n != -1) + magick->n_frames = VIPS_MIN(magick->n_frames, magick->n); + + /* So we can finally set the height. + */ + if (magick->n_frames > 1) { + vips_image_set_int(out, VIPS_META_PAGE_HEIGHT, out->Ysize); + out->Ysize *= magick->n_frames; + } + + vips_image_set_int(out, VIPS_META_N_PAGES, magick->n_pages); + + vips_image_set_int(out, VIPS_META_ORIENTATION, + VIPS_CLIP(1, image->orientation, 8)); + + vips_image_set_int(out, VIPS_META_BITS_PER_SAMPLE, depth); + + return 0; +} + +/* Divide by this to get 0 - MAX from a Quantum. Eg. consider QuantumRange == + * 65535, MAX == 255 (a Q16 ImageMagic representing an 8-bit image). Make sure + * this can't be zero (if QuantumRange < MAX) .. can happen if we have a Q8 + * ImageMagick trying to represent a 16-bit image. + */ +#define SCALE(MAX) \ + (QuantumRange < (MAX) \ + ? 1 \ + : ((QuantumRange + 1) / ((MAX) + 1))) + +#define GRAY_LOOP(TYPE, MAX) \ + { \ + TYPE *q = (TYPE *) q8; \ +\ + for (x = 0; x < n; x++) \ + q[x] = pixels[x].green / SCALE(MAX); \ + } + +#define GRAYA_LOOP(TYPE, MAX) \ + { \ + TYPE *q = (TYPE *) q8; \ +\ + for (x = 0; x < n; x++) { \ + q[0] = pixels[x].green / SCALE(MAX); \ + q[1] = MAX - pixels[x].opacity / SCALE(MAX); \ +\ + q += 2; \ + } \ + } + +#define RGB_LOOP(TYPE, MAX) \ + { \ + TYPE *q = (TYPE *) q8; \ +\ + for (x = 0; x < n; x++) { \ + q[0] = pixels[x].red / SCALE(MAX); \ + q[1] = pixels[x].green / SCALE(MAX); \ + q[2] = pixels[x].blue / SCALE(MAX); \ +\ + q += 3; \ + } \ + } + +#define RGBA_LOOP(TYPE, MAX) \ + { \ + TYPE *q = (TYPE *) q8; \ +\ + for (x = 0; x < n; x++) { \ + q[0] = pixels[x].red / SCALE(MAX); \ + q[1] = pixels[x].green / SCALE(MAX); \ + q[2] = pixels[x].blue / SCALE(MAX); \ + q[3] = MAX - pixels[x].opacity / SCALE(MAX); \ +\ + q += 4; \ + } \ + } + +static void +unpack_pixels(VipsImage *im, VipsPel *q8, PixelPacket *pixels, int n) +{ + int x; + + switch (im->Bands) { + case 1: + /* Gray. + */ + switch (im->BandFmt) { + case VIPS_FORMAT_UCHAR: + GRAY_LOOP(unsigned char, 255); + break; + case VIPS_FORMAT_USHORT: + GRAY_LOOP(unsigned short, 65535); + break; + case VIPS_FORMAT_UINT: + GRAY_LOOP(unsigned int, 4294967295UL); + break; + case VIPS_FORMAT_DOUBLE: + GRAY_LOOP(double, QuantumRange); + break; + + default: + g_assert_not_reached(); + } + break; + + case 2: + /* Gray plus alpha. + */ + switch (im->BandFmt) { + case VIPS_FORMAT_UCHAR: + GRAYA_LOOP(unsigned char, 255); + break; + case VIPS_FORMAT_USHORT: + GRAYA_LOOP(unsigned short, 65535); + break; + case VIPS_FORMAT_UINT: + GRAYA_LOOP(unsigned int, 4294967295UL); + break; + case VIPS_FORMAT_DOUBLE: + GRAYA_LOOP(double, QuantumRange); + break; + + default: + g_assert_not_reached(); + } + break; + + case 3: + /* RGB. + */ + switch (im->BandFmt) { + case VIPS_FORMAT_UCHAR: + RGB_LOOP(unsigned char, 255); + break; + case VIPS_FORMAT_USHORT: + RGB_LOOP(unsigned short, 65535); + break; + case VIPS_FORMAT_UINT: + RGB_LOOP(unsigned int, 4294967295UL); + break; + case VIPS_FORMAT_DOUBLE: + RGB_LOOP(double, QuantumRange); + break; + + default: + g_assert_not_reached(); + } + break; + + case 4: + /* RGBA or CMYK. + */ + switch (im->BandFmt) { + case VIPS_FORMAT_UCHAR: + RGBA_LOOP(unsigned char, 255); + break; + case VIPS_FORMAT_USHORT: + RGBA_LOOP(unsigned short, 65535); + break; + case VIPS_FORMAT_UINT: + RGBA_LOOP(unsigned int, 4294967295UL); + break; + case VIPS_FORMAT_DOUBLE: + RGBA_LOOP(double, QuantumRange); + break; + + default: + g_assert_not_reached(); + } + break; + + default: + g_assert_not_reached(); + } +} + +static PixelPacket * +get_pixels(Image *image, int left, int top, int width, int height) +{ + PixelPacket *pixels; + +#ifdef HAVE_GETVIRTUALPIXELS + if (!(pixels = (PixelPacket *) GetVirtualPixels(image, + left, top, width, height, &image->exception))) +#else + if (!(pixels = GetImagePixels(image, left, top, width, height))) +#endif + return NULL; + + /* Can't happen if red/green/blue are doubles. + */ +#ifndef UseHDRI + /* Unpack palette. + */ + if (image->storage_class == PseudoClass) { +#ifdef HAVE_GETVIRTUALPIXELS + IndexPacket *indexes = (IndexPacket *) + GetVirtualIndexQueue(image); +#else + /* Was GetIndexes(), but that's now deprecated. + */ + IndexPacket *indexes = AccessMutableIndexes(image); +#endif + + int i; + + for (i = 0; i < width * height; i++) { + IndexPacket x = indexes[i]; + + if (x < image->colors) { + pixels[i].red = image->colormap[x].red; + pixels[i].green = image->colormap[x].green; + pixels[i].blue = image->colormap[x].blue; + } + } + } +#endif /*UseHDRI*/ + + return pixels; +} + +static int +vips_foreign_load_magick_fill_region(VipsRegion *out_region, + void *seq, void *a, void *b, gboolean *stop) +{ + VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) a; + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(magick); + VipsRect *r = &out_region->valid; + VipsImage *im = out_region->im; + + int y; + + for (y = 0; y < r->height; y++) { + int top = r->top + y; + int frame = top / magick->frame_height; + int line = top % magick->frame_height; + + PixelPacket *pixels; + + vips__worker_lock(magick->lock); + + pixels = get_pixels(magick->frames[frame], + r->left, line, r->width, 1); + + g_mutex_unlock(magick->lock); + + if (!pixels) { + vips_foreign_load_invalidate(im); + vips_error(class->nickname, + "%s", _("unable to read pixels")); + return -1; + } + + unpack_pixels(im, VIPS_REGION_ADDR(out_region, r->left, top), + pixels, r->width); + } + + return 0; +} + +static int +vips_foreign_load_magick_load(VipsForeignLoadMagick *magick) +{ + VipsForeignLoad *load = (VipsForeignLoad *) magick; + + Image *p; + int i; + +#ifdef DEBUG + printf("vips_foreign_load_magick_load: %p\n", magick); +#endif /*DEBUG*/ + + if (vips_foreign_load_magick_parse(magick, + magick->image, load->out)) + return -1; + + /* Record frame pointers. + */ + g_assert(!magick->frames); + if (!(magick->frames = + VIPS_ARRAY(NULL, magick->n_frames, Image *))) + return -1; + p = magick->image; + for (i = 0; i < magick->n_frames; i++) { + magick->frames[i] = p; + p = GetNextImageInList(p); + } + + if (vips_image_generate(load->out, + NULL, vips_foreign_load_magick_fill_region, NULL, + magick, NULL)) + return -1; + + return 0; +} + typedef struct _VipsForeignLoadMagickFile { VipsForeignLoadMagick parent_object; @@ -200,18 +937,30 @@ static int vips_foreign_load_magick_file_header(VipsForeignLoad *load) { VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) load; - VipsForeignLoadMagickFile *magick_file = - (VipsForeignLoadMagickFile *) load; + VipsForeignLoadMagickFile *file = (VipsForeignLoadMagickFile *) load; + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(magick); - if (magick->all_frames) - magick->n = -1; // FIXME: Invalidates operation cache +#ifdef DEBUG + printf("vips_foreign_load_magick_file_header: %p\n", load); +#endif /*DEBUG*/ + + g_strlcpy(magick->image_info->filename, file->filename, + MaxTextExtent); + + magick_sniff_file(magick->image_info, file->filename); - if (vips__magick_read(magick_file->filename, - load->out, magick->density, - magick->page, magick->n)) + magick->image = ReadImage(magick->image_info, magick->exception); + if (!magick->image) { + magick_vips_error(class->nickname, magick->exception); + vips_error(class->nickname, + _("unable to read file \"%s\""), file->filename); return -1; + } - VIPS_SETSTR(load->out->filename, magick_file->filename); + if (vips_foreign_load_magick_load(magick)) + return -1; + + VIPS_SETSTR(load->out->filename, file->filename); return 0; } @@ -232,7 +981,6 @@ vips_foreign_load_magick_file_class_init( load_class->is_a = ismagick; load_class->header = vips_foreign_load_magick_file_header; - load_class->load = NULL; VIPS_ARG_STRING(class, "filename", 1, _("Filename"), @@ -278,14 +1026,28 @@ vips_foreign_load_magick_buffer_header(VipsForeignLoad *load) VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) load; VipsForeignLoadMagickBuffer *magick_buffer = (VipsForeignLoadMagickBuffer *) load; + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(magick); - if (magick->all_frames) - magick->n = -1; // FIXME: Invalidates operation cache +#ifdef DEBUG + printf("vips_foreign_load_magick_buffer_header: %p\n", load); +#endif /*DEBUG*/ + + /* It would be great if we could PingImage and just read the header, + * but sadly many IM coders do not support ping. The critical one for + * us is DICOM. TGA also has issues. + */ + magick_sniff_bytes(magick->image_info, + magick_buffer->buf->data, magick_buffer->buf->length); + magick->image = BlobToImage(magick->image_info, + magick_buffer->buf->data, magick_buffer->buf->length, + magick->exception); + if (!magick->image) { + magick_vips_error(class->nickname, magick->exception); + vips_error(class->nickname, _("unable to read buffer")); + return -1; + } - if (vips__magick_read_buffer( - magick_buffer->buf->data, magick_buffer->buf->length, - load->out, magick->density, magick->page, - magick->n)) + if (vips_foreign_load_magick_load(magick)) return -1; return 0; @@ -307,7 +1069,6 @@ vips_foreign_load_magick_buffer_class_init( load_class->is_a_buffer = vips_foreign_load_magick_buffer_is_a_buffer; load_class->header = vips_foreign_load_magick_buffer_header; - load_class->load = NULL; VIPS_ARG_BOXED(class, "buffer", 1, _("Buffer"), diff --git a/libvips/foreign/meson.build b/libvips/foreign/meson.build index 23874be308..1a280acbae 100644 --- a/libvips/foreign/meson.build +++ b/libvips/foreign/meson.build @@ -73,7 +73,6 @@ foreign_headers = files( # if it is not built as a dynamically loadable module. magick_module_sources = files( 'magick.c', - 'magick2vips.c', 'magick6load.c', 'magick7load.c', 'vips2magick.c', From fd1ec8a6502a17c7cf6f002da9a159e8bcd759a8 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Mon, 17 Mar 2025 14:34:06 +0000 Subject: [PATCH 080/174] convi: ensure double sum precision when multiplying floats (#4418) --- ChangeLog | 1 + libvips/convolution/convi.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8d81352d1f..c2f546f3bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,7 @@ - svgload: add support for custom CSS via stylesheet option [lovell] - heifload: `unlimited` flag removes all limits (requires libheif 1.19.0+) [lovell] - heifsave: improve alpha channel detection [lovell] +- convi: ensure double sum precision for floats [lovell] 8.16.1 diff --git a/libvips/convolution/convi.c b/libvips/convolution/convi.c index f44cc72819..bfa36ffa20 100644 --- a/libvips/convolution/convi.c +++ b/libvips/convolution/convi.c @@ -728,7 +728,7 @@ vips_convi_gen_vector(VipsRegion *out_region, \ sum = 0; \ for (i = 0; i < nnz; i++) \ - sum += t[i] * p[offsets[i]]; \ + sum += (double) t[i] * p[offsets[i]]; \ \ sum = (sum / scale) + offset; \ \ From f3b712f059c894f83867332ecc4bdff06b415a18 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Tue, 18 Mar 2025 14:46:30 +0000 Subject: [PATCH 081/174] dzsave: ensure IIIF scaleFactors includes all levels (#4421) LGTM! what a silly error :( --- libvips/foreign/dzsave.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index 7f4fefea0a..b331c5dd1c 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -776,11 +776,11 @@ write_json(VipsForeignSaveDz *dz) " {\n" " \"scaleFactors\": [\n"); - for (i = 0; i < dz->level->n; i++) { + for (i = 0; i <= dz->level->n; i++) { vips_dbuf_writef(&dbuf, " %d", 1 << i); - if (i != dz->level->n - 1) + if (i != dz->level->n) vips_dbuf_writef(&dbuf, ","); vips_dbuf_writef(&dbuf, "\n"); } From ad790cda5b2510e006197c33696a12cb6786c025 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 20 Mar 2025 09:49:22 +0000 Subject: [PATCH 082/174] minor reformat --- libvips/iofuncs/sinkscreen.c | 48 ++++++++++++------------------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/libvips/iofuncs/sinkscreen.c b/libvips/iofuncs/sinkscreen.c index f719d0e5ae..a7b1ea3f4a 100644 --- a/libvips/iofuncs/sinkscreen.c +++ b/libvips/iofuncs/sinkscreen.c @@ -205,8 +205,7 @@ render_thread_state_init(RenderThreadState *state) static VipsThreadState * render_thread_state_new(VipsImage *im, void *a) { - return VIPS_THREAD_STATE(vips_object_new( - render_thread_state_get_type(), + return VIPS_THREAD_STATE(vips_object_new(render_thread_state_get_type(), vips_thread_state_set, im, a)); } @@ -341,8 +340,7 @@ render_tile_dirty_reuse(Render *render) g_assert(tile->dirty); tile->dirty = FALSE; - VIPS_DEBUG_MSG("render_tile_get_dirty_reuse: reusing dirty %p\n", - tile); + VIPS_DEBUG_MSG("render_tile_get_dirty_reuse: reusing dirty %p\n", tile); } return tile; @@ -419,8 +417,7 @@ render_work(VipsThreadState *state, void *a) if (vips_region_prepare_to(state->reg, tile->region, &tile->area, tile->area.left, tile->area.top)) { - VIPS_DEBUG_MSG_RED("render_work: " - "vips_region_prepare_to() failed: %s\n", + VIPS_DEBUG_MSG_RED("render_work: vips_region_prepare_to() failed: %s\n", vips_error_buffer()); return -1; } @@ -476,8 +473,7 @@ render_dirty_put(Render *render) if (render->dirty) { if (!g_slist_find(render_dirty_all, render)) { - render_dirty_all = g_slist_prepend(render_dirty_all, - render); + render_dirty_all = g_slist_prepend(render_dirty_all, render); render_dirty_all = g_slist_sort(render_dirty_all, (GCompareFunc) render_dirty_sort); @@ -583,12 +579,10 @@ render_new(VipsImage *in, VipsImage *out, VipsImage *mask, /* Both out and mask must close before we can free the render. */ - g_signal_connect(out, "close", - G_CALLBACK(render_close_cb), render); + g_signal_connect(out, "close", G_CALLBACK(render_close_cb), render); if (mask) { - g_signal_connect(mask, "close", - G_CALLBACK(render_close_cb), render); + g_signal_connect(mask, "close", G_CALLBACK(render_close_cb), render); render_ref(render); } @@ -760,13 +754,10 @@ render_tile_get_painted(Render *render) Tile *tile; tile = NULL; - g_hash_table_foreach(render->tiles, - (GHFunc) tile_test_clean_ticks, &tile); + g_hash_table_foreach(render->tiles, (GHFunc) tile_test_clean_ticks, &tile); - if (tile) { - VIPS_DEBUG_MSG("render_tile_get_painted: reusing painted %p\n", - tile); - } + if (tile) + VIPS_DEBUG_MSG("render_tile_get_painted: reusing painted %p\n", tile); return tile; } @@ -845,8 +836,7 @@ tile_copy(Tile *tile, VipsRegion *to) tile, tile->area.left, tile->area.top); for (y = ovlap.top; y < VIPS_RECT_BOTTOM(&ovlap); y++) { - VipsPel *p = VIPS_REGION_ADDR(tile->region, - ovlap.left, y); + VipsPel *p = VIPS_REGION_ADDR(tile->region, ovlap.left, y); VipsPel *q = VIPS_REGION_ADDR(to, ovlap.left, y); memcpy(q, p, len); @@ -877,8 +867,7 @@ image_fill(VipsRegion *out, void *seq, void *a, void *b, gboolean *stop) int xs = (r->left / tile_width) * tile_width; int ys = (r->top / tile_height) * tile_height; - VIPS_DEBUG_MSG("image_fill: left = %d, top = %d, " - "width = %d, height = %d\n", + VIPS_DEBUG_MSG("image_fill: left = %d, top = %d, width = %d, height = %d\n", r->left, r->top, r->width, r->height); g_mutex_lock(render->lock); @@ -929,8 +918,7 @@ mask_fill(VipsRegion *out, void *seq, void *a, void *b, gboolean *stop) int xs = (r->left / tile_width) * tile_width; int ys = (r->top / tile_height) * tile_height; - VIPS_DEBUG_MSG("mask_fill: left = %d, top = %d, " - "width = %d, height = %d\n", + VIPS_DEBUG_MSG("mask_fill: left = %d, top = %d, width = %d, height = %d\n", r->left, r->top, r->width, r->height); g_mutex_lock(render->lock); @@ -1048,8 +1036,7 @@ vips__sink_screen_once(void *data) /* Don't use vips_thread_execute(), since this thread will only be * ended by vips_shutdown, and that isn't always called. */ - render_thread = vips_g_thread_new("sink_screen", - render_thread_main, NULL); + render_thread = vips_g_thread_new("sink_screen", render_thread_main, NULL); return NULL; } @@ -1124,13 +1111,11 @@ vips_sink_screen(VipsImage *in, VipsImage *out, VipsImage *mask, } if (vips_image_pio_input(in) || - vips_image_pipelinev(out, - VIPS_DEMAND_STYLE_SMALLTILE, in, NULL)) + vips_image_pipelinev(out, VIPS_DEMAND_STYLE_SMALLTILE, in, NULL)) return -1; if (mask) { - if (vips_image_pipelinev(mask, - VIPS_DEMAND_STYLE_SMALLTILE, in, NULL)) + if (vips_image_pipelinev(mask, VIPS_DEMAND_STYLE_SMALLTILE, in, NULL)) return -1; mask->Bands = 1; @@ -1149,8 +1134,7 @@ vips_sink_screen(VipsImage *in, VipsImage *out, VipsImage *mask, vips_start_one, image_fill, vips_stop_one, in, render)) return -1; if (mask && - vips_image_generate(mask, - NULL, mask_fill, NULL, render, NULL)) + vips_image_generate(mask, NULL, mask_fill, NULL, render, NULL)) return -1; return 0; From 7e2b786c431c9a0a39ea80ffa6afa42e5df5589d Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 20 Mar 2025 14:36:09 +0100 Subject: [PATCH 083/174] Deprecate `GCond` and `GMutex` compat layer (#4249) * Deprecate `GCond` and `GMutex` compat layer * semaphore: ensure ABI compatibility Changing `GCond *` to `GCond` in public structures would break ABI compatibility, at least when building against GLib 2.x. See: https://gitlab.gnome.org/GNOME/glib/-/issues/1256. --- libvips/conversion/sequential.c | 16 +++++----- libvips/conversion/tilecache.c | 32 ++++++++++---------- libvips/deprecated/im_exr2vips.c | 1 - libvips/deprecated/im_nifti2vips.c | 1 - libvips/deprecated/im_openslide2vips.c | 1 - libvips/deprecated/im_tiff2vips.c | 1 - libvips/deprecated/rename.c | 36 ++++++++++++++++++++++ libvips/foreign/fits.c | 19 +++++------- libvips/foreign/magick6load.c | 10 +++---- libvips/foreign/magick7load.c | 10 +++---- libvips/foreign/openexr2vips.c | 1 - libvips/foreign/tiff2vips.c | 1 - libvips/foreign/vips2tiff.c | 10 +++---- libvips/include/vips/almostdeprecated.h | 10 +++++++ libvips/include/vips/image.h | 2 +- libvips/include/vips/semaphore.h | 9 ++++-- libvips/include/vips/thread.h | 17 +---------- libvips/include/vips/type.h | 2 +- libvips/include/vips/vips.h | 1 + libvips/iofuncs/buffer.c | 1 - libvips/iofuncs/error.c | 1 - libvips/iofuncs/generate.c | 1 - libvips/iofuncs/image.c | 8 ++--- libvips/iofuncs/init.c | 1 - libvips/iofuncs/memory.c | 1 - libvips/iofuncs/region.c | 25 ++++++++-------- libvips/iofuncs/semaphore.c | 26 ++++++++-------- libvips/iofuncs/sink.c | 1 - libvips/iofuncs/sink.h | 1 - libvips/iofuncs/sinkdisc.c | 2 -- libvips/iofuncs/sinkmemory.c | 2 -- libvips/iofuncs/sinkscreen.c | 37 +++++++++++------------ libvips/iofuncs/thread.c | 40 ------------------------- libvips/iofuncs/threadpool.c | 23 +++++++------- libvips/iofuncs/threadset.c | 1 - libvips/iofuncs/type.c | 18 +++++------ libvips/iofuncs/window.c | 19 ++++++------ libvips/mosaicing/lrmerge.c | 19 ++++++------ libvips/mosaicing/pmosaicing.h | 2 +- libvips/mosaicing/tbmerge.c | 11 ++++--- 40 files changed, 194 insertions(+), 226 deletions(-) diff --git a/libvips/conversion/sequential.c b/libvips/conversion/sequential.c index 07860f235b..da114e449a 100644 --- a/libvips/conversion/sequential.c +++ b/libvips/conversion/sequential.c @@ -84,7 +84,7 @@ typedef struct _VipsSequential { /* Lock access to y_pos with this. */ - GMutex *lock; + GMutex lock; /* The next read from our source will fetch this scanline, ie. it's 0 * when we start. @@ -106,7 +106,7 @@ vips_sequential_dispose(GObject *gobject) { VipsSequential *sequential = (VipsSequential *) gobject; - VIPS_FREEF(vips_g_mutex_free, sequential->lock); + g_mutex_clear(&sequential->lock); G_OBJECT_CLASS(vips_sequential_parent_class)->dispose(gobject); } @@ -126,14 +126,14 @@ vips_sequential_generate(VipsRegion *out_region, VIPS_GATE_START("vips_sequential_generate: wait"); - vips__worker_lock(sequential->lock); + vips__worker_lock(&sequential->lock); VIPS_GATE_STOP("vips_sequential_generate: wait"); /* If we've seen an error, everything must stop. */ if (sequential->error) { - g_mutex_unlock(sequential->lock); + g_mutex_unlock(&sequential->lock); return -1; } @@ -157,7 +157,7 @@ vips_sequential_generate(VipsRegion *out_region, area.height = VIPS_MIN(sequential->tile_height, r->top - area.top); if (vips_region_prepare(ir, &area)) { sequential->error = -1; - g_mutex_unlock(sequential->lock); + g_mutex_unlock(&sequential->lock); return -1; } @@ -172,13 +172,13 @@ vips_sequential_generate(VipsRegion *out_region, if (vips_region_prepare(ir, r) || vips_region_region(out_region, ir, r, r->left, r->top)) { sequential->error = -1; - g_mutex_unlock(sequential->lock); + g_mutex_unlock(&sequential->lock); return -1; } sequential->y_pos = VIPS_MAX(sequential->y_pos, VIPS_RECT_BOTTOM(r)); - g_mutex_unlock(sequential->lock); + g_mutex_unlock(&sequential->lock); return 0; } @@ -270,7 +270,7 @@ vips_sequential_class_init(VipsSequentialClass *class) static void vips_sequential_init(VipsSequential *sequential) { - sequential->lock = vips_g_mutex_new(); + g_mutex_init(&sequential->lock); sequential->tile_height = 1; sequential->error = 0; sequential->trace = FALSE; diff --git a/libvips/conversion/tilecache.c b/libvips/conversion/tilecache.c index c601bc04f8..ba308050fb 100644 --- a/libvips/conversion/tilecache.c +++ b/libvips/conversion/tilecache.c @@ -129,8 +129,8 @@ typedef struct _VipsBlockCache { gboolean threaded; gboolean persistent; - GMutex *lock; /* Lock everything here */ - GCond *new_tile; /* A new tile is ready */ + GMutex lock; /* Lock everything here */ + GCond new_tile; /* A new tile is ready */ GHashTable *tiles; /* Tiles, hashed by coordinates */ GQueue *recycle; /* Queue of unreffed tiles to reuse */ } VipsBlockCache; @@ -158,8 +158,8 @@ vips_block_cache_dispose(GObject *gobject) VipsBlockCache *cache = (VipsBlockCache *) gobject; vips_block_cache_drop_all(cache); - VIPS_FREEF(vips_g_mutex_free, cache->lock); - VIPS_FREEF(vips_g_cond_free, cache->new_tile); + g_mutex_clear(&cache->lock); + g_cond_clear(&cache->new_tile); if (cache->tiles) g_assert(g_hash_table_size(cache->tiles) == 0); @@ -342,14 +342,14 @@ vips_block_cache_minimise(VipsImage *image, VipsBlockCache *cache) { VIPS_DEBUG_MSG("vips_block_cache_minimise:\n"); - g_mutex_lock(cache->lock); + g_mutex_lock(&cache->lock); /* We can't drop tiles that are in use. */ g_hash_table_foreach_remove(cache->tiles, vips_tile_unlocked, NULL); - g_mutex_unlock(cache->lock); + g_mutex_unlock(&cache->lock); } static int @@ -481,8 +481,8 @@ vips_block_cache_init(VipsBlockCache *cache) cache->threaded = FALSE; cache->persistent = FALSE; - cache->lock = vips_g_mutex_new(); - cache->new_tile = vips_g_cond_new(); + g_mutex_init(&cache->lock); + g_cond_init(&cache->new_tile); cache->tiles = g_hash_table_new_full( (GHashFunc) vips_rect_hash, (GEqualFunc) vips_rect_equal, @@ -615,7 +615,7 @@ vips_tile_cache_gen(VipsRegion *out_region, VIPS_GATE_START("vips_tile_cache_gen: wait1"); - vips__worker_lock(cache->lock); + vips__worker_lock(&cache->lock); VIPS_GATE_STOP("vips_tile_cache_gen: wait1"); @@ -674,7 +674,7 @@ vips_tile_cache_gen(VipsRegion *out_region, * mode, we keep the lock and make 'em wait. */ if (cache->threaded) - g_mutex_unlock(cache->lock); + g_mutex_unlock(&cache->lock); /* Don't compute if we've seen an error * previously. @@ -688,7 +688,7 @@ vips_tile_cache_gen(VipsRegion *out_region, if (cache->threaded) { VIPS_GATE_START("vips_tile_cache_gen: wait2"); - g_mutex_lock(cache->lock); + g_mutex_lock(&cache->lock); VIPS_GATE_STOP("vips_tile_cache_gen: wait2"); } @@ -718,7 +718,7 @@ vips_tile_cache_gen(VipsRegion *out_region, /* Let everyone know there's a new DATA tile. * They need to all check their work lists. */ - g_cond_broadcast(cache->new_tile); + g_cond_broadcast(&cache->new_tile); break; } @@ -741,7 +741,7 @@ vips_tile_cache_gen(VipsRegion *out_region, VIPS_GATE_START("vips_tile_cache_gen: wait3"); - vips__worker_cond_wait(cache->new_tile, cache->lock); + vips__worker_cond_wait(&cache->new_tile, &cache->lock); VIPS_GATE_STOP("vips_tile_cache_gen: wait3"); @@ -749,7 +749,7 @@ vips_tile_cache_gen(VipsRegion *out_region, } } - g_mutex_unlock(cache->lock); + g_mutex_unlock(&cache->lock); return result; } @@ -889,7 +889,7 @@ vips_line_cache_gen(VipsRegion *out_region, VIPS_GATE_START("vips_line_cache_gen: wait"); - vips__worker_lock(block_cache->lock); + vips__worker_lock(&block_cache->lock); VIPS_GATE_STOP("vips_line_cache_gen: wait"); @@ -903,7 +903,7 @@ vips_line_cache_gen(VipsRegion *out_region, block_cache->max_tiles); } - g_mutex_unlock(block_cache->lock); + g_mutex_unlock(&block_cache->lock); return vips_tile_cache_gen(out_region, seq, a, b, stop); } diff --git a/libvips/deprecated/im_exr2vips.c b/libvips/deprecated/im_exr2vips.c index 5b8e0298f1..3bff896312 100644 --- a/libvips/deprecated/im_exr2vips.c +++ b/libvips/deprecated/im_exr2vips.c @@ -46,7 +46,6 @@ #include #include -#include #include #include "../foreign/pforeign.h" diff --git a/libvips/deprecated/im_nifti2vips.c b/libvips/deprecated/im_nifti2vips.c index c16146cf7f..895f52b5e4 100644 --- a/libvips/deprecated/im_nifti2vips.c +++ b/libvips/deprecated/im_nifti2vips.c @@ -46,7 +46,6 @@ #include #include -#include #include static int diff --git a/libvips/deprecated/im_openslide2vips.c b/libvips/deprecated/im_openslide2vips.c index 2e582e3a32..295b927eee 100644 --- a/libvips/deprecated/im_openslide2vips.c +++ b/libvips/deprecated/im_openslide2vips.c @@ -50,7 +50,6 @@ #include #include -#include #include static int diff --git a/libvips/deprecated/im_tiff2vips.c b/libvips/deprecated/im_tiff2vips.c index ff8977bb4e..cb0f4f929b 100644 --- a/libvips/deprecated/im_tiff2vips.c +++ b/libvips/deprecated/im_tiff2vips.c @@ -47,7 +47,6 @@ #include #include -#include #include "../foreign/pforeign.h" diff --git a/libvips/deprecated/rename.c b/libvips/deprecated/rename.c index dd638530bb..0e8d2affcd 100644 --- a/libvips/deprecated/rename.c +++ b/libvips/deprecated/rename.c @@ -128,6 +128,42 @@ im_warning(const char *fmt, ...) va_end(ap); } +GMutex * +vips_g_mutex_new(void) +{ + GMutex *mutex; + + mutex = g_new(GMutex, 1); + g_mutex_init(mutex); + + return mutex; +} + +void +vips_g_mutex_free(GMutex *mutex) +{ + g_mutex_clear(mutex); + g_free(mutex); +} + +GCond * +vips_g_cond_new(void) +{ + GCond *cond; + + cond = g_new(GCond, 1); + g_cond_init(cond); + + return cond; +} + +void +vips_g_cond_free(GCond *cond) +{ + g_cond_clear(cond); + g_free(cond); +} + void * vips_g_thread_join(GThread *thread) { diff --git a/libvips/foreign/fits.c b/libvips/foreign/fits.c index 49f1ff958d..fb1a444c73 100644 --- a/libvips/foreign/fits.c +++ b/libvips/foreign/fits.c @@ -109,7 +109,7 @@ typedef struct { int naxis; long long int naxes[MAX_DIMENSIONS]; - GMutex *lock; /* Lock fits_*() calls with this */ + GMutex lock; /* Lock fits_*() calls with this */ /* One line of pels ready for scatter/gather. */ @@ -139,7 +139,8 @@ static void vips_fits_close(VipsFits *fits) { VIPS_FREE(fits->filename); - VIPS_FREEF(vips_g_mutex_free, fits->lock); + if (fits->line) + g_mutex_clear(&fits->lock); VIPS_FREEF(vips_slist_free_all, fits->dedupe); if (fits->fptr) { @@ -174,7 +175,7 @@ vips_fits_new_read(const char *filename, VipsImage *out) fits->filename = vips_strdup(NULL, filename); fits->image = out; fits->fptr = NULL; - fits->lock = NULL; + g_mutex_init(&fits->lock); fits->line = NULL; g_signal_connect(out, "close", G_CALLBACK(vips_fits_close_cb), fits); @@ -186,8 +187,6 @@ vips_fits_new_read(const char *filename, VipsImage *out) return NULL; } - fits->lock = vips_g_mutex_new(); - return fits; } @@ -465,7 +464,7 @@ vips_fits_generate(VipsRegion *out, "generating left = %d, top = %d, width = %d, height = %d\n", r->left, r->top, r->width, r->height); - vips__worker_lock(fits->lock); + vips__worker_lock(&fits->lock); for (int w = 0; w < out->im->Bands; w++) { for (int y = r->top; y < VIPS_RECT_BOTTOM(r); y++) { @@ -492,7 +491,7 @@ vips_fits_generate(VipsRegion *out, */ if (vips_fits_read_subset(fits, fpixel, lpixel, inc, fits->line)) { - g_mutex_unlock(fits->lock); + g_mutex_unlock(&fits->lock); return -1; } @@ -502,7 +501,7 @@ vips_fits_generate(VipsRegion *out, } } - g_mutex_unlock(fits->lock); + g_mutex_unlock(&fits->lock); return 0; } @@ -561,7 +560,7 @@ vips_fits_new_write(VipsImage *in, const char *filename) fits->filename = vips_strdup(VIPS_OBJECT(in), filename); fits->image = in; fits->fptr = NULL; - fits->lock = NULL; + g_mutex_init(&fits->lock); fits->line = NULL; g_signal_connect(in, "close", G_CALLBACK(vips_fits_close_cb), fits); @@ -588,8 +587,6 @@ vips_fits_new_write(VipsImage *in, const char *filename) return NULL; } - fits->lock = vips_g_mutex_new(); - return fits; } diff --git a/libvips/foreign/magick6load.c b/libvips/foreign/magick6load.c index bf1a63ae8e..c57d509b01 100644 --- a/libvips/foreign/magick6load.c +++ b/libvips/foreign/magick6load.c @@ -171,7 +171,7 @@ typedef struct _VipsForeignLoadMagick { /* Mutex to serialise calls to libMagick during threaded read. */ - GMutex *lock; + GMutex lock; } VipsForeignLoadMagick; @@ -205,7 +205,7 @@ vips_foreign_load_magick_dispose(GObject *gobject) VIPS_FREEF(DestroyImageInfo, magick->image_info); VIPS_FREE(magick->frames); VIPS_FREEF(magick_destroy_exception, magick->exception); - VIPS_FREEF(vips_g_mutex_free, magick->lock); + g_mutex_clear(&magick->lock); G_OBJECT_CLASS(vips_foreign_load_magick_parent_class)->dispose(gobject); } @@ -223,7 +223,7 @@ vips_foreign_load_magick_build(VipsObject *object) magick->image_info = CloneImageInfo(NULL); magick->exception = magick_acquire_exception(); - magick->lock = vips_g_mutex_new(); + g_mutex_init(&magick->lock); if (!magick->image_info) return -1; @@ -845,12 +845,12 @@ vips_foreign_load_magick_fill_region(VipsRegion *out_region, PixelPacket *pixels; - vips__worker_lock(magick->lock); + vips__worker_lock(&magick->lock); pixels = get_pixels(magick->frames[frame], r->left, line, r->width, 1); - g_mutex_unlock(magick->lock); + g_mutex_unlock(&magick->lock); if (!pixels) { vips_foreign_load_invalidate(im); diff --git a/libvips/foreign/magick7load.c b/libvips/foreign/magick7load.c index 0dc7bd0716..02ee0b39b0 100644 --- a/libvips/foreign/magick7load.c +++ b/libvips/foreign/magick7load.c @@ -92,7 +92,7 @@ typedef struct _VipsForeignLoadMagick7 { /* Mutex to serialise calls to libMagick during threaded read. */ - GMutex *lock; + GMutex lock; } VipsForeignLoadMagick7; @@ -286,7 +286,7 @@ vips_foreign_load_magick7_dispose(GObject *gobject) VIPS_FREE(magick7->frames); VIPS_FREE(magick7->cache_view); VIPS_FREEF(magick_destroy_exception, magick7->exception); - VIPS_FREEF(vips_g_mutex_free, magick7->lock); + g_mutex_clear(&magick7->lock); G_OBJECT_CLASS(vips_foreign_load_magick7_parent_class)->dispose(gobject); } @@ -304,7 +304,7 @@ vips_foreign_load_magick7_build(VipsObject *object) magick7->image_info = CloneImageInfo(NULL); magick7->exception = magick_acquire_exception(); - magick7->lock = vips_g_mutex_new(); + g_mutex_init(&magick7->lock); if (!magick7->image_info) return -1; @@ -675,13 +675,13 @@ vips_foreign_load_magick7_fill_region(VipsRegion *out_region, Quantum *restrict p; VipsPel *restrict q; - vips__worker_lock(magick7->lock); + vips__worker_lock(&magick7->lock); p = GetCacheViewAuthenticPixels(magick7->cache_view[frame], r->left, line, r->width, 1, magick7->exception); - g_mutex_unlock(magick7->lock); + g_mutex_unlock(&magick7->lock); if (!p) /* This can happen if, for example, some frames of a diff --git a/libvips/foreign/openexr2vips.c b/libvips/foreign/openexr2vips.c index bd0677ffe7..e3e1637494 100644 --- a/libvips/foreign/openexr2vips.c +++ b/libvips/foreign/openexr2vips.c @@ -83,7 +83,6 @@ #include #include -#include #include #include diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index 2aaae395d0..718678f0a7 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -261,7 +261,6 @@ #include #include -#include #include "pforeign.h" #include "tiff.h" diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 91a507e857..89f23930c1 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -393,7 +393,7 @@ struct _Wtiff { /* Lock thread calls into libtiff with this. */ - GMutex *lock; + GMutex lock; }; /* Write an ICC Profile from a file into the JPEG stream. @@ -1223,7 +1223,7 @@ wtiff_free(Wtiff *wtiff) VIPS_UNREF(wtiff->ready); VIPS_FREE(wtiff->tbuf); - VIPS_FREEF(vips_g_mutex_free, wtiff->lock); + g_mutex_clear(&wtiff->lock); VIPS_FREE(wtiff); } @@ -1390,7 +1390,7 @@ wtiff_new(VipsImage *input, VipsTarget *target, wtiff->page_number = 0; wtiff->n_pages = 1; wtiff->image_height = input->Ysize; - wtiff->lock = vips_g_mutex_new(); + g_mutex_init(&wtiff->lock); /* Any pre-processing on the image. */ @@ -1784,11 +1784,11 @@ wtiff_row_add_tile(WtiffRow *row, tile->buffer = buffer; tile->length = length; - g_mutex_lock(row->wtiff->lock); + g_mutex_lock(&row->wtiff->lock); row->tiles = g_slist_prepend(row->tiles, tile); - g_mutex_unlock(row->wtiff->lock); + g_mutex_unlock(&row->wtiff->lock); return 0; } diff --git a/libvips/include/vips/almostdeprecated.h b/libvips/include/vips/almostdeprecated.h index e18cb26bde..7fbfb09ab9 100644 --- a/libvips/include/vips/almostdeprecated.h +++ b/libvips/include/vips/almostdeprecated.h @@ -151,6 +151,16 @@ VIPS_DEPRECATED_FOR(g_warning) void im_warning(const char *fmt, ...) G_GNUC_PRINTF(1, 2); +VIPS_DEPRECATED_FOR(g_mutex_init) +GMutex *vips_g_mutex_new(void); +VIPS_DEPRECATED_FOR(g_mutex_clear) +void vips_g_mutex_free(GMutex *); + +VIPS_DEPRECATED_FOR(g_cond_init) +GCond *vips_g_cond_new(void); +VIPS_DEPRECATED_FOR(g_cond_clear) +void vips_g_cond_free(GCond *); + VIPS_DEPRECATED_FOR(g_thread_join) void *vips_g_thread_join(GThread *thread); diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index b5d6752755..cdfe578cc3 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -252,7 +252,7 @@ struct _VipsImage { VipsStopFn stop_fn; void *client1; /* user arguments */ void *client2; - GMutex *sslock; /* start-stop lock */ + GMutex sslock; /* start-stop lock */ GSList *regions; /* list of regions current for this image */ VipsDemandStyle dhint; /* demand style hint */ diff --git a/libvips/include/vips/semaphore.h b/libvips/include/vips/semaphore.h index adab65cd8a..71a7ad8351 100644 --- a/libvips/include/vips/semaphore.h +++ b/libvips/include/vips/semaphore.h @@ -38,8 +38,6 @@ #define VIPS_SEMAPHORE_H #include -#include -#include #ifdef __cplusplus extern "C" { @@ -48,10 +46,15 @@ extern "C" { /* Implement our own semaphores. */ typedef struct { + /*< private >*/ char *name; int v; - GMutex *mutex; + GMutex mutex; + + /* FIXME: sizeof(GCond) != sizeof(GCond *) + * https://gitlab.gnome.org/GNOME/glib/-/issues/1256 + */ GCond *cond; } VipsSemaphore; diff --git a/libvips/include/vips/thread.h b/libvips/include/vips/thread.h index 79f41e213a..cb40d66d65 100644 --- a/libvips/include/vips/thread.h +++ b/libvips/include/vips/thread.h @@ -36,22 +36,7 @@ extern "C" { #endif /*__cplusplus*/ -/* We need wrappers over g_mutex_new(), it was replaced by g_mutex_init() in - * glib 2.32+ - */ -VIPS_API -GMutex *vips_g_mutex_new(void); -VIPS_API -void vips_g_mutex_free(GMutex *); - -/* Same for GCond. - */ -VIPS_API -GCond *vips_g_cond_new(void); -VIPS_API -void vips_g_cond_free(GCond *); - -/* ... and for GThread. +/* Wrapper for g_thread_try_new(). */ VIPS_API GThread *vips_g_thread_new(const char *, GThreadFunc, gpointer); diff --git a/libvips/include/vips/type.h b/libvips/include/vips/type.h index 1de36a631f..be74cf6f89 100644 --- a/libvips/include/vips/type.h +++ b/libvips/include/vips/type.h @@ -74,7 +74,7 @@ typedef struct _VipsArea { * structure, so a simple GMutex is OK. */ int count; - GMutex *lock; + GMutex lock; /* Things like ICC profiles need their own free functions. * diff --git a/libvips/include/vips/vips.h b/libvips/include/vips/vips.h index 9e74ef5579..e77dcbd34d 100644 --- a/libvips/include/vips/vips.h +++ b/libvips/include/vips/vips.h @@ -117,6 +117,7 @@ extern "C" { #include #include #include +#include #include #include #include diff --git a/libvips/iofuncs/buffer.c b/libvips/iofuncs/buffer.c index de486474af..158d272abd 100644 --- a/libvips/iofuncs/buffer.c +++ b/libvips/iofuncs/buffer.c @@ -70,7 +70,6 @@ #include #include -#include #ifdef DEBUG /* Track all buffers here for debugging. diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index 9821294f2d..2feb859e53 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -62,7 +62,6 @@ #include #include #include -#include #include #ifdef G_OS_WIN32 diff --git a/libvips/iofuncs/generate.c b/libvips/iofuncs/generate.c index 6f3b991b71..a2ef201fa0 100644 --- a/libvips/iofuncs/generate.c +++ b/libvips/iofuncs/generate.c @@ -108,7 +108,6 @@ #include #include -#include #include /** diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 5623010eaa..3c09627b39 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -471,7 +471,7 @@ vips_image_finalize(GObject *gobject) */ vips_image_delete(image); - VIPS_FREEF(vips_g_mutex_free, image->sslock); + g_mutex_clear(&image->sslock); VIPS_FREE(image->Hist); VIPS_FREEF(vips__gslist_gvalue_free, image->history_list); @@ -1025,14 +1025,14 @@ vips_image_real_invalidate(VipsImage *image, void *data) VIPS_GATE_START("vips_image_real_invalidate: wait"); - g_mutex_lock(image->sslock); + g_mutex_lock(&image->sslock); VIPS_GATE_STOP("vips_image_real_invalidate: wait"); (void) vips_slist_map2(image->regions, (VipsSListMap2Fn) vips_image_real_invalidate_cb, NULL, NULL); - g_mutex_unlock(image->sslock); + g_mutex_unlock(&image->sslock); } static void @@ -1347,7 +1347,7 @@ vips_image_init(VipsImage *image) image->Yres = 1.0; image->fd = -1; /* since 0 is stdout */ - image->sslock = vips_g_mutex_new(); + g_mutex_init(&image->sslock); image->sizeof_header = VIPS_SIZEOF_HEADER; diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index cf95ef9128..abb1fd8bef 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -97,7 +97,6 @@ #define VIPS_DISABLE_DEPRECATION_WARNINGS #include #include -#include #include /* abort() on the first warning or error. diff --git a/libvips/iofuncs/memory.c b/libvips/iofuncs/memory.c index 1c3b500a52..9e7e2b5f50 100644 --- a/libvips/iofuncs/memory.c +++ b/libvips/iofuncs/memory.c @@ -74,7 +74,6 @@ #endif #include -#include /** * SECTION: memory diff --git a/libvips/iofuncs/region.c b/libvips/iofuncs/region.c index f1a34bb6bf..56d1557c5b 100644 --- a/libvips/iofuncs/region.c +++ b/libvips/iofuncs/region.c @@ -102,7 +102,6 @@ #include #include -#include #include /** @@ -231,14 +230,14 @@ vips__region_start(VipsRegion *region) if (!region->seq && image->start_fn) { VIPS_GATE_START("vips__region_start: wait"); - g_mutex_lock(image->sslock); + g_mutex_lock(&image->sslock); VIPS_GATE_STOP("vips__region_start: wait"); region->seq = image->start_fn(image, image->client1, image->client2); - g_mutex_unlock(image->sslock); + g_mutex_unlock(&image->sslock); if (!region->seq) { #ifdef DEBUG @@ -265,14 +264,14 @@ vips__region_stop(VipsRegion *region) VIPS_GATE_START("vips__region_stop: wait"); - g_mutex_lock(image->sslock); + g_mutex_lock(&image->sslock); VIPS_GATE_STOP("vips__region_stop: wait"); result = image->stop_fn(region->seq, image->client1, image->client2); - g_mutex_unlock(image->sslock); + g_mutex_unlock(&image->sslock); /* stop function can return an error, but we have nothing we * can really do with it, sadly. @@ -312,13 +311,13 @@ vips_region_dispose(GObject *gobject) */ VIPS_GATE_START("vips_region_dispose: wait"); - g_mutex_lock(image->sslock); + g_mutex_lock(&image->sslock); VIPS_GATE_STOP("vips_region_dispose: wait"); image->regions = g_slist_remove(image->regions, region); - g_mutex_unlock(image->sslock); + g_mutex_unlock(&image->sslock); region->im = NULL; @@ -382,7 +381,7 @@ vips__region_take_ownership(VipsRegion *region) */ VIPS_GATE_START("vips__region_take_ownership: wait"); - g_mutex_lock(region->im->sslock); + g_mutex_lock(®ion->im->sslock); VIPS_GATE_STOP("vips__region_take_ownership: wait"); @@ -400,7 +399,7 @@ vips__region_take_ownership(VipsRegion *region) region->thread = g_thread_self(); } - g_mutex_unlock(region->im->sslock); + g_mutex_unlock(®ion->im->sslock); } void @@ -422,7 +421,7 @@ vips__region_no_ownership(VipsRegion *region) { VIPS_GATE_START("vips__region_no_ownership: wait"); - g_mutex_lock(region->im->sslock); + g_mutex_lock(®ion->im->sslock); VIPS_GATE_STOP("vips__region_no_ownership: wait"); @@ -432,7 +431,7 @@ vips__region_no_ownership(VipsRegion *region) if (region->buffer) vips_buffer_undone(region->buffer); - g_mutex_unlock(region->im->sslock); + g_mutex_unlock(®ion->im->sslock); } static int @@ -452,13 +451,13 @@ vips_region_build(VipsObject *object) */ VIPS_GATE_START("vips_region_build: wait"); - g_mutex_lock(image->sslock); + g_mutex_lock(&image->sslock); VIPS_GATE_STOP("vips_region_build: wait"); image->regions = g_slist_prepend(image->regions, region); - g_mutex_unlock(image->sslock); + g_mutex_unlock(&image->sslock); return 0; } diff --git a/libvips/iofuncs/semaphore.c b/libvips/iofuncs/semaphore.c index cf7dcd6228..aaf5dbf613 100644 --- a/libvips/iofuncs/semaphore.c +++ b/libvips/iofuncs/semaphore.c @@ -48,11 +48,9 @@ #include #include -#include #include #include -#include #include void @@ -60,15 +58,17 @@ vips_semaphore_init(VipsSemaphore *s, int v, char *name) { s->v = v; s->name = name; - s->mutex = vips_g_mutex_new(); - s->cond = vips_g_cond_new(); + g_mutex_init(&s->mutex); + s->cond = g_new(GCond, 1); + g_cond_init(s->cond); } void vips_semaphore_destroy(VipsSemaphore *s) { - VIPS_FREEF(vips_g_mutex_free, s->mutex); - VIPS_FREEF(vips_g_cond_free, s->cond); + g_mutex_clear(&s->mutex); + g_cond_clear(s->cond); + g_free(s->cond); } /* Add n to the semaphore and signal any threads that are blocked waiting @@ -79,7 +79,7 @@ vips_semaphore_upn(VipsSemaphore *s, int n) { int value_after_op; - g_mutex_lock(s->mutex); + g_mutex_lock(&s->mutex); s->v += n; value_after_op = s->v; @@ -90,7 +90,7 @@ vips_semaphore_upn(VipsSemaphore *s, int n) g_cond_signal(s->cond); else g_cond_broadcast(s->cond); - g_mutex_unlock(s->mutex); + g_mutex_unlock(&s->mutex); #ifdef DEBUG_IO printf("vips_semaphore_upn(\"%s\",%d) = %d\n", @@ -120,15 +120,15 @@ vips__semaphore_downn_until(VipsSemaphore *s, int n, gint64 end_time) VIPS_GATE_START("vips__semaphore_downn_until: wait"); - g_mutex_lock(s->mutex); + g_mutex_lock(&s->mutex); while (s->v < n) { if (end_time == -1) - vips__worker_cond_wait(s->cond, s->mutex); - else if (!g_cond_wait_until(s->cond, s->mutex, end_time)) { + vips__worker_cond_wait(s->cond, &s->mutex); + else if (!g_cond_wait_until(s->cond, &s->mutex, end_time)) { /* timeout has passed. */ - g_mutex_unlock(s->mutex); + g_mutex_unlock(&s->mutex); VIPS_GATE_STOP("vips__semaphore_downn_until: wait"); return -1; @@ -138,7 +138,7 @@ vips__semaphore_downn_until(VipsSemaphore *s, int n, gint64 end_time) s->v -= n; value_after_op = s->v; - g_mutex_unlock(s->mutex); + g_mutex_unlock(&s->mutex); #ifdef DEBUG_IO printf("vips__semaphore_downn_until(\"%s\",%d): %d\n", diff --git a/libvips/iofuncs/sink.c b/libvips/iofuncs/sink.c index 80821855fe..bf146b23cc 100644 --- a/libvips/iofuncs/sink.c +++ b/libvips/iofuncs/sink.c @@ -44,7 +44,6 @@ #include #include -#include #include #include diff --git a/libvips/iofuncs/sink.h b/libvips/iofuncs/sink.h index be5835aa84..a21067f6e0 100644 --- a/libvips/iofuncs/sink.h +++ b/libvips/iofuncs/sink.h @@ -39,7 +39,6 @@ extern "C" { #endif /*__cplusplus*/ #include -#include /* Base for sink.c / sinkdisc.c / sinkmemory.c */ diff --git a/libvips/iofuncs/sinkdisc.c b/libvips/iofuncs/sinkdisc.c index 35dd1ad868..e48d14daf4 100644 --- a/libvips/iofuncs/sinkdisc.c +++ b/libvips/iofuncs/sinkdisc.c @@ -59,8 +59,6 @@ #include #include -#include -#include #include #include "sink.h" diff --git a/libvips/iofuncs/sinkmemory.c b/libvips/iofuncs/sinkmemory.c index ba8994f47b..2871ec57ff 100644 --- a/libvips/iofuncs/sinkmemory.c +++ b/libvips/iofuncs/sinkmemory.c @@ -51,8 +51,6 @@ #include #include -#include -#include #include #include "sink.h" diff --git a/libvips/iofuncs/sinkscreen.c b/libvips/iofuncs/sinkscreen.c index a7b1ea3f4a..fd5c9d43f2 100644 --- a/libvips/iofuncs/sinkscreen.c +++ b/libvips/iofuncs/sinkscreen.c @@ -69,7 +69,6 @@ #endif /*HAVE_UNISTD_H*/ #include -#include #include #include @@ -111,7 +110,7 @@ typedef struct _Render { gatomicrefcount ref_count; #else int ref_count; - GMutex *ref_count_lock; + GMutex ref_count_lock; #endif /* Parameters. @@ -128,7 +127,7 @@ typedef struct _Render { /* Lock here before reading or modifying the tile structure. */ - GMutex *lock; + GMutex lock; /* Tile cache. */ @@ -243,9 +242,9 @@ render_free(Render *render) g_mutex_unlock(&render_dirty_lock); #if !GLIB_CHECK_VERSION(2, 58, 0) - vips_g_mutex_free(render->ref_count_lock); + g_mutex_clear(&render->ref_count_lock); #endif - vips_g_mutex_free(render->lock); + g_mutex_clear(&render->lock); vips_slist_map2(render->all, (VipsSListMap2Fn) tile_free, NULL, NULL); VIPS_FREEF(g_slist_free, render->all); @@ -273,10 +272,10 @@ render_ref(Render *render) g_assert(!g_atomic_ref_count_compare(&render->ref_count, 0)); g_atomic_ref_count_inc(&render->ref_count); #else - g_mutex_lock(render->ref_count_lock); + g_mutex_lock(&render->ref_count_lock); g_assert(render->ref_count != 0); render->ref_count += 1; - g_mutex_unlock(render->ref_count_lock); + g_mutex_unlock(&render->ref_count_lock); #endif return 0; @@ -291,11 +290,11 @@ render_unref(Render *render) g_assert(!g_atomic_ref_count_compare(&render->ref_count, 0)); kill = g_atomic_ref_count_dec(&render->ref_count); #else - g_mutex_lock(render->ref_count_lock); + g_mutex_lock(&render->ref_count_lock); g_assert(render->ref_count > 0); render->ref_count -= 1; kill = render->ref_count == 0; - g_mutex_unlock(render->ref_count_lock); + g_mutex_unlock(&render->ref_count_lock); #endif if (kill) @@ -387,7 +386,7 @@ render_allocate(VipsThreadState *state, void *a, gboolean *stop) RenderThreadState *rstate = (RenderThreadState *) state; Tile *tile; - g_mutex_lock(render->lock); + g_mutex_lock(&render->lock); if (render_reschedule || !(tile = render_tile_dirty_get(render))) { @@ -398,7 +397,7 @@ render_allocate(VipsThreadState *state, void *a, gboolean *stop) else rstate->tile = tile; - g_mutex_unlock(render->lock); + g_mutex_unlock(&render->lock); return 0; } @@ -552,7 +551,7 @@ render_new(VipsImage *in, VipsImage *out, VipsImage *mask, g_atomic_ref_count_init(&render->ref_count); #else render->ref_count = 1; - render->ref_count_lock = vips_g_mutex_new(); + g_mutex_init(&render->ref_count_lock); #endif render->in = in; @@ -565,7 +564,7 @@ render_new(VipsImage *in, VipsImage *out, VipsImage *mask, render->notify = notify; render->a = a; - render->lock = vips_g_mutex_new(); + g_mutex_init(&render->lock); render->all = NULL; render->ntiles = 0; @@ -726,13 +725,13 @@ tile_queue(Tile *tile, VipsRegion *reg) * This tile won't get pulled out from under us since it's not * marked as "painted", and it's not on the dirty list. */ - g_mutex_unlock(render->lock); + g_mutex_unlock(&render->lock); if (vips_region_prepare_to(reg, tile->region, &tile->area, tile->area.left, tile->area.top)) VIPS_DEBUG_MSG_RED("tile_queue: prepare failed\n"); - g_mutex_lock(render->lock); + g_mutex_lock(&render->lock); tile->painted = TRUE; } @@ -870,7 +869,7 @@ image_fill(VipsRegion *out, void *seq, void *a, void *b, gboolean *stop) VIPS_DEBUG_MSG("image_fill: left = %d, top = %d, width = %d, height = %d\n", r->left, r->top, r->width, r->height); - g_mutex_lock(render->lock); + g_mutex_lock(&render->lock); /* @@ -896,7 +895,7 @@ image_fill(VipsRegion *out, void *seq, void *a, void *b, gboolean *stop) VIPS_DEBUG_MSG_RED("image_fill: argh!\n"); } - g_mutex_unlock(render->lock); + g_mutex_unlock(&render->lock); return 0; } @@ -921,7 +920,7 @@ mask_fill(VipsRegion *out, void *seq, void *a, void *b, gboolean *stop) VIPS_DEBUG_MSG("mask_fill: left = %d, top = %d, width = %d, height = %d\n", r->left, r->top, r->width, r->height); - g_mutex_lock(render->lock); + g_mutex_lock(&render->lock); for (y = ys; y < VIPS_RECT_BOTTOM(r); y += tile_height) for (x = xs; x < VIPS_RECT_RIGHT(r); x += tile_width) { @@ -946,7 +945,7 @@ mask_fill(VipsRegion *out, void *seq, void *a, void *b, gboolean *stop) vips_region_paint(out, &area, value); } - g_mutex_unlock(render->lock); + g_mutex_unlock(&render->lock); return 0; } diff --git a/libvips/iofuncs/thread.c b/libvips/iofuncs/thread.c index 5fbad04aca..585bb3a4c7 100644 --- a/libvips/iofuncs/thread.c +++ b/libvips/iofuncs/thread.c @@ -50,7 +50,6 @@ #include #include -#include #include #ifdef G_OS_WIN32 @@ -87,45 +86,6 @@ vips_thread_isvips(void) return g_private_get(&is_vips_thread_key) != NULL; } -/* Glib 2.32 revised the thread API. We need some compat functions. - */ - -GMutex * -vips_g_mutex_new(void) -{ - GMutex *mutex; - - mutex = g_new(GMutex, 1); - g_mutex_init(mutex); - - return mutex; -} - -void -vips_g_mutex_free(GMutex *mutex) -{ - g_mutex_clear(mutex); - g_free(mutex); -} - -GCond * -vips_g_cond_new(void) -{ - GCond *cond; - - cond = g_new(GCond, 1); - g_cond_init(cond); - - return cond; -} - -void -vips_g_cond_free(GCond *cond) -{ - g_cond_clear(cond); - g_free(cond); -} - typedef struct { const char *domain; GThreadFunc func; diff --git a/libvips/iofuncs/threadpool.c b/libvips/iofuncs/threadpool.c index 5d6e7f007a..2407dfecaa 100644 --- a/libvips/iofuncs/threadpool.c +++ b/libvips/iofuncs/threadpool.c @@ -71,7 +71,6 @@ #include #include -#include #include #ifdef G_OS_WIN32 @@ -251,7 +250,7 @@ typedef struct _VipsThreadpool { VipsThreadStartFn start; VipsThreadpoolAllocateFn allocate; VipsThreadpoolWorkFn work; - GMutex *allocate_lock; + GMutex allocate_lock; void *a; /* User argument to start / allocate / etc. */ int max_workers; /* Max number of workers in pool */ @@ -311,7 +310,7 @@ vips_worker_work_unit(VipsWorker *worker) VIPS_GATE_START("vips_worker_work_unit: wait"); - vips__worker_lock(pool->allocate_lock); + vips__worker_lock(&pool->allocate_lock); VIPS_GATE_STOP("vips_worker_work_unit: wait"); @@ -319,7 +318,7 @@ vips_worker_work_unit(VipsWorker *worker) */ if (pool->stop) { worker->stop = TRUE; - g_mutex_unlock(pool->allocate_lock); + g_mutex_unlock(&pool->allocate_lock); return; } @@ -330,7 +329,7 @@ vips_worker_work_unit(VipsWorker *worker) * flag. */ worker->stop = TRUE; - g_mutex_unlock(pool->allocate_lock); + g_mutex_unlock(&pool->allocate_lock); return; } else { @@ -343,7 +342,7 @@ vips_worker_work_unit(VipsWorker *worker) if (vips_worker_allocate(worker)) { pool->error = TRUE; worker->stop = TRUE; - g_mutex_unlock(pool->allocate_lock); + g_mutex_unlock(&pool->allocate_lock); return; } @@ -351,11 +350,11 @@ vips_worker_work_unit(VipsWorker *worker) */ if (pool->stop) { worker->stop = TRUE; - g_mutex_unlock(pool->allocate_lock); + g_mutex_unlock(&pool->allocate_lock); return; } - g_mutex_unlock(pool->allocate_lock); + g_mutex_unlock(&pool->allocate_lock); if (worker->state->stall && vips__stall) { @@ -407,11 +406,11 @@ vips_thread_main_loop(void *a, void *b) /* unreffing the worker state will trigger stop in the threadstate, so * we need to single-thread. */ - g_mutex_lock(pool->allocate_lock); + g_mutex_lock(&pool->allocate_lock); VIPS_FREEF(g_object_unref, worker->state); - g_mutex_unlock(pool->allocate_lock); + g_mutex_unlock(&pool->allocate_lock); VIPS_FREE(worker); g_private_set(&worker_key, NULL); @@ -491,7 +490,7 @@ vips_threadpool_free(VipsThreadpool *pool) vips_threadpool_wait(pool); - VIPS_FREEF(vips_g_mutex_free, pool->allocate_lock); + g_mutex_clear(&pool->allocate_lock); vips_semaphore_destroy(&pool->n_workers); vips_semaphore_destroy(&pool->tick); VIPS_FREE(pool); @@ -513,7 +512,7 @@ vips_threadpool_new(VipsImage *im) pool->im = im; pool->allocate = NULL; pool->work = NULL; - pool->allocate_lock = vips_g_mutex_new(); + g_mutex_init(&pool->allocate_lock); pool->max_workers = vips_concurrency_get(); vips_semaphore_init(&pool->n_workers, 0, "n_workers"); vips_semaphore_init(&pool->tick, 0, "tick"); diff --git a/libvips/iofuncs/threadset.c b/libvips/iofuncs/threadset.c index 10b48a332b..7cbe31a270 100644 --- a/libvips/iofuncs/threadset.c +++ b/libvips/iofuncs/threadset.c @@ -49,7 +49,6 @@ #include #include -#include #include typedef struct _VipsThreadExec { diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index a93f0e07b1..8eed55a357 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -137,7 +137,7 @@ static GSList *vips_area_all = NULL; VipsArea * vips_area_copy(VipsArea *area) { - g_mutex_lock(area->lock); + g_mutex_lock(&area->lock); g_assert(area->count > 0); @@ -147,7 +147,7 @@ vips_area_copy(VipsArea *area) printf("vips_area_copy: %p count = %d\n", area, area->count); #endif /*DEBUG*/ - g_mutex_unlock(area->lock); + g_mutex_unlock(&area->lock); return area; } @@ -175,7 +175,7 @@ vips_area_free(VipsArea *area) void vips_area_unref(VipsArea *area) { - g_mutex_lock(area->lock); + g_mutex_lock(&area->lock); g_assert(area->count > 0); @@ -194,9 +194,9 @@ vips_area_unref(VipsArea *area) if (area->count == 0) { vips_area_free(area); - g_mutex_unlock(area->lock); + g_mutex_unlock(&area->lock); - VIPS_FREEF(vips_g_mutex_free, area->lock); + g_mutex_clear(&area->lock); if (vips__leak) { g_mutex_lock(&vips__global_lock); @@ -214,7 +214,7 @@ vips_area_unref(VipsArea *area) #endif /*DEBUG*/ } else - g_mutex_unlock(area->lock); + g_mutex_unlock(&area->lock); } /* autoptr needs typed versions of functions for free. @@ -256,7 +256,7 @@ vips_area_new(VipsCallbackFn free_fn, void *data) area = g_new(VipsArea, 1); area->count = 1; - area->lock = vips_g_mutex_new(); + g_mutex_init(&area->lock); area->length = 0; area->data = data; area->free_fn = free_fn; @@ -724,7 +724,7 @@ vips_blob_set(VipsBlob *blob, { VipsArea *area = VIPS_AREA(blob); - g_mutex_lock(area->lock); + g_mutex_lock(&area->lock); vips_area_free(area); @@ -732,7 +732,7 @@ vips_blob_set(VipsBlob *blob, area->length = length; area->data = (void *) data; - g_mutex_unlock(area->lock); + g_mutex_unlock(&area->lock); } /* Transform a blob to a G_TYPE_STRING. diff --git a/libvips/iofuncs/window.c b/libvips/iofuncs/window.c index 6bd2ce466c..216b83547d 100644 --- a/libvips/iofuncs/window.c +++ b/libvips/iofuncs/window.c @@ -56,7 +56,6 @@ #include #include -#include #ifdef G_OS_WIN32 #include @@ -139,7 +138,7 @@ vips_window_unref(VipsWindow *window) { VipsImage *im = window->im; - g_mutex_lock(im->sslock); + g_mutex_lock(&im->sslock); #ifdef DEBUG printf("vips_window_unref: window top = %d, height = %d, count = %d\n", @@ -152,12 +151,12 @@ vips_window_unref(VipsWindow *window) if (window->ref_count == 0) { if (vips_window_free(window)) { - g_mutex_unlock(im->sslock); + g_mutex_unlock(&im->sslock); return -1; } } - g_mutex_unlock(im->sslock); + g_mutex_unlock(&im->sslock); return 0; } @@ -353,20 +352,20 @@ vips_window_take(VipsWindow *window, VipsImage *im, int top, int height) window->top + window->height >= top + height) return window; - g_mutex_lock(im->sslock); + g_mutex_lock(&im->sslock); /* We have a window and we are the only ref to it ... scroll. */ if (window && window->ref_count == 1) { if (vips_window_set(window, top, height)) { - g_mutex_unlock(im->sslock); + g_mutex_unlock(&im->sslock); vips_window_unref(window); return NULL; } - g_mutex_unlock(im->sslock); + g_mutex_unlock(&im->sslock); return window; } @@ -380,7 +379,7 @@ vips_window_take(VipsWindow *window, VipsImage *im, int top, int height) /* Is there an existing window we can reuse? */ if ((window = vips_window_find(im, top, height))) { - g_mutex_unlock(im->sslock); + g_mutex_unlock(&im->sslock); return window; } @@ -396,11 +395,11 @@ vips_window_take(VipsWindow *window, VipsImage *im, int top, int height) height = VIPS_CLIP(0, height, im->Ysize - top); if (!(window = vips_window_new(im, top, height))) { - g_mutex_unlock(im->sslock); + g_mutex_unlock(&im->sslock); return NULL; } - g_mutex_unlock(im->sslock); + g_mutex_unlock(&im->sslock); return window; } diff --git a/libvips/mosaicing/lrmerge.c b/libvips/mosaicing/lrmerge.c index 27d9e8f625..eb1b9d9d52 100644 --- a/libvips/mosaicing/lrmerge.c +++ b/libvips/mosaicing/lrmerge.c @@ -130,7 +130,6 @@ */ #include -#include #include #include @@ -332,7 +331,7 @@ make_firstlast(MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg) * threads. In fact it's harmless if we do get two writers, but we may * avoid duplicating work. */ - g_mutex_lock(ovlap->fl_lock); + g_mutex_lock(&ovlap->fl_lock); /* Do we already have first/last for this area? Bail out if we do. */ @@ -349,7 +348,7 @@ make_firstlast(MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg) if (!missing) { /* No work to do! */ - g_mutex_unlock(ovlap->fl_lock); + g_mutex_unlock(&ovlap->fl_lock); return 0; } @@ -383,7 +382,7 @@ make_firstlast(MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg) */ if (vips_region_prepare(rir, &rr) || vips_region_prepare(sir, &sr)) { - g_mutex_unlock(ovlap->fl_lock); + g_mutex_unlock(&ovlap->fl_lock); return -1; } @@ -404,7 +403,7 @@ make_firstlast(MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg) sr.left, ys, sr.width) || find_last(rir, last, rr.left, yr, rr.width)) { - g_mutex_unlock(ovlap->fl_lock); + g_mutex_unlock(&ovlap->fl_lock); return -1; } @@ -425,7 +424,7 @@ make_firstlast(MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg) } } - g_mutex_unlock(ovlap->fl_lock); + g_mutex_unlock(&ovlap->fl_lock); return 0; } @@ -737,9 +736,9 @@ lr_blend_labpack(VipsRegion *out_region, MergeInfo *inf, Overlapping *ovlap, } static void -lock_free(VipsImage *image, GMutex *lock) +ovlap_free(VipsImage *image, Overlapping *ovlap) { - VIPS_FREEF(vips_g_mutex_free, lock); + g_mutex_clear(&ovlap->fl_lock); } /* Build basic per-call state and do some geometry calculations. Shared with @@ -853,10 +852,10 @@ vips__build_mergestate(const char *domain, for (x = 0; x < ovlap->flsize; x++) ovlap->first[x] = -1; - ovlap->fl_lock = vips_g_mutex_new(); + g_mutex_init(&ovlap->fl_lock); g_signal_connect(out, "close", - G_CALLBACK(lock_free), ovlap->fl_lock); + G_CALLBACK(ovlap_free), ovlap); return ovlap; } diff --git a/libvips/mosaicing/pmosaicing.h b/libvips/mosaicing/pmosaicing.h index 5f6a7ce521..5e4c1f0e3f 100644 --- a/libvips/mosaicing/pmosaicing.h +++ b/libvips/mosaicing/pmosaicing.h @@ -82,7 +82,7 @@ typedef struct _Overlapping { /* Overlap start/end cache */ - GMutex *fl_lock; /* Need to lock on build */ + GMutex fl_lock; /* Need to lock on build */ int *first, *last; /* Blend function. diff --git a/libvips/mosaicing/tbmerge.c b/libvips/mosaicing/tbmerge.c index a827c18ad0..9477392cc2 100644 --- a/libvips/mosaicing/tbmerge.c +++ b/libvips/mosaicing/tbmerge.c @@ -112,7 +112,6 @@ #include #include -#include #include #include @@ -283,7 +282,7 @@ make_firstlast(MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg) * threads. In fact it's harmless if we do get two writers, but we may * avoid duplicating work. */ - g_mutex_lock(ovlap->fl_lock); + g_mutex_lock(&ovlap->fl_lock); /* Do we already have first/last for this area? Bail out if we do. */ @@ -300,7 +299,7 @@ make_firstlast(MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg) if (!missing) { /* No work to do! */ - g_mutex_unlock(ovlap->fl_lock); + g_mutex_unlock(&ovlap->fl_lock); return 0; } @@ -327,7 +326,7 @@ make_firstlast(MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg) */ if (vips_region_prepare(rir, &rr) || vips_region_prepare(sir, &sr)) { - g_mutex_unlock(ovlap->fl_lock); + g_mutex_unlock(&ovlap->fl_lock); return -1; } @@ -347,7 +346,7 @@ make_firstlast(MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg) x + sr.left, sr.top, sr.height) || find_bot(rir, last, x + rr.left, rr.top, rr.height)) { - g_mutex_unlock(ovlap->fl_lock); + g_mutex_unlock(&ovlap->fl_lock); return -1; } @@ -368,7 +367,7 @@ make_firstlast(MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg) } } - g_mutex_unlock(ovlap->fl_lock); + g_mutex_unlock(&ovlap->fl_lock); return 0; } From 13ff1c07c9c0780bca088dd4d0e54fd2ae6e6a5a Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 21 Mar 2025 13:34:34 +0100 Subject: [PATCH 084/174] Improve guard against corrupt ICC profiles (#4428) --- ChangeLog | 1 + libvips/colour/icc_transform.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2f546f3bd..c2bc1a32eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,7 @@ - heifload: `unlimited` flag removes all limits (requires libheif 1.19.0+) [lovell] - heifsave: improve alpha channel detection [lovell] - convi: ensure double sum precision for floats [lovell] +- improve guard against corrupt ICC profiles with older lcms2 versions [kleisauke] 8.16.1 diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 420b77a5f3..8d7d8dcfde 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -622,9 +622,15 @@ vips_icc_load_profile_blob(VipsIcc *icc, VipsBlob *blob, icc->selected_intent = icc->intent; if (icc->intent == VIPS_INTENT_AUTO || - !cmsIsIntentSupported(profile, icc->intent, direction)) - icc->selected_intent = (VipsIntent) cmsGetHeaderRenderingIntent( - profile); + !cmsIsIntentSupported(profile, icc->intent, direction)) { + cmsUInt32Number intent = cmsGetHeaderRenderingIntent(profile); + if (intent > VIPS_INTENT_ABSOLUTE) { + VIPS_FREEF(cmsCloseProfile, profile); + g_warning("corrupt profile"); + return NULL; + } + icc->selected_intent = (VipsIntent) intent; + } if (icc->intent != VIPS_INTENT_AUTO && icc->selected_intent != icc->intent) From 4dd6de44e173ba7295dc0a5b9f9edc6ab393be58 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 21 Mar 2025 13:36:43 +0100 Subject: [PATCH 085/174] Minor improvements (#4427) * Remove redundant private markers * semaphore: clarify that all struct fields are private * magickload: remove invalid FIXMEs This load operation is not cached. * Remove redundant `-1` from `*snprintf()` calls At most `n-1` characters are written to the buffer for these calls, so explicitly subtracting `-1` is unnecessary. --- libvips/deprecated/package.c | 4 ++-- libvips/foreign/magick6load.c | 4 ++-- libvips/foreign/magick7load.c | 2 +- libvips/include/vips/foreign.h | 2 ++ libvips/include/vips/format.h | 2 ++ libvips/include/vips/region.h | 2 +- libvips/include/vips/semaphore.h | 2 ++ libvips/iofuncs/gate.c | 2 -- libvips/iofuncs/init.c | 4 ++-- libvips/iofuncs/threadpool.c | 2 -- 10 files changed, 14 insertions(+), 12 deletions(-) diff --git a/libvips/deprecated/package.c b/libvips/deprecated/package.c index 9544779d06..f268fba629 100644 --- a/libvips/deprecated/package.c +++ b/libvips/deprecated/package.c @@ -745,7 +745,7 @@ im_load_plugins(const char *fmt, ...) return 0; va_start(ap, fmt); - (void) im_vsnprintf(dir_name, VIPS_PATH_MAX - 1, fmt, ap); + (void) im_vsnprintf(dir_name, VIPS_PATH_MAX, fmt, ap); va_end(ap); g_info("im_load_plugins: searching \"%s\"", dir_name); @@ -760,7 +760,7 @@ im_load_plugins(const char *fmt, ...) if (im_ispostfix(name, ".plg")) { char path[VIPS_PATH_MAX]; - im_snprintf(path, VIPS_PATH_MAX - 1, + im_snprintf(path, VIPS_PATH_MAX, "%s" G_DIR_SEPARATOR_S "%s", dir_name, name); if (!im_load_plugin(path)) result = -1; diff --git a/libvips/foreign/magick6load.c b/libvips/foreign/magick6load.c index c57d509b01..61fcf7fba1 100644 --- a/libvips/foreign/magick6load.c +++ b/libvips/foreign/magick6load.c @@ -229,13 +229,13 @@ vips_foreign_load_magick_build(VipsObject *object) return -1; if (magick->all_frames) - magick->n = -1; // FIXME: Invalidates operation cache + magick->n = -1; /* IM doesn't use the -1 means end-of-file convention, change it to a * very large number. */ if (magick->n == -1) - magick->n = 10000000; // FIXME: Invalidates operation cache + magick->n = 10000000; /* Canvas resolution for rendering vector formats like SVG. */ diff --git a/libvips/foreign/magick7load.c b/libvips/foreign/magick7load.c index 02ee0b39b0..9c615b6d87 100644 --- a/libvips/foreign/magick7load.c +++ b/libvips/foreign/magick7load.c @@ -310,7 +310,7 @@ vips_foreign_load_magick7_build(VipsObject *object) return -1; if (magick7->all_frames) - magick7->n = -1; // FIXME: Invalidates operation cache + magick7->n = -1; /* Canvas resolution for rendering vector formats like SVG. */ diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index f2e7134b6b..6ea2addd8f 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -145,6 +145,7 @@ typedef enum { typedef struct _VipsForeignLoad { VipsForeign parent_object; + /*< private >*/ /* Set TRUE to force open via memory. @@ -201,6 +202,7 @@ typedef struct _VipsForeignLoad { typedef struct _VipsForeignLoadClass { VipsForeignClass parent_class; + /*< public >*/ /* Is a file in this format. diff --git a/libvips/include/vips/format.h b/libvips/include/vips/format.h index b96c4eb9a9..9f52a16e06 100644 --- a/libvips/include/vips/format.h +++ b/libvips/include/vips/format.h @@ -64,6 +64,7 @@ typedef enum { typedef struct _VipsFormat { VipsObject parent_object; + /*< public >*/ } VipsFormat; @@ -72,6 +73,7 @@ typedef struct _VipsFormatClass { VipsObjectClass parent_class; /*< public >*/ + /* Is a file in this format. */ gboolean (*is_a)(const char *); diff --git a/libvips/include/vips/region.h b/libvips/include/vips/region.h index b0662890f5..7e4c7c1048 100644 --- a/libvips/include/vips/region.h +++ b/libvips/include/vips/region.h @@ -90,9 +90,9 @@ typedef enum { struct _VipsRegion { VipsObject parent_object; - /*< public >*/ /* Users may read these two fields. */ + /*< public >*/ VipsImage *im; /* Link back to parent image */ VipsRect valid; /* Area of parent we can see */ diff --git a/libvips/include/vips/semaphore.h b/libvips/include/vips/semaphore.h index 71a7ad8351..d548c397c0 100644 --- a/libvips/include/vips/semaphore.h +++ b/libvips/include/vips/semaphore.h @@ -46,6 +46,8 @@ extern "C" { /* Implement our own semaphores. */ typedef struct { + /* All fields are private. + */ /*< private >*/ char *name; int v; diff --git a/libvips/iofuncs/gate.c b/libvips/iofuncs/gate.c index 8f33747296..029bbd057a 100644 --- a/libvips/iofuncs/gate.c +++ b/libvips/iofuncs/gate.c @@ -70,8 +70,6 @@ typedef struct _VipsThreadGate { */ typedef struct _VipsThreadProfile { - /*< private >*/ - const char *name; GThread *thread; GHashTable *gates; diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index abb1fd8bef..5605686eaf 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -286,7 +286,7 @@ vips_load_plugins(const char *fmt, ...) return; va_start(ap, fmt); - (void) g_vsnprintf(dir_name, VIPS_PATH_MAX - 1, fmt, ap); + (void) g_vsnprintf(dir_name, VIPS_PATH_MAX, fmt, ap); va_end(ap); g_info("searching \"%s\"", dir_name); @@ -300,7 +300,7 @@ vips_load_plugins(const char *fmt, ...) char path[VIPS_PATH_MAX]; GModule *module; - g_snprintf(path, VIPS_PATH_MAX - 1, + g_snprintf(path, VIPS_PATH_MAX, "%s" G_DIR_SEPARATOR_S "%s", dir_name, name); g_info("loading \"%s\"", path); diff --git a/libvips/iofuncs/threadpool.c b/libvips/iofuncs/threadpool.c index 2407dfecaa..59a18e8dfb 100644 --- a/libvips/iofuncs/threadpool.c +++ b/libvips/iofuncs/threadpool.c @@ -228,7 +228,6 @@ vips_thread_state_new(VipsImage *im, void *a) /* What we track for each thread in the pool. */ typedef struct _VipsWorker { - /*< private >*/ struct _VipsThreadpool *pool; /* Pool we are part of */ VipsThreadState *state; @@ -240,7 +239,6 @@ typedef struct _VipsWorker { /* What we track for a group of threads working together. */ typedef struct _VipsThreadpool { - /*< private >*/ VipsImage *im; /* Image we are calculating */ /* Start a thread, do a unit of work (runs in parallel) and allocate From f75d6d3aae4b1ed0c52e8dc23147600c9f16e55d Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Fri, 21 Mar 2025 14:52:26 +0000 Subject: [PATCH 086/174] Tidy up code that frees deprecated plugins during vips_shutdown (#4429) Helps prevent static code analysis tools from triggering. --- libvips/deprecated/package.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvips/deprecated/package.c b/libvips/deprecated/package.c index f268fba629..68860ccf4c 100644 --- a/libvips/deprecated/package.c +++ b/libvips/deprecated/package.c @@ -645,9 +645,9 @@ plugin_free(Plugin *plug) } VIPS_FREE(plug->name); plug->pack = NULL; - g_free(plug); plugin_list = g_slist_remove(plugin_list, plug); + g_free(plug); return 0; } From 21fbd93ddf02514fd55f1be72f5c502e3e8b288a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 22 Mar 2025 13:30:10 +0000 Subject: [PATCH 087/174] improve handling of malformed size values (#4385) thanks Simcha Kosman --- ChangeLog | 1 + libvips/iofuncs/util.c | 1 + 2 files changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index c2bc1a32eb..ef848e6a52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ - much more reliable operation caching - colour: add support for auto-selecting the rendering intent [kleisauke] - add matrixmultiply +- better handling of malformed size values [Simcha Kosman] - improve performance of vips_shrink() [kleisauke] - svgload: add support for custom CSS via stylesheet option [lovell] - heifload: `unlimited` flag removes all limits (requires libheif 1.19.0+) [lovell] diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index acf78ade81..624e221d4b 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -1610,6 +1610,7 @@ vips__parse_size(const char *size_string) */ unit = g_strdup(size_string); + size = 0; n = sscanf(size_string, "%" G_GUINT64_FORMAT " %s", &size, unit); if (n > 1) for (int j = 0; j < VIPS_NUMBER(units); j++) From d2b025cf0efc4a91bac18de2e0223a0ac716758a Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 22 Mar 2025 13:30:29 +0000 Subject: [PATCH 088/174] heifload: improve detection of seek beyond EOF (#4424) --- ChangeLog | 1 + libvips/foreign/heifload.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ef848e6a52..91fc646d88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ - heifsave: improve alpha channel detection [lovell] - convi: ensure double sum precision for floats [lovell] - improve guard against corrupt ICC profiles with older lcms2 versions [kleisauke] +- heifload: improve detection of seek beyond EOF [lovell] 8.16.1 diff --git a/libvips/foreign/heifload.c b/libvips/foreign/heifload.c index 3e334be9a3..84bc0cccac 100644 --- a/libvips/foreign/heifload.c +++ b/libvips/foreign/heifload.c @@ -1185,7 +1185,7 @@ vips_foreign_load_heif_wait_for_file_size(gint64 target_size, void *userdata) result = vips_source_seek(heif->source, target_size, SEEK_SET); vips_source_seek(heif->source, old_position, SEEK_SET); - if (result < 0) + if (result < 0 || old_position < 0) /* Unable to seek to this point, so it's beyond EOF. */ status = heif_reader_grow_status_size_beyond_eof; From cc4d147d328fa7af2fd53d946e124ca0cbdc6c26 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 23 Mar 2025 11:05:01 +0000 Subject: [PATCH 089/174] Add jp2kload oneshot (#4432) * add oneshot to jp2kload improves compatibility with some images thanks mbklein see https://github.com/libvips/libvips/issues/4205 * revise docs and comments --- ChangeLog | 3 ++ libvips/foreign/jp2kload.c | 56 ++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 91fc646d88..50b0852b4e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +master + 8.17.0 - add `keep_duplicate_frames` option to GIF save [dloebl] @@ -16,6 +18,7 @@ - convi: ensure double sum precision for floats [lovell] - improve guard against corrupt ICC profiles with older lcms2 versions [kleisauke] - heifload: improve detection of seek beyond EOF [lovell] +- add "oneshot" option to jp2kload [mbklein] 8.16.1 diff --git a/libvips/foreign/jp2kload.c b/libvips/foreign/jp2kload.c index 05e74427b8..752a92dd10 100644 --- a/libvips/foreign/jp2kload.c +++ b/libvips/foreign/jp2kload.c @@ -80,6 +80,10 @@ typedef struct _VipsForeignLoadJp2k { int page; int shrink; + /* Load images a frame at a time rather than a tile at a time. + */ + gboolean oneshot; + /* Decompress state. */ opj_stream_t *stream; /* Source as an opj stream */ @@ -279,7 +283,12 @@ vips_foreign_load_jp2k_is_a_source(VipsSource *source) static VipsForeignFlags vips_foreign_load_jp2k_get_flags(VipsForeignLoad *load) { - return VIPS_FOREIGN_PARTIAL; + VipsForeignLoadJp2k *jp2k = (VipsForeignLoadJp2k *) load; + + if (jp2k->oneshot) + return VIPS_FOREIGN_SEQUENTIAL; + else + return VIPS_FOREIGN_PARTIAL; } /* The openjpeg info and warning callbacks are incredibly chatty. @@ -1147,9 +1156,9 @@ vips_foreign_load_jp2k_load(VipsForeignLoad *load) VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(load), 3); - int vips_tile_width; - int vips_tile_height; - int vips_tiles_across; + int tile_width; + int tile_height; + int tiles_across; #ifdef DEBUG printf("vips_foreign_load_jp2k_load:\n"); @@ -1161,13 +1170,11 @@ vips_foreign_load_jp2k_load(VipsForeignLoad *load) /* Untiled jp2k images need a different read API. */ - if (jp2k->info->tw == 1 && - jp2k->info->th == 1) { - vips_tile_width = 512; - vips_tile_height = 512; - vips_tiles_across = - VIPS_ROUND_UP(t[0]->Xsize, vips_tile_width) / - vips_tile_width; + if (jp2k->oneshot || + (jp2k->info->tw == 1 && jp2k->info->th == 1)) { + tile_width = jp2k->width; + tile_height = jp2k->height; + tiles_across = 1; if (vips_image_generate(t[0], NULL, vips_foreign_load_jp2k_generate_untiled, NULL, @@ -1175,9 +1182,9 @@ vips_foreign_load_jp2k_load(VipsForeignLoad *load) return -1; } else { - vips_tile_width = jp2k->info->tdx; - vips_tile_height = jp2k->info->tdy; - vips_tiles_across = jp2k->info->tw; + tile_width = jp2k->info->tdx; + tile_height = jp2k->info->tdy; + tiles_across = jp2k->info->tw; if (vips_image_generate(t[0], NULL, vips_foreign_load_jp2k_generate_tiled, NULL, @@ -1189,9 +1196,9 @@ vips_foreign_load_jp2k_load(VipsForeignLoad *load) * rows, plus 50%. */ if (vips_tilecache(t[0], &t[1], - "tile_width", vips_tile_width, - "tile_height", vips_tile_height, - "max_tiles", 3 * vips_tiles_across, + "tile_width", tile_width, + "tile_height", tile_height, + "max_tiles", 3 * tiles_across, NULL)) return -1; @@ -1231,6 +1238,14 @@ vips_foreign_load_jp2k_class_init(VipsForeignLoadJp2kClass *class) VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET(VipsForeignLoadJp2k, page), 0, 100000, 0); + + VIPS_ARG_BOOL(class, "oneshot", 21, + _("One-shot"), + _("Load images a frame at a time"), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET(VipsForeignLoadJp2k, oneshot), + FALSE); + } static void @@ -1612,6 +1627,7 @@ vips__foreign_load_jp2k_decompress(VipsImage *out, * Optional arguments: * * * @page: %gint, load this page + * * @oneshot: %gboolean, load pages in one-shot mode * * @fail_on: #VipsFailOn, types of read error to fail on * * Read a JPEG2000 image. The loader supports 8, 16 and 32-bit int pixel @@ -1624,6 +1640,10 @@ vips__foreign_load_jp2k_decompress(VipsImage *out, * image and higher-numbered pages are x2 reductions. Use the metadata item * "n-pages" to find the number of pyramid layers. * + * Some versions of openjpeg can fail to decode some tiled images correctly. + * Setting @oneshot will force the loader to decode tiled images in a single + * operation and can improve compatibility. + * * Use @fail_on to set the type of error that will cause load to fail. By * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. * @@ -1654,6 +1674,7 @@ vips_jp2kload(const char *filename, VipsImage **out, ...) * Optional arguments: * * * @page: %gint, load this page + * * @oneshot: %gboolean, load pages in one-shot mode * * @fail_on: #VipsFailOn, types of read error to fail on * * Exactly as vips_jp2kload(), but read from a buffer. @@ -1692,6 +1713,7 @@ vips_jp2kload_buffer(void *buf, size_t len, VipsImage **out, ...) * Optional arguments: * * * @page: %gint, load this page + * * @oneshot: %gboolean, load pages in one-shot mode * * @fail_on: #VipsFailOn, types of read error to fail on * * Exactly as vips_jp2kload(), but read from a source. From 5ab8aa58cc73259ccea344dad25510fe7a5f1f7d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 26 Mar 2025 08:29:04 +0000 Subject: [PATCH 090/174] note vips_sink_screen() changes --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 50b0852b4e..08335d8010 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,7 @@ master - improve guard against corrupt ICC profiles with older lcms2 versions [kleisauke] - heifload: improve detection of seek beyond EOF [lovell] - add "oneshot" option to jp2kload [mbklein] +- improved scheduling for vips_sink_screen() 8.16.1 From 881c4ca61cdeb2a4347937064e116a921a7907a2 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 26 Mar 2025 10:21:57 +0000 Subject: [PATCH 091/174] add private threadpools for thumbnail rendering (#4430) In the old model, there was a single rendering thread that moved between the active sink_screen tasks by priority. If a thumbnail and a main image window both needed updating, the thumbnail render (which can take a long time since it is effectively single-threaded) could block all high-priority updates. This PR adds private threadpools for low priority vips_sink_screen() rendering tasks. Now all thumbnails will update in the background as single-threaded tasks, and will not block foreground updates. --- ChangeLog | 2 +- libvips/iofuncs/sinkscreen.c | 171 ++++++++++++++++++++++++++--------- 2 files changed, 130 insertions(+), 43 deletions(-) diff --git a/ChangeLog b/ChangeLog index 08335d8010..63b8c3c355 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,9 +17,9 @@ master - heifsave: improve alpha channel detection [lovell] - convi: ensure double sum precision for floats [lovell] - improve guard against corrupt ICC profiles with older lcms2 versions [kleisauke] +- improve vips_sink_screen() thumbnail rendering - heifload: improve detection of seek beyond EOF [lovell] - add "oneshot" option to jp2kload [mbklein] -- improved scheduling for vips_sink_screen() 8.16.1 diff --git a/libvips/iofuncs/sinkscreen.c b/libvips/iofuncs/sinkscreen.c index fd5c9d43f2..f8873ab2f6 100644 --- a/libvips/iofuncs/sinkscreen.c +++ b/libvips/iofuncs/sinkscreen.c @@ -125,6 +125,14 @@ typedef struct _Render { VipsSinkNotify notify; /* Tell caller about paints here */ void *a; + /* This render has it's own threadpool and is not on the shared list. + * + * This private threadpool needs a semaphore to wait on for dirty tiles + * to arrive. + */ + gboolean private_threadpool; + VipsSemaphore dirty_sem; + /* Lock here before reading or modifying the tile structure. */ GMutex lock; @@ -246,6 +254,9 @@ render_free(Render *render) #endif g_mutex_clear(&render->lock); + if (render->private_threadpool) + vips_semaphore_destroy(&render->dirty_sem); + vips_slist_map2(render->all, (VipsSListMap2Fn) tile_free, NULL, NULL); VIPS_FREEF(g_slist_free, render->all); render->ntiles = 0; @@ -384,6 +395,7 @@ render_allocate(VipsThreadState *state, void *a, gboolean *stop) { Render *render = (Render *) a; RenderThreadState *rstate = (RenderThreadState *) state; + Tile *tile; g_mutex_lock(&render->lock); @@ -468,22 +480,28 @@ render_dirty_sort(Render *a, Render *b, void *user_data) static void render_dirty_put(Render *render) { - g_mutex_lock(&render_dirty_lock); - - if (render->dirty) { - if (!g_slist_find(render_dirty_all, render)) { - render_dirty_all = g_slist_prepend(render_dirty_all, render); - render_dirty_all = g_slist_sort(render_dirty_all, - (GCompareFunc) render_dirty_sort); + if (render->private_threadpool) + // set our private renderer going + vips_semaphore_up(&render->dirty_sem); + else { + // add to the worklist for thwe global renderer + g_mutex_lock(&render_dirty_lock); - /* Tell the bg render thread we have one more dirty - * render on there. - */ - vips_semaphore_up(&n_render_dirty_sem); + if (render->dirty) { + if (!g_slist_find(render_dirty_all, render)) { + render_dirty_all = g_slist_prepend(render_dirty_all, render); + render_dirty_all = g_slist_sort(render_dirty_all, + (GCompareFunc) render_dirty_sort); + + /* Tell the bg render thread we have one more dirty + * render on there. + */ + vips_semaphore_up(&n_render_dirty_sem); + } } - } - g_mutex_unlock(&render_dirty_lock); + g_mutex_unlock(&render_dirty_lock); + } } static guint @@ -519,13 +537,21 @@ render_close_cb(VipsImage *image, Render *render) */ render->shutdown = TRUE; - render_unref(render); + if (render->private_threadpool) { + /* Nudge the bg thread (if any) for this pool. + */ + VIPS_DEBUG_MSG_GREEN("render_close_cb: nudge private worker\n"); + vips_semaphore_up(&render->dirty_sem); + } + else { + /* If this render is being worked on, we want to jog the bg thread, + * make it drop it's ref and think again. + */ + VIPS_DEBUG_MSG_GREEN("render_close_cb: reschedule\n"); + render_reschedule = TRUE; + } - /* If this render is being worked on, we want to jog the bg thread, - * make it drop it's ref and think again. - */ - VIPS_DEBUG_MSG_GREEN("render_close_cb: reschedule\n"); - render_reschedule = TRUE; + render_unref(render); } static Render * @@ -564,6 +590,11 @@ render_new(VipsImage *in, VipsImage *out, VipsImage *mask, render->notify = notify; render->a = a; + if (render->priority < 0) { + render->private_threadpool = TRUE; + vips_semaphore_init(&render->dirty_sem, 0, "dirty_sem"); + } + g_mutex_init(&render->lock); render->all = NULL; @@ -1025,6 +1056,58 @@ render_thread_main(void *client) return NULL; } +static int +render_allocate_private(VipsThreadState *state, void *a, gboolean *stop) +{ + Render *render = (Render *) a; + RenderThreadState *rstate = (RenderThreadState *) state; + + /* Wait for a dirty tile to arrive on this render. + */ + vips_semaphore_down(&render->dirty_sem); + + /* The mask or image is closing, we must exit. + */ + if (render->shutdown) { + *stop = TRUE; + rstate->tile = NULL; + return 0; + } + + /* Get the dirty tile, if any. + */ + g_mutex_lock(&render->lock); + rstate->tile = render_tile_dirty_get(render); + VIPS_DEBUG_MSG_AMBER("render_allocate_private: allocated tile %p\n", + rstate->tile); + g_mutex_unlock(&render->lock); + + return 0; +} + +/* A worker for a private render. + */ +static void +render_work_private(void *data, void *null) +{ + VIPS_DEBUG_MSG_AMBER("render_work_private: start\n"); + + Render *render = (Render *) data; + + // this will quit on ->shutdown == TRUE + if (vips_threadpool_run(render->in, + render_thread_state_new, + render_allocate_private, + render_work, + NULL, + render)) + VIPS_DEBUG_MSG_RED("render_work_private: threadpool_run failed\n"); + + render_unref(render); + + VIPS_DEBUG_MSG_AMBER("render_work_private: stop\n"); +} + static void * vips__sink_screen_once(void *data) { @@ -1052,34 +1135,33 @@ vips__sink_screen_once(void *data) * @notify_fn: (scope call) (nullable): pixels are ready notification callback * @a: (closure notify_fn) (nullable): client data for callback * - * This operation renders @in in the background, making pixels available on - * @out as they are calculated. The @notify_fn callback is run every time a new - * set of pixels are available. Calculated pixels are kept in a cache with - * tiles sized @tile_width by @tile_height pixels and with at most @max_tiles - * tiles. - * If @max_tiles is -1, the cache is of unlimited size (up to the maximum image - * size). - * The @mask image is a one-band uchar image and has 255 for pixels which are - * currently in cache and 0 for uncalculated pixels. + * This operation renders @in in the background, making pixels available + * on @out as they are calculated. The @notify_fn callback is run every + * time a new set of pixels are available. Calculated pixels are kept in + * a cache with tiles sized @tile_width by @tile_height pixels and with at + * most @max_tiles tiles. If @max_tiles is -1, the cache is of unlimited + * size (up to the maximum image * size). The @mask image is a one-band + * uchar image and has 255 for pixels which are currently in cache and 0 + * for uncalculated pixels. + * + * Renders with a positive priority are assumed to be large, gh-priority, + * foreground images. Although there can be many of these, only one is ever + * active, to avoid overcommitting threads. * - * Only a single sink is calculated at any one time, though many may be - * alive. Use @priority to indicate which renders are more important: - * zero means normal - * priority, negative numbers are low priority, positive numbers high - * priority. + * Renders with a negative priority are assumed to be small, thumbnail images + * consisting of a single tile. Single tile images are effectively + * single-threaded, so all these renders are evaluated together. * * Calls to vips_region_prepare() on @out return immediately and hold - * whatever is - * currently in cache for that #VipsRect (check @mask to see which parts of the - * #VipsRect are valid). Any pixels in the #VipsRect which are not in - * cache are added - * to a queue, and the @notify_fn callback will trigger when those pixels are - * ready. + * whatever is currently in cache for that #VipsRect (check @mask to see + * which parts of the #VipsRect are valid). Any pixels in the #VipsRect + * which are not in cache are added to a queue, and the @notify_fn + * callback will trigger when those pixels are ready. * * The @notify_fn callback is run from one of the background threads. In the - * callback - * you need to somehow send a message to the main thread that the pixels are - * ready. In a glib-based application, this is easily done with g_idle_add(). + * callback you need to somehow send a message to the main thread that the + * pixels are ready. In a glib-based application, this is easily done with + * g_idle_add(). * * If @notify_fn is %NULL then vips_sink_screen() runs synchronously. * vips_region_prepare() on @out will always block until the pixels have been @@ -1129,6 +1211,11 @@ vips_sink_screen(VipsImage *in, VipsImage *out, VipsImage *mask, VIPS_DEBUG_MSG("vips_sink_screen: max = %d, %p\n", max_tiles, render); + if (render->private_threadpool) { + render_ref(render); + vips_thread_execute("private threadpool", render_work_private, render); + } + if (vips_image_generate(out, vips_start_one, image_fill, vips_stop_one, in, render)) return -1; From 6dad20abbd687cdc8de604284b491f97b5826e98 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 26 Mar 2025 15:06:51 +0100 Subject: [PATCH 092/174] Remove stray declarations (#4434) --- libvips/foreign/pforeign.h | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/libvips/foreign/pforeign.h b/libvips/foreign/pforeign.h index 748328ae07..2e88cb0cfa 100644 --- a/libvips/foreign/pforeign.h +++ b/libvips/foreign/pforeign.h @@ -81,14 +81,6 @@ int vips__analyze_read(const char *filename, VipsImage *out); extern const char *vips__foreign_csv_suffs[]; -int vips__matrix_read_header(const char *filename, - int *width, int *height, double *scale, double *offset); -int vips__matrix_ismatrix(const char *filename); -VipsImage *vips__matrix_read_file(FILE *fp); -VipsImage *vips__matrix_read(const char *filename); -int vips__matrix_write(VipsImage *in, const char *filename); -int vips__matrix_write_file(VipsImage *in, FILE *fp); - extern const char *vips__foreign_matrix_suffs[]; int vips__openexr_isexr(const char *filename); @@ -104,16 +96,6 @@ int vips__fits_read(const char *filename, VipsImage *out); int vips__fits_write(VipsImage *in, const char *filename); -int vips__magick_read(const char *filename, - VipsImage *out, const char *density, int page, int n); -int vips__magick_read_header(const char *filename, - VipsImage *out, const char *density, int page, int n); - -int vips__magick_read_buffer(const void *buf, const size_t len, - VipsImage *out, const char *density, int page, int n); -int vips__magick_read_buffer_header(const void *buf, const size_t len, - VipsImage *out, const char *density, int page, int n); - extern const char *vips__mat_suffs[]; int vips__mat_load(const char *filename, VipsImage *out); @@ -127,8 +109,6 @@ extern const char *vips__save_ppm_suffs[]; extern const char *vips__save_pfm_suffs[]; extern const char *vips__save_pnm_suffs[]; -int vips__ppm_save_target(VipsImage *in, VipsTarget *target, - gboolean ascii, gboolean squash); int vips__rad_israd(VipsSource *source); int vips__rad_header(VipsSource *source, VipsImage *out); int vips__rad_load(VipsSource *source, VipsImage *out); From add9ca07841b87a0c27ab955b0d14437c4c4bd4c Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 26 Mar 2025 15:07:29 +0100 Subject: [PATCH 093/174] Remove redundant `#undef` for `HAVE_STDLIB_H` (#4435) It's no longer defined by our build system. --- libvips/foreign/jpeg.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libvips/foreign/jpeg.h b/libvips/foreign/jpeg.h index 3eb654c237..097bc46d57 100644 --- a/libvips/foreign/jpeg.h +++ b/libvips/foreign/jpeg.h @@ -35,13 +35,6 @@ extern "C" { #endif /*__cplusplus*/ -/* jpeglib includes jconfig.h, which can define HAVE_STDLIB_H ... which we - * also define. Make sure it's turned off. - */ -#ifdef HAVE_STDLIB_H -#undef HAVE_STDLIB_H -#endif /*HAVE_STDLIB_H*/ - /* jpeglib defines its own boolean type as an enum which then clashes with * everyone elses. Rename it as jboolean. */ From dd3a19437c911bef2e714f21b35b11339f84c09b Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 26 Mar 2025 15:08:23 +0100 Subject: [PATCH 094/174] Fix vips7 compatibility layer for *magick (#4433) --- libvips/deprecated/format.c | 2 +- libvips/deprecated/im_magick2vips.c | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/libvips/deprecated/format.c b/libvips/deprecated/format.c index 877848672d..f67c203c20 100644 --- a/libvips/deprecated/format.c +++ b/libvips/deprecated/format.c @@ -296,7 +296,7 @@ im__format_init(void) vips_format_fits_get_type(); #endif /*HAVE_CFITSIO*/ vips_format_rad_get_type(); -#ifdef HAVE_MAGICK +#if defined(HAVE_MAGICK6) || defined(HAVE_MAGICK7) extern GType vips_format_magick_get_type(void); vips_format_magick_get_type(); #endif /*HAVE_MAGICK*/ diff --git a/libvips/deprecated/im_magick2vips.c b/libvips/deprecated/im_magick2vips.c index 803d247044..c0a761f58d 100644 --- a/libvips/deprecated/im_magick2vips.c +++ b/libvips/deprecated/im_magick2vips.c @@ -42,21 +42,22 @@ #include -#include "../foreign/pforeign.h" - int im_magick2vips(const char *filename, IMAGE *out) { -#ifdef HAVE_MAGICK + VipsImage *t; + /* Old behaviour was always to read all frames. */ - return vips__magick_read(filename, out, NULL, 0, -1); -#else - vips_error("im_magick2vips", - "%s", _("no libMagick support in your libvips")); + if (vips_magickload(filename, &t, "n", -1, NULL)) + return -1; + if (vips_image_write(t, out)) { + g_object_unref(t); + return -1; + } + g_object_unref(t); - return -1; -#endif /*HAVE_MAGICK*/ + return 0; } static int From 53db48d49cea96a699fb74c6713fe810e0ed805b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 29 Mar 2025 09:10:45 +0000 Subject: [PATCH 095/174] reenable caching of openslideload and invalidate on load error --- libvips/foreign/openslideload.c | 59 +++++++++++---------------------- 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/libvips/foreign/openslideload.c b/libvips/foreign/openslideload.c index a5a7f19af3..368cde1fea 100644 --- a/libvips/foreign/openslideload.c +++ b/libvips/foreign/openslideload.c @@ -447,8 +447,7 @@ readslide_attach_associated(ReadSlide *rslide, VipsImage *image) *associated_name))) return -1; - g_snprintf(buf, 256, - "openslide.associated.%s", *associated_name); + g_snprintf(buf, 256, "openslide.associated.%s", *associated_name); vips_image_set_image(image, buf, associated); g_object_unref(associated); @@ -481,21 +480,18 @@ readslide_parse(ReadSlide *rslide, VipsImage *image) rslide->osr = openslide_open(rslide->filename); if (!rslide->osr) { - vips_error("openslide2vips", - "%s", _("unsupported slide format")); + vips_error("openslide2vips", "%s", _("unsupported slide format")); return -1; } error = openslide_get_error(rslide->osr); if (error) { - vips_error("openslide2vips", - _("opening slide: %s"), error); + vips_error("openslide2vips", _("opening slide: %s"), error); return -1; } if (rslide->level < 0 || rslide->level >= openslide_get_level_count(rslide->osr)) { - vips_error("openslide2vips", - "%s", _("invalid slide level")); + vips_error("openslide2vips", "%s", _("invalid slide level")); return -1; } @@ -508,21 +504,18 @@ readslide_parse(ReadSlide *rslide, VipsImage *image) rslide->associated, &w, &h); vips_image_set_string(image, "slide-associated-image", rslide->associated); - if (vips_image_pipelinev(image, - VIPS_DEMAND_STYLE_THINSTRIP, NULL)) + if (vips_image_pipelinev(image, VIPS_DEMAND_STYLE_THINSTRIP, NULL)) return -1; } else { char buf[256]; const char *value; - openslide_get_level_dimensions(rslide->osr, - rslide->level, &w, &h); + openslide_get_level_dimensions(rslide->osr, rslide->level, &w, &h); rslide->downsample = openslide_get_level_downsample( rslide->osr, rslide->level); vips_image_set_int(image, "slide-level", rslide->level); - if (vips_image_pipelinev(image, - VIPS_DEMAND_STYLE_SMALLTILE, NULL)) + if (vips_image_pipelinev(image, VIPS_DEMAND_STYLE_SMALLTILE, NULL)) return -1; /* Try to get tile width/height. An undocumented, experimental @@ -593,8 +586,7 @@ readslide_parse(ReadSlide *rslide, VipsImage *image) } if (w > INT_MAX || h > INT_MAX) { - vips_error("openslide2vips", - "%s", _("image dimensions overflow int")); + vips_error("openslide2vips", "%s", _("image dimensions overflow int")); return -1; } @@ -613,8 +605,7 @@ readslide_parse(ReadSlide *rslide, VipsImage *image) for (properties = openslide_get_property_names(rslide->osr); *properties != NULL; properties++) { const char *name = *properties; - const char *value = - openslide_get_property_value(rslide->osr, name); + const char *value = openslide_get_property_value(rslide->osr, name); /* Can be NULL for some openslides with some images. */ @@ -630,8 +621,7 @@ readslide_parse(ReadSlide *rslide, VipsImage *image) associated_names = g_strjoinv(", ", (char **) openslide_get_associated_image_names(rslide->osr)); - vips_image_set_string(image, - "slide-associated-images", associated_names); + vips_image_set_string(image, "slide-associated-images", associated_names); VIPS_FREE(associated_names); vips_image_init_fields(image, w, h, rslide->rgb ? 3 : 4, @@ -687,7 +677,7 @@ vips__openslide_start(VipsImage *out, void *a, void *b) uint32_t *tile_buffer; if (!(tile_buffer = VIPS_MALLOC(NULL, - (size_t) rslide->tile_width * rslide->tile_height * 4))) + (size_t) rslide->tile_width * rslide->tile_height * 4))) return NULL; return (void *) tile_buffer; @@ -740,23 +730,20 @@ vips__openslide_generate(VipsRegion *out, rslide->level, r->width, r->height); - /* openslide errors are terminal. To support - * @fail we'd have to close the openslide_t and reopen, perhaps - * somehow marking this tile as unreadable. - * - * See - * https://github.com/libvips/libvips/commit/bb0a6643f94e69294e36d2b253f9bdd60c8c40ed#commitcomment-19838911 - */ error = openslide_get_error(rslide->osr); if (error) { - vips_error("openslide2vips", - _("reading region: %s"), error); + vips_error("openslide2vips", _("reading region: %s"), error); + + /* Knock the output out of cache ... openslide errors are terminal, so + * we need to force a reopen. + */ + vips_foreign_load_invalidate(rslide->out); + return -1; } if (rslide->rgb) - argb2rgb(tile_buffer, - VIPS_REGION_ADDR(out, r->left, r->top), n); + argb2rgb(tile_buffer, VIPS_REGION_ADDR(out, r->left, r->top), n); else argb2rgba(buf, n, bg); @@ -1026,13 +1013,7 @@ vips_foreign_load_openslide_class_init(VipsForeignLoadOpenslideClass *class) */ foreign_class->priority = 100; - /* libopenslide does not try to recover from errors, so it's not safe - * to cache. - */ - operation_class->flags |= VIPS_OPERATION_NOCACHE; - - /* openslide has not been fuzzed and is largly unmaintained, so should - * not be used with untrusted input unless you are very careful. + /* openslide is not fuzzed too heavily. */ operation_class->flags |= VIPS_OPERATION_UNTRUSTED; From 047cd336a9b1c25ab5481540a7a8dffb33bd8d80 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 31 Mar 2025 11:59:28 +0200 Subject: [PATCH 096/174] CI: fix macOS build (#4439) --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7c155afee..1f14750e40 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,6 +54,10 @@ jobs: if: runner.os == 'macOS' run: | pip3 install meson --break-system-packages + # Run `brew update` to ensure we have the latest formulae. + # Note: GHA macOS runners set `HOMEBREW_NO_AUTO_UPDATE=1` + # by default, as updating can be time-consuming. + brew update brew install \ ninja pkgconf \ cfitsio cgif fftw fontconfig glib \ From 1741857876e54f90c23c0fcc45f411d4522ce341 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 31 Mar 2025 11:47:13 +0100 Subject: [PATCH 097/174] WIP: experiment with gi-docgen (#3056) * sort-of works * fix some small issues * more hacking * better version numbers * oops, dropped a change * fix links in binding.md and enable external linking * rewrite `extending.xml` in markdown * rewrite using-C in markdown * rewrite file-format in markdown * move function-list to markdown and unify formatting * ready to rename links * revise * revise patterns again * generate rename list for methods * add some missing (method) annotations * more markup revision * almost there * just a few broken links now * more enum expansions in rename * oop missing comma in gen-function-list * Fix some rebase issues * Fix metadata * Clarify comment * doc: revise and port to gi-docgen linking syntax * doc: move the buf SECTION Move it to the VipsBuf struct docs. * target.c: port to gi-docgen linking syntax * doc: move the header SECTION Move it to a separate page as there's no public struct to hang the docs off. * header.c: port to gi-docgen linking syntax * Ensure GIR file includes the whole public API It was missing public API functions such as `vips_sink_disc()`. * Fix GIR warnings after bd4f4bcb * doc: move the VipsImage SECTION Move it to the struct docs. * object: ensure all `VIPS_ARG_*` function macros are introspectable * memory: ignore autocleanups when generating introspection data * Ignore private/test API when generating introspection data * Remove redundant gtk-doc comments * Remove gtk-doc workaround * doc: move the VipsRegion SECTION Move it to the struct docs. * doc: move the VipsOperation SECTION Move it to the struct docs. * doc: move the VipsObject SECTION Move it to the struct docs. Also, separate VipsArgument to its own struct doc. * doc: move the VipsThreadState SECTION Move it to the struct docs. * doc: move the VipsForeign SECTION Move it to the struct docs. Also, separate VipsForeignLoad and VipsForeignSave to its own struct doc. * doc: drop the rectangle SECTION * doc: move the connection SECTION Move it to the struct docs. * doc: move the VipsSbuf SECTION Move it to the struct docs. * doc: move the interpolator SECTION Move it to the struct docs. Also, port the whole file to gi-docgen linking syntax * Add docs for `Source`, `SourceCustom`, `Target` and `TargetCustom` * doc: move the arithmetic SECTION Move it to a separate page as there's no public struct to hang the docs off. * fix links in function-list.md * add more methods to rename * turn more func into method * Appease clang-format --------- Co-authored-by: Kleis Auke Wolthuizen --- cplusplus/meson.build | 2 +- doc/Cite.md | 18 - doc/Cite.xml | 21 - doc/Developer-checklist.xml | 173 -- doc/Examples.xml | 93 - doc/How-it-opens-files.xml | 105 -- doc/How-it-works.xml | 279 --- doc/Making-image-pyramids.xml | 189 -- doc/Using-vipsthumbnail.xml | 310 --- doc/binding.md | 66 +- doc/binding.xml | 222 --- doc/cite.md | 12 + ...er-checklist.md => developer-checklist.md} | 46 +- doc/{Examples.md => examples.md} | 60 +- doc/extending.md | 350 ++++ doc/extending.xml | 462 ----- doc/file-format.md | 91 + doc/file-format.xml | 245 --- doc/function-list.md | 360 ++++ doc/function-list.xml | 1657 ----------------- doc/gen-function-list.py | 81 +- ...t-opens-files.md => how-it-opens-files.md} | 35 +- doc/{How-it-works.md => how-it-works.md} | 183 +- doc/images/x.jpg | Bin 6861 -> 0 bytes doc/libvips-arithmetic.md | 193 ++ doc/libvips-docs.xml | 108 -- doc/libvips-from-C++.md | 19 - doc/libvips-from-C++.xml | 21 - doc/libvips-header.md | 122 ++ ...e-pyramids.md => making-image-pyramids.md} | 66 +- doc/meson.build | 213 +-- doc/multipage-and-animated-images.md | 27 +- doc/multipage-and-animated-images.xml | 221 --- doc/pandoc-docbook-template.docbook | 21 - doc/rename.sed | 347 ++++ doc/rename.sh | 5 + doc/urlmap.js | 6 + doc/using-C.xml | 370 ---- doc/using-command-line.xml | 236 --- doc/using-from-c.md | 288 +++ doc/using-from-cplusplus.md | 10 + doc/using-the-cli.md | 164 ++ doc/using-threads.md | 180 ++ doc/using-threads.xml | 232 --- ...ipsthumbnail.md => using-vipsthumbnail.md} | 55 +- doc/version.xml.in | 1 - doc/vips.toml.in | 79 + libvips/arithmetic/add.c | 2 +- libvips/arithmetic/arithmetic.c | 207 -- libvips/arithmetic/boolean.c | 12 +- libvips/arithmetic/complex.c | 6 +- libvips/arithmetic/divide.c | 2 +- libvips/arithmetic/math2.c | 8 +- libvips/arithmetic/maxpair.c | 2 +- libvips/arithmetic/minpair.c | 2 +- libvips/arithmetic/multiply.c | 2 +- libvips/arithmetic/relational.c | 14 +- libvips/arithmetic/remainder.c | 2 +- libvips/arithmetic/subtract.c | 2 +- libvips/colour/dE00.c | 2 +- libvips/colour/dE76.c | 2 +- libvips/colour/dECMC.c | 2 +- libvips/conversion/bandjoin.c | 2 +- libvips/conversion/embed.c | 2 +- libvips/conversion/ifthenelse.c | 2 +- libvips/conversion/join.c | 2 +- libvips/create/gaussnoise.c | 1 + libvips/create/perlin.c | 1 + libvips/create/worley.c | 1 + libvips/deprecated/format.c | 4 +- libvips/foreign/foreign.c | 101 +- libvips/freqfilt/phasecor.c | 2 +- libvips/include/vips/basic.h | 4 + libvips/include/vips/buf.h | 5 - libvips/include/vips/connection.h | 54 +- libvips/include/vips/foreign.h | 6 - libvips/include/vips/format.h | 10 +- libvips/include/vips/gate.h | 11 - libvips/include/vips/image.h | 2 - libvips/include/vips/internal.h | 55 + libvips/include/vips/interpolate.h | 2 - libvips/include/vips/memory.h | 4 + libvips/include/vips/meson.build | 27 +- libvips/include/vips/object.h | 32 +- libvips/include/vips/operation.h | 2 - libvips/include/vips/private.h | 50 + libvips/include/vips/region.h | 2 - libvips/include/vips/thread.h | 10 +- libvips/include/vips/threadpool.h | 6 - libvips/include/vips/type.h | 4 + libvips/include/vips/util.h | 78 +- libvips/include/vips/vector.h | 4 - libvips/iofuncs/buf.c | 14 +- libvips/iofuncs/connection.c | 28 +- libvips/iofuncs/generate.c | 9 +- libvips/iofuncs/ginputsource.c | 2 +- libvips/iofuncs/header.c | 292 ++- libvips/iofuncs/image.c | 89 +- libvips/iofuncs/object.c | 143 +- libvips/iofuncs/operation.c | 85 +- libvips/iofuncs/rect.c | 12 +- libvips/iofuncs/region.c | 36 +- libvips/iofuncs/sbuf.c | 15 +- libvips/iofuncs/sink.c | 12 +- libvips/iofuncs/sinkdisc.c | 4 +- libvips/iofuncs/sinkscreen.c | 4 +- libvips/iofuncs/source.c | 54 +- libvips/iofuncs/sourceginput.c | 2 +- libvips/iofuncs/target.c | 74 +- libvips/iofuncs/thread.c | 10 + libvips/iofuncs/threadpool.c | 43 +- libvips/iofuncs/threadset.c | 6 +- libvips/iofuncs/util.c | 128 +- libvips/meson.build | 5 +- libvips/mosaicing/match.c | 2 +- libvips/mosaicing/merge.c | 2 +- libvips/mosaicing/mosaic.c | 2 +- libvips/mosaicing/mosaic1.c | 2 +- libvips/resample/interpolate.c | 56 +- libvips/resample/reduce.c | 64 - libvips/resample/reduceh.cpp | 31 +- libvips/resample/reducev.cpp | 31 +- meson.build | 10 +- meson_options.txt | 8 +- 124 files changed, 3509 insertions(+), 6563 deletions(-) delete mode 100644 doc/Cite.md delete mode 100644 doc/Cite.xml delete mode 100644 doc/Developer-checklist.xml delete mode 100644 doc/Examples.xml delete mode 100644 doc/How-it-opens-files.xml delete mode 100644 doc/How-it-works.xml delete mode 100644 doc/Making-image-pyramids.xml delete mode 100644 doc/Using-vipsthumbnail.xml delete mode 100644 doc/binding.xml create mode 100644 doc/cite.md rename doc/{Developer-checklist.md => developer-checklist.md} (80%) rename doc/{Examples.md => examples.md} (61%) create mode 100644 doc/extending.md delete mode 100644 doc/extending.xml create mode 100644 doc/file-format.md delete mode 100644 doc/file-format.xml create mode 100644 doc/function-list.md delete mode 100644 doc/function-list.xml rename doc/{How-it-opens-files.md => how-it-opens-files.md} (86%) rename doc/{How-it-works.md => how-it-works.md} (61%) delete mode 100644 doc/images/x.jpg create mode 100644 doc/libvips-arithmetic.md delete mode 100644 doc/libvips-docs.xml delete mode 100644 doc/libvips-from-C++.md delete mode 100644 doc/libvips-from-C++.xml create mode 100644 doc/libvips-header.md rename doc/{Making-image-pyramids.md => making-image-pyramids.md} (79%) delete mode 100644 doc/multipage-and-animated-images.xml delete mode 100644 doc/pandoc-docbook-template.docbook create mode 100644 doc/rename.sed create mode 100755 doc/rename.sh create mode 100644 doc/urlmap.js delete mode 100644 doc/using-C.xml delete mode 100644 doc/using-command-line.xml create mode 100644 doc/using-from-c.md create mode 100644 doc/using-from-cplusplus.md create mode 100644 doc/using-the-cli.md create mode 100644 doc/using-threads.md delete mode 100644 doc/using-threads.xml rename doc/{Using-vipsthumbnail.md => using-vipsthumbnail.md} (91%) delete mode 100644 doc/version.xml.in create mode 100644 doc/vips.toml.in diff --git a/cplusplus/meson.build b/cplusplus/meson.build index a47ad6ccf4..66ecf2855f 100644 --- a/cplusplus/meson.build +++ b/cplusplus/meson.build @@ -39,7 +39,7 @@ custom_target('vips-operators-source', output: 'vips-operators.cpp' ) -if get_option('doxygen') +if get_option('cpp-docs') doxygen = find_program('doxygen') doxygen_data = configuration_data() doxygen_data.set('VIPS_MAJOR_VERSION', version_major) diff --git a/doc/Cite.md b/doc/Cite.md deleted file mode 100644 index a8f880c3d6..0000000000 --- a/doc/Cite.md +++ /dev/null @@ -1,18 +0,0 @@ - - Cite - 3 - libvips - - - - Cite - References to cite for libvips - - -Martinez, K. and Cupitt, J. (2005) -VIPS -- a highly tuned image processing software architecture. In Proceedings of IEEE International -Conference on Image Processing 2, pp. 574-577, Genova. - -Cupitt, J. and Martinez, K. (1996) -VIPS: An image processing system for large images, Proc. SPIE, vol. 2663, pp. 19--28. - diff --git a/doc/Cite.xml b/doc/Cite.xml deleted file mode 100644 index 871eb86fd5..0000000000 --- a/doc/Cite.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - Cite 3 libvips - - - Cite References to cite for libvips - - - Martinez, K. and Cupitt, J. (2005) VIPS – a highly tuned image processing software architecture. In Proceedings of IEEE International Conference on Image Processing 2, pp. 574-577, Genova. - - - Cupitt, J. and Martinez, K. (1996) VIPS: An image processing system for large images, Proc. SPIE, vol. 2663, pp. 19–28. - - - - diff --git a/doc/Developer-checklist.xml b/doc/Developer-checklist.xml deleted file mode 100644 index c4227e7ecf..0000000000 --- a/doc/Developer-checklist.xml +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - - Developer checklist 3 libvips - - - Dev checklist Checklist for libvips users - - - libvips is a slightly unusual library and you may need to take some of its stranger features into account when you design software that uses it. - - - Codestin Search App - - The thumbnail operation combines load and resize into one step. This lets it take advantage of format library features, such as shrink on load, and can lead to a large improvement in speed and a large drop in memory use. - - - For example, with this JPEG image: - - -$ vipsheader nina.jpg -nina.jpg: 6048x4032 uchar, 3 bands, srgb, jpegload - - - I see: - - -$ /usr/bin/time -f %M:%e vips resize nina.jpg x.jpg 0.1 -123648:0.23 - - - 124 MB of RAM and 0.23s to shink by a factor of 10. With thumbnail it’s: - - -$ /usr/bin/time -f %M:%e vips thumbnail nina.jpg x.jpg 605 -68864:0.08 - - - Now it’s 68 MB of memory and 0.08s – half the memory use, and 3x faster. In fact the improvement is better than that, since the vips command takes a while to start and needs a fair amount of memory: - - -$ /usr/bin/time -f %M:%e vips > /dev/null -31232:0.02 - - - 31 MB and 0.02s, so thumbnail is really 2.5x less memory and 4x faster. - - - You can see much larger improvements with other formats, and quality will often be better as well, since thumbnail will automatically premultiply and can render vector images directly at the correct size. - - - - Codestin Search App - - It’s just there for emergencies. It can’t do any of the rendering tricks, so it’s no faster than resize. Use thumbnail if you can. - - - - Codestin Search App - - This is a hint you pass to new_from_file and friends that signals that you will only scan this image in the direction that the underlying load library supports. This can give a useful improvement in speed and reduction in memory use in many cases. - - - See the How it opens files chapter for background on this feature. - - - - Codestin Search App - - libvips is demand-driven, and uses partial images as intermediates. This means you can construct long pipelines of image processing operations, they won’t use much memory, and they’ll (usually) join efficiently. - - - libvips is horizontally threaded, meaning that threads run along the pipeline of operations you are evaluating, not up and down images. This means that libvips can (usually) parallelise longer pipelines more efficiently than short ones. - - - If you can, aim for long pipelines of processing operations. - - - - Codestin Search App - - If an image is reused repeatedly in one pipeline, it’ll be recomputed each time. You can sometimes get a big speedup by keeping images like this in memory rather than recalculating their pixels, see (for example), copy_memory() in pyvips. - - - This can raise memory use, of course. - - - - Codestin Search App - - If you can, put large resizes right at the start (see thumbnail above), then area filters (sharpen, for example), and finally any point operations. - - - - Codestin Search App - - libvips after version 8.13 has a system for enabling and disabling image load libraries at runtime, see: - - - https://www.libvips.org/2022/05/28/What’s-new-in-8.13.html - - - You can usually improve security and avoid memory spikes by only enabling the image formats you really need. If you are handling untrusted data, I would set the VIPS_BLOCK_UNTRUSTED env var and only use the loaders we have tested for security. - - - Older versions of libvips need compile-time configuration. - - - - Codestin Search App - - libvips image open is always fast and safe, as long as you have disabled load via imagemagick. This means you can open an image and sanity-check it before further processing. - - - There are two main checks that are very worthwhile: - - - - - Sanity check image dimensions to protect you from decompression bombs like those described at https://www.bamsoftware.com/hacks/deflate.html - - - - - Check for interlaced (also called progressive) images. - - - These are the ones that appear in low detail first, then progressively sharpen as they are downloaded. - - - The downside is that you don’t get the final pixels until the whole image is in memory, which prevents any streaming processing and hugely increases memory use. For example: - - - - -$ /usr/bin/time -f %M:%e vipsthumbnail big-progressive.jpg -3732224:4.23 -$ vips copy big-progressive.jpg x.jpg -$ /usr/bin/time -f %M:%e vipsthumbnail x.jpg -72448:0.26 - - - So this progressive jpeg takes 4gb of memory and 4.3s to thumbnail, but exactly the same image as a regular jpeg takes 72mb and 0.26s. - - - I would detect these horrors before processing by looking for the interlaced metadata item and either ban them, or if your users insist on uploading in this terrible format, push them to a separate low-priority queue on a special container. Keep them away from your main image path. - - - - Codestin Search App - - The default memory allocator on most glibc-based Linux systems (e.g. Debian, Red Hat) is unsuitable for long-running, multi-threaded processes that involve lots of small memory allocations. - - - To help avoid fragmentation and improve performance on these systems, the use of an alternative memory allocator such as jemalloc is recommended. - - - Those using musl-based Linux (e.g. Alpine) and non-Linux systems are unaffected. - - - - Codestin Search App - - The libvips operation cache is not useful for image proxies (i.e. processing many different images). Consider disabling this with vips_cache_set_max(0);. - - - - - diff --git a/doc/Examples.xml b/doc/Examples.xml deleted file mode 100644 index 56751d0a66..0000000000 --- a/doc/Examples.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - Examples 3 libvips - - - libvips examples A few example Python programs using libvips - - - This page shows a few libvips examples using Python. They will work with small syntax changes in any language with a libvips binding. - - - The libvips test suite is written in Python and exercises every operation in the API. It’s also a useful source of examples. - - - Codestin Search App - -#!/usr/bin/python3 - -import sys -import pyvips - -left = 10 -top = 10 -width = 64 -height = 64 - -image = pyvips.Image.new_from_file(sys.argv[1]) -roi = image.crop(left, top, width, height) -print('average:', roi.avg()) - - - - Codestin Search App - - This makes a 100,000 x 100,000 black image, then inserts all the images you pass on the command-line into it at random positions. libvips is able to run this program in sequential mode: it’ll open all the input images at the same time, and stream pixels from them as it needs them to generate the output. - - - To test it, first make a large 1-bit image. This command will take the green channel and write as a 1-bit fax image. wtc.jpg is a test 10,000 x 10,000 jpeg: - - -$ vips extract_band wtc.jpg x.tif[squash,compression=ccittfax4,keep=none] 1 - - - Now make 1,000 copies of that image in a subdirectory: - - -$ mkdir test -$ for i in {1..1000}; do cp x.tif test/$i.tif; done - - - And run this Python program on them: - - -$ time python try255.py x.tif[squash,compression=ccittfax4,strip,bigtiff] test/* -real 1m59.924s -user 4m5.388s -sys 0m8.936s - - - It completes in just under two minutes on this laptop, and needs about 7gb of RAM to run. It would need about the same amount of memory for a full-colour RGB image, I was just keen to keep disc usage down. - - - If you wanted to handle transparency, or if you wanted mixed CMYK and RGB images, you’d need to do some more work to convert them all into the same colourspace before inserting them. - - -#!/usr/bin/python3 -#file try255.py - -import sys -import random -import pyvips - -# this makes a 8-bit, mono image of 100,000 x 100,000 pixels, each pixel zero -im = pyvips.Image.black(100000, 100000) - -for filename in sys.argv[2:]: - tile = pyvips.Image.new_from_file(filename, access='sequential') - - im = im.insert(tile, - random.randint(0, im.width - tile.width), - random.randint(0, im.height - tile.height)) - -im.write_to_file(sys.argv[1]) - - - - - diff --git a/doc/How-it-opens-files.xml b/doc/How-it-opens-files.xml deleted file mode 100644 index cfcd058e1c..0000000000 --- a/doc/How-it-opens-files.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - Opening files 3 libvips - - - Opening How libvips opens files - - - libvips has at least four different ways of opening image files, each best for different file types, file sizes and image use cases. libvips tries hard to pick the best strategy in each case and mostly you don’t need to know what it is doing behind the scenes, except unfortunately when you do. - - - This page tries to explain what the different strategies are and when each is used. If you are running into unexpected memory, disc or CPU use, this might be helpful. vips_image_new_from_file() has the official documentation. - - - Codestin Search App - - libvips caches recent operations. This means that if a file changes between one load and the next, the second load will return the old image, even though the file has been replaced. - - - You can force libvips to load a file and ignore any cached value by setting the revalidate flag, see #VipsForeignLoad. - - - - Codestin Search App - - This is the fastest and simplest one. The file is mapped directly into the process’s address space and can be read with ordinary pointer access. Small files are completely mapped; large files are mapped in a series of small windows that are shared and which scroll about as pixels are read. Files which are accessed like this can be read by many threads at once, making them especially quick. They also interact well with the computer’s operating system: your OS will use spare memory to cache recently used chunks of the file. - - - For this to be possible, the file format needs to be a simple dump of a memory array. libvips supports direct access for vips, 8-bit binary ppm/pbm/pnm, analyse and raw. - - - libvips has a special direct write mode where pixels can be written directly to the file image. This is used for the draw operators. - - - - Codestin Search App - - Some image file formats have libraries which allow true random access to image pixels. For example, libtiff lets you read any tile out of a tiled tiff image very quickly. Because the libraries allow true random access, libvips can simply hook the image load library up to the input of the operation pipeline. - - - These libraries are generally single-threaded, so only one thread may read at once, making them slower than simple direct access. Additionally, tiles are often compressed, meaning that each time a tile is fetched it must be decompressed. libvips keeps a cache of recently-decompressed tiles to try to avoid repeatedly decompressing the same tile. - - - libvips can load tiled tiff, tiled OpenEXR, FITS and OpenSlide images in this manner. - - - - Codestin Search App - - Many image load libraries do not support random access. In order to use images of this type as inputs to pipelines, libvips has to convert them to a random access format first. - - - For small images (less than 100mb when decompressed), libvips allocates a large area of memory and decompresses the entire image to that. It then uses that memory buffer of decompressed pixels to feed the pipeline. For large images, libvips decompresses to a temporary file on disc, then loads that temporary file in direct access mode (see above). Note that on open libvips just reads the image header and is quick: the image decompress happens on the first pixel access. - - - You can control this process with environment variables, command-line flags and API calls as you choose, see vips_image_new_from_file(). They let you set the threshold at which libvips switches between memory and disc and where on disc the temporary files are held. - - - This is the slowest and most memory-hungry way to read files, but it’s unavoidable for many file formats. Unless you can use the next one! - - - - Codestin Search App - - This a fairly recent addition to libvips and is a hybrid of the previous two. - - - Imagine how this command might be executed: - - -$ vips flip fred.jpg jim.jpg vertical - - - meaning, read fred.jpg, flip it up-down, and write as jim.jpg. - - - In order to write jim.jpg top-to-bottom, it’ll have to read fred.jpg bottom-to-top. Unfortunately libjpeg only supports top-to-bottom reading and writing, so libvips must convert fred.jpg to a random access format before it can run the flip operation. - - - However many useful operations do not require true random access. For example: - - -$ vips shrink fred.png jim.png 10 10 - - - meaning shrink fred.png by a factor of 10 in both axes and write as jim.png. - - - You can imagine this operation running without needing fred.png to be completely decompressed first. You just read 10 lines from fred.png for every one line you write to jim.png. - - - To help in this case, libvips has a hint you can give to loaders to say I will only need pixels from this image in top-to-bottom order. With this hint set, libvips will hook up the pipeline of operations directly to the read-a-line interface provided by the image library, and add a small cache of the most recent 100 or so lines. - - - This is done automatically in command-line operation. In programs, you need to set access to #VIPS_ACCESS_SEQUENTIAL in calls to functions like vips_image_new_from_file(). - - - - - diff --git a/doc/How-it-works.xml b/doc/How-it-works.xml deleted file mode 100644 index b237b3e570..0000000000 --- a/doc/How-it-works.xml +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - - How libvips works 3 libvips - - - Internals A high-level technical overview of libvips’s evaluation system - - - Compared to most image processing libraries, VIPS needs little RAM and runs quickly, especially on machines with more than one CPU. VIPS achieves this improvement by only keeping the pixels currently being processed in RAM and by having an efficient, threaded image IO system. This page explains how these features are implemented. - - - Images - - - VIPS images have three dimensions: width, height and bands. Bands usually (though not always) represent colour. These three dimensions can be any size up to 2 ** 31 elements. Every band element in an image has to have the same format. A format is an 8-, 16- or 32-bit int, signed or unsigned, 32- or 64-bit float, and 64- or 128-bit complex. - - - Regions - - - An image can be very large, much larger than the available memory, so you can’t just access pixels with a pointer *. - - - Instead, you read pixels from an image with a region. This is a rectangular sub-area of an image. In C, the API looks like: - - -VipsImage *image = vips_image_new_from_file(filename, NULL); -VipsRegion *region = vips_region_new(image); - -// ask for a 100x100 pixel region at 0x0 (top left) -VipsRect r = { .left = 0, .top = 0, .width = 100, .height = 100 }; -if (vips_region_prepare(region, &r)) - vips_error(...); - -// get a pointer to the pixel at x, y, where x, y must -// be within the region - -// as long as you stay within the valid area for the region, -// you can address pixels with regular pointer arithmetic - -// compile with -DDEBUG and the macro will check bounds for you - -// add VIPS_REGION_LSKIP() to move down a line -VipsPel *pixel = VIPS_REGION_ADDR(region, x, y); - -// you can call vips_region_prepare() many times - -// everything in libvips is a GObject ... when you're done, -// just free with -g_object_unref(region); - - - The action that vips_region_prepare() takes varies with the type of image. If the image is a file on disc, for example, then VIPS will arrange for a section of the file to be read in. - - - (* there is an image access mode where you can just use a pointer, but it’s rarely used) - - - Partial images - - - A partial image is one where, instead of storing a value for each pixel, VIPS stores a function which can make any rectangular area of pixels on demand. - - - If you use vips_region_prepare() on a region created on a partial image, VIPS will allocate enough memory to hold the pixels you asked for and use the stored function to calculate values for just those pixels *. - - - The stored function comes in three parts: a start function, a generate function and a stop function. The start function creates a state, the generate function uses the state plus a requested area to calculate pixel values and the stop function frees the state again. Breaking the stored function into three parts is good for SMP scaling: resource allocation and synchronisation mostly happens in start functions, so generate functions can run without having to talk to each other. - - - VIPS makes a set of guarantees about parallelism that make this simple to program. Start and stop functions are mutually exclusive and a state is never used by more than one generate. In other words, a start / generate / generate / stop sequence works like a thread. - - - - - - - - - - (* in fact VIPS keeps a cache of calculated pixel buffers and will return a pointer to a previously-calculated buffer if it can) - - - Operations - - - VIPS operations read input images and write output images, performing some transformation on the pixels. When an operation writes to an image the action it takes depends upon the image type. For example, if the image is a file on disc then VIPS will start a data sink to stream pixels to the file, or if the image is a partial one then it will just attach start / generate / stop functions. - - - Like most threaded image processing systems, all VIPS operations have to be free of side-effects. In other words, operations cannot modify images, they can only create new images. This could result in a lot of copying if an operation is only making a small change to a large image so VIPS has a set of mechanisms to copy image areas by just adjusting pointers. Most of the time no actual copying is necessary and you can perform operations on large images at low cost. - - - SIMD optimisations - - - VIPS uses Highway, a C++ library, to optimise various operations with SIMD/vector instructions. These optimised code paths are flexible and can adapt to different instruction sets, including those with scalable vectors (size unknown at compile time). At runtime, dynamic dispatch selects the best available implementation based on the processor’s capabilities, ensuring optimal performance. - - - SIMD typically speeds operations up by a factor of three or four. - - - Joining operations together - - - The region create / prepare / prepare / free calls you use to get pixels from an image are an exact parallel to the start / generate / generate / stop calls that images use to create pixels. In fact, they are the same: a region on a partial image holds the state created by that image for the generate function that will fill the region with pixels. - - - - - - - - - - VIPS joins image processing operations together by linking the output of one operation (the start / generate / stop sequence) to the input of the next (the region it uses to get pixels for processing). This link is a single function call, and very fast. Additionally, because of the the split between allocation and processing, once a pipeline of operations has been set up, VIPS is able to run without allocating and freeing memory. - - - This graph (generated by vipsprofile, the vips profiler) shows memory use over time for a vips pipeline running on a large image. The bottom trace shows total memory, the upper traces show threads calculating useful results (green), threads blocked on synchronisation (red) and memory allocations (white ticks). - - - - - - - - - - Because the intermediate image is just a small region in memory, a pipeline of operations running together needs very little RAM. In fact, intermediates are small enough that they can fit in L2 cache on most machines, so an entire pipeline can run without touching main memory. And finally, because each thread runs a very cheap copy of just the writeable state of the entire pipeline, threads can run with few locks. VIPS needs just four lock operations per output tile, regardless of the pipeline length or complexity. - - - Data sources - - - VIPS has data sources which can supply pixels for processing from a variety of sources. VIPS can stream images from files in VIPS native format, from tiled TIFF files, from binary PPM/PGM/PBM/PFM, from Radiance (HDR) files, from FITS images and from tiled OpenEXR images. VIPS will automatically unpack other formats to temporary disc files for you but this can obviously generate a lot of disc traffic. It also has a special sequential mode for streaming operations on non-random-access formats. Another section in these docs explains how libvips opens a file. One of the sources uses the ImageMagick (or optionally GraphicsMagick library, so VIPS can read any image format that these libraries can read. - - - VIPS images are held on disc as a 64-byte header containing basic image information like width, height, bands and format, then the image data as a single large block of pixels, left-to-right and top-to-bottom, then an XML extension block holding all the image metadata, such as ICC profiles and EXIF blocks. - - - When reading from a large VIPS image (or any other format with the same structure on disc, such as binary PPM), VIPS keeps a set of small rolling windows into the file, some small number of scanlines in size. As pixels are demanded by different threads VIPS will move these windows up and down the file. As a result, VIPS can process images much larger than RAM, even on 32-bit machines. - - - Data sinks - - - In a demand-driven system, something has to do the demanding. VIPS has a variety of data sinks that you can use to pull image data though a pipeline in various situations. There are sinks that will build a complete image in memory, sinks to draw to a display, sinks to loop over an image (useful for statistical operations, for example) and sinks to stream an image to disc. - - - The disc sink looks something like this: - - - - - - - - - - The sink keeps two buffers*, each as wide as the image. It starts threads as rapidly as it can up to the concurrency limit, filling each buffer with tiles** of calculated pixels, each thread calculating one tile at once. A separate background thread watches each buffer and, as soon as the last tile in a buffer finishes, writes that complete set of scanlines to disc using whatever image write library is appropriate. VIPS can write with libjpeg, libtiff, libpng and others. It then wipes the buffer and repositions it further down the image, ready for the next set of tiles to stream in. - - - These features in combination mean that, once a pipeline of image processing operations has been built, VIPS can run almost lock-free. This is very important for SMP scaling: you don’t want the synchronization overhead to scale with either the number of threads or the complexity of the pipeline of operations being performed. As a result, VIPS scales almost linearly with increasing numbers of threads: - - - - - - - - - - Number of CPUs is on the horizontal axis, speedup is on the vertical axis. Taken from the [[Benchmarks]] page. - - - (* there can actually be more than one, it allocate enough buffers to ensure that there are at least two tiles for every thread) - - - (** tiles can be any shape and size, VIPS has a tile hint system that operations use to tell sinks what tile geometry they prefer) - - - Operation cache - - - Because VIPS operations are free of side-effects*, you can cache them. Every time you call an operation, VIPS searches the cache for a previous call to the same operation with the same arguments. If it finds a match, you get the previous result again. This can give a huge speedup. - - - By default, VIPS caches the last 100 operation calls. You can also control the cache size by memory use or by files opened. - - - (* Some vips operations DO have side effects, for example, vips_draw_circle() will draw a circle on an image. These operations emit an invalidate signal on the image they are called on and this signal makes all downstream operations and caches drop their contents.) - - - Operation database and APIs - - - VIPS has around 300 image processing operations written in this style. Each operation is a GObject class. You can use the standard GObject calls to walk the class hierarchy and discover operations, and libvips adds a small amount of extra introspection metadata to handle things like optional arguments. - - - The C API is a set of simple wrappers which create class instances for you. The C++ API is a little fancier and adds things like automatic object lifetime management. The command-line interface uses introspection to run any vips operation in the class hierarchy. - - - There are bindings for many other languages on many platforms. Most of these bindings use the introspection system to generate the binding at run-time. - - - Snip - - - The VIPS GUI, nip2, has its own scripting language called Snip. Snip is a lazy, higher-order, purely functional, object oriented language. Almost all of nip2’s menus are implemented in it, and nip2 workspaces are Snip programs. - - - VIPS operations listed in the operation database appear as Snip functions. For example, abs can be used from Snip as: - - -// absolute value of image b -a = vips_call "abs" [b] []; - - - However, abs won’t work on anything except the primitive vips image type. It can’t be used on any class, or list or number. Definitions in _stdenv.dev wrap each VIPS operation as a higher level Snip operation. For example: - - -abs x - = oo_unary_function abs_op x, is_class x - = vips_call "abs" [x] [], is_image x - = abs_cmplx x, is_complex x - = abs_num x, is_real x - = abs_list x, is_real_list x - = abs_list (map abs_list x), is_matrix x - = error (_ "bad arguments to " ++ "abs") -{ - abs_op = Operator "abs" abs Operator_type.COMPOUND false; - - abs_list l = (sum (map square l)) ** 0.5; - - abs_num n - = n, n >= 0 - = -n; - - abs_cmplx c = ((re c)**2 + (im c)**2) ** 0.5; -} - - - This defines the behaviour of abs for the base Snip types (number, list, matrix, image and so on), then classes will use that to define operator behaviour on higher-level objects. - - - Now you can use: - - -// absolute value of anything -a = abs b; - - - and you ought to get sane behaviour for any object, including things like the Matrix class. - - - You can write Snip classes which present functions to the user as menu items. For example, Math.def has this: - - -Math_arithmetic_item = class - Menupullright "_Arithmetic" "basic arithmetic for objects" { - - Absolute_value_item = class - Menuaction "A_bsolute Value" "absolute value of x" { - action x = map_unary abs x; - } -} - - - Now the user can select an object and click Math / Abs to find the absolute value of that object. - - - - diff --git a/doc/Making-image-pyramids.xml b/doc/Making-image-pyramids.xml deleted file mode 100644 index 5ba725152d..0000000000 --- a/doc/Making-image-pyramids.xml +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - - Image pyramids 3 libvips - - - Pyramids How to use libvips to make image pyramids - - - libvips includes vips_dzsave(), an operation that can build image pyramids compatible with DeepZoom, Zoomify and Google Maps image viewers. It’s fast and can generate pyramids for large images using only a small amount of memory. - - - The TIFF writer, vips_tiffsave() can also build tiled pyramidal TIFF images, but that’s very simple to use. This page concentrates on the DeepZoom builder. - - - Run dzsave with no arguments to see a summary: - - -$ vips dzsave -save image to deepzoom file -usage: - dzsave in filename [--option-name option-value ...] -where: - in - Image to save, input VipsImage - filename - Filename to save to, input gchararray -optional arguments: - imagename - Image name, input gchararray - layout - Directory layout, input VipsForeignDzLayout - default enum: dz - allowed enums: dz, zoomify, google, iiif, iiif3 - suffix - Filename suffix for tiles, input gchararray - overlap - Tile overlap in pixels, input gint - default: 1 - min: 0, max: 8192 - tile-size - Tile size in pixels, input gint - default: 254 - min: 1, max: 8192 - centre - Center image in tile, input gboolean - default: false - depth - Pyramid depth, input VipsForeignDzDepth - default enum: onepixel - allowed enums: onepixel, onetile, one - angle - Rotate image during save, input VipsAngle - default enum: d0 - allowed enums: d0, d90, d180, d270 - container - Pyramid container type, input VipsForeignDzContainer - default enum: fs - allowed enums: fs, zip, szi - compression - ZIP deflate compression level, input gint - default: 0 - min: -1, max: 9 - region-shrink - Method to shrink regions, input VipsRegionShrink - default enum: mean - allowed enums: mean, median, mode, max, min, nearest - skip-blanks - Skip tiles which are nearly equal to the background, input gint - default: -1 - min: -1, max: 65535 - id - Resource ID, input gchararray - Q - Q factor, input gint - default: 75 - min: 1, max: 100 - keep - Which metadata to retain, input VipsForeignKeep - default flags: exif:xmp:iptc:icc:other:all - allowed flags: none, exif, xmp, iptc, icc, other, all - background - Background value, input VipsArrayDouble -operation flags: sequential nocache - - - You can also call vips_dzsave() from any language with a libvips binding, or by using .dz or .szi as an output file suffix. - - - Codestin Search App - - The --layout option sets the basic mode of operation. With no --layout, dzsave writes DeepZoom pyramids. For example: - - -$ vips dzsave huge.tif mydz - - - This will create a directory called mydz_files containing the image tiles, and write a file called mydz.dzi containing the image metadata. - - - You can use the --suffix option to control how tiles are written. For example: - - -$ vips dzsave huge.tif mydz --suffix .jpg[Q=90] - - - will write JPEG tiles with the quality factor set to 90. You can set any format write options you like, see the API docs for vips_jpegsave() for details. - - - - Codestin Search App - - Use --layout zoomify to put dzsave into zoomify mode. For example: - - -$ vips dzsave huge.tif myzoom --layout zoomify - - - This will create a directory called myzoom containing a file called ImageProperties.xml with the image metadata in, and a series of directories called TileGroupn, each containing 256 image tiles. - - - As with DeepZoom, you can use --suffix to set jpeg quality. - - - - Codestin Search App - - Use --layout google to write Google maps-style pyramids. These are compatible with Leaflet. For example: - - -$ vips dzsave wtc.tif gmapdir --layout google - - - Will create a directory called gmapdir containing blank.png, the file to display for blank tiles, and a set of numbered directories, one for each zoom level. The pyramid can be sparse (blank tiles are not written). - - - As with DeepZoom, you can use --suffix to set jpeg quality. - - - Use --background to set the background colour. This is the colour displayed for bits of the pyramid not in the image (image edges, for example). By default, the image background is white. - - - Use --centre to add a border to the image large enough to centre the image within the lowest resolution tile. By default, images are not centred. - - - For example: - - -$ vips dzsave wtc.tif gmapdir --layout google --background 0 --centre - - - - Codestin Search App - - You can use --tile-size and --overlap to control how large the tiles are and how they overlap (obviously). They default to the correct values for the selected layout. - - - You can use --depth to control how deep the pyramid should be. Possible values are onepixel, onetile and one. onepixel means the image is shrunk until it fits within a single pixel. onetile means shrink until it fits with a tile. one means only write one pyramid layer (the highest resolution one). It defaults to the correct value for the selected layout. --depth one is handy for slicing up a large image into tiles (rather than a pyramid). - - - You can use --angle to do a 90, 180 or 270 degree rotate of an image during pyramid write. - - - You can use --container to set the container type. Normally dzsave will write a tree of directories, but with --container zip you’ll get a zip file instead. Use .zip as the directory suffix to turn on zip format automatically: - - -$ vips dzsave wtc.tif mypyr.zip - - - to write a zipfile containing the tiles. You can use .szi as a suffix to enable zip output as well. - - - - Codestin Search App - - You can use .dz as a filename suffix, meaning send the image to vips_dzsave(). This means you can write the output of any vips operation to a pyramid. For example: - - -$ vips extract_area huge.svs mypy.dz[layout=google] 100 100 10000 10000 - - - The arguments to extract_area are image-in, image-out, left, top, width, height. So this command will cut out a 10,000 by 10,000 pixel area from near the top-left-hand corner of an Aperio slide image, then build a pyramid in Google layout using just those pixels. - - - If you are working from OpenSlide images, you can use the shrink-on-load feature of many of those formats. For example: - - -$ vips dzsave CMU-1.mrxs[level=1] x - - - Will pull out level 1 (the half-resolution level of an MRXS slide) and make a pyramid from that. - - - - Codestin Search App - - If you are building vips from source you do need to check the summary at the end of configure carefully. You must have the libarchive-dev package for vips_dzsave() to work. - - - - - diff --git a/doc/Using-vipsthumbnail.xml b/doc/Using-vipsthumbnail.xml deleted file mode 100644 index 445f62836b..0000000000 --- a/doc/Using-vipsthumbnail.xml +++ /dev/null @@ -1,310 +0,0 @@ - - - - - - - Using vipsthumbnail 3 libvips - - - vipsthumbnail Introduction to vipsthumbnail, with examples - - - libvips ships with a handy command-line image thumbnailer, vipsthumbnail. This page introduces it, with some examples. - - - The thumbnailing functionality is implemented by vips_thumbnail() and vips_thumbnail_buffer() (which thumbnails an image held as a string), see the docs for details. You can use these functions from any language with a libvips binding. For example, from PHP you could write: - - -$filename = "image.jpg"; -$image = Vips\Image::thumbnail($filename, 200, ["height" => 200]); -$image->writeToFile("my-thumbnail.jpg"); - - - You can also call thumbnail_source from the CLI, for example: - - -$ cat k2.jpg | \ - vips thumbnail_source [descriptor=0] .jpg[Q=90] 128 | \ - cat > x.jpg - - - Codestin Search App - - vipsthumbnail supports the usual range of vips command-line options. A few of them are useful: - - - --vips-cache-trace shows each operation as libvips starts it. It can be handy to see exactly what operations vipsthumbnail is running for you. - - - --vips-leak turns on the libvips memory leak checker. As well as reporting leaks (hopefully there are none) it also tracks and reports peak memory use. - - - --vips-progress runs a progress indicator during computation. It can be useful to see where libvips is looping and how often. - - - --vips-info shows a higher level view of the operations that vipsthumbnail is running. - - - - Codestin Search App - - vipsthumbnail can process many images in one command. For example: - - -$ vipsthumbnail *.jpg - - - will make a thumbnail for every JPEG in the current directory. See the Output directory section below to see how to change where thumbnails are written. - - - vipsthumbnail will process images one after the other. You can get a good speedup by running several vipsthumbnails in parallel, depending on how much load you want to put on your system. For example: - - -$ parallel vipsthumbnail ::: *.jpg - - - - Codestin Search App - - You can set the bounding box of the generated thumbnail with the --size option. For example: - - -$ vipsthumbnail shark.jpg --size 200x100 - - - Use a single number to set a square bounding box. You can omit either number but keep the x to mean resize just based on that axis, for example: - - -$ vipsthumbnail shark.jpg --size 200x - - - Will resize to 200 pixels across, no matter what the height of the input image is. - - - You can append < or > to mean only resize if the image is smaller or larger than the target. - - - You can append ! to force a resize to the exact target size, breaking the aspect ratio. - - - - Codestin Search App - - vipsthumbnail normally shrinks images to fit within the box set by --size. You can use the --smartcrop option to crop to fill the box instead. Excess pixels are trimmed away using the strategy you set. For example: - - -$ vipsthumbnail owl.jpg --smartcrop attention -s 128 - - - Where owl.jpg is an off-centre composition: - - - - - - - - - - Gives this result: - - - - - - - - - - First it shrinks the image to get the vertical axis to 128 pixels, then crops down to 128 pixels across using the attention strategy. This one searches the image for features which might catch a human eye, see vips_smartcrop() for details. - - - - Codestin Search App - - Shrinking images involves combining many pixels into one. Arithmetic averaging really ought to be in terms of the number of photons, but (for historical reasons) the values stored in image files are usually related to the voltage that should be applied to the electron gun in a CRT display. - - - vipsthumbnail has an option to perform image shrinking in linear space, that is, a colourspace where values are proportional to photon numbers. For example: - - -$ vipsthumbnail fred.jpg --linear - - - The downside is that in linear mode, none of the very fast shrink-on-load tricks that vipsthumbnail normally uses are possible, since the shrinking is done at encode time, not decode time, and is done in terms of CRT voltage, not photons. This can make linear light thumbnailing of large images extremely slow. - - - For example, for a 10,000 x 10,000 pixel JPEG I see: - - -$ time vipsthumbnail wtc.jpg -real 0m0.317s -user 0m0.292s -sys 0m0.016s -$ time vipsthumbnail wtc.jpg --linear -real 0m4.660s -user 0m4.640s -sys 0m0.016s - - - - Codestin Search App - - You set the thumbnail write parameters with the -o option. This is a pattern which the input filename is pasted into to produce the output filename. For example: - - -$ vipsthumbnail fred.jpg jim.tif -o tn_%s.jpg - - - For each of the files to be thumbnailed, vipsthumbnail will drop the extension (.jpg and .tif in this case) and then substitute the name into the -o option, replacing the %s So this example will write thumbnails to tn_fred.jpg and tn_jim.jpg. - - - If the pattern given to -o is an absolute path, any path components are dropped from the input filenames. This lets you write all of your thumbnails to a specific directory, if you want. For example: - - -$ vipsthumbnail fred.jpg ../jim.tif -o /mythumbs/tn_%s.jpg - - - Now both thumbnails will be written to /mythumbs, even though the source images are in different directories. - - - Conversely, if -o is set to a relative path, any path component from the input file is prepended. For example: - - -$ vipsthumbnail fred.jpg ../jim.tif -o mythumbs/tn_%s.jpg - - - Now both input files will have thumbnails written to a subdirectory of their current directory. - - - - Codestin Search App - - You can use -o to specify the thumbnail image format too. For example: - - -$ vipsthumbnail fred.jpg ../jim.tif -o tn_%s.png - - - Will write thumbnails in PNG format. - - - You can give options to the image write operation as a list of comma-separated arguments in square brackets. For example: - - -$ vipsthumbnail fred.jpg ../jim.tif -o tn_%s.jpg[Q=90,optimize_coding] - - - will write JPEG images with quality 90, and will turn on the libjpeg coding optimizer. - - - Check the image write operations to see all the possible options. For example: - - -$ vips jpegsave -save image to jpeg file -usage: - jpegsave in filename [--option-name option-value ...] -where: - in - Image to save, input VipsImage - filename - Filename to save to, input gchararray -optional arguments: - Q - Q factor, input gint - default: 75 - min: 1, max: 100 - optimize-coding - Compute optimal Huffman coding tables, input gboolean - default: false - interlace - Generate an interlaced (progressive) jpeg, input gboolean - default: false - trellis-quant - Apply trellis quantisation to each 8x8 block, input gboolean - default: false - overshoot-deringing - Apply overshooting to samples with extreme values, input gboolean - default: false - optimize-scans - Split spectrum of DCT coefficients into separate scans, input gboolean - default: false - quant-table - Use predefined quantization table with given index, input gint - default: 0 - min: 0, max: 8 - subsample-mode - Select chroma subsample operation mode, input VipsForeignSubsample - default enum: auto - allowed enums: auto, on, off - restart-interval - Add restart markers every specified number of mcu, input gint - default: 0 - min: 0, max: 2147483647 - keep - Which metadata to retain, input VipsForeignKeep - default flags: exif:xmp:iptc:icc:other:all - allowed flags: none, exif, xmp, iptc, icc, other, all - background - Background value, input VipsArrayDouble - profile - Filename of ICC profile to embed, input gchararray - - - The keep option is especially useful. Many image have very large IPTC, ICC or XMP metadata items embedded in them, and removing these can give a large saving. - - - For example: - - -$ vipsthumbnail 42-32157534.jpg -$ ls -l tn_42-32157534.jpg --rw-r–r– 1 john john 6682 Nov 12 21:27 tn_42-32157534.jpg - - - keep=none almost halves the size of the thumbnail: - - -$ vipsthumbnail 42-32157534.jpg -o x.jpg[optimize_coding,keep=none] -$ ls -l x.jpg --rw-r–r– 1 john john 3600 Nov 12 21:27 x.jpg - - - - Codestin Search App - - vipsthumbnail will optionally put images through LittleCMS for you. You can use this to move all thumbnails to the same colour space. All web browsers assume that images without an ICC profile are in sRGB colourspace, so if you move your thumbnails to sRGB, you can strip all the embedded profiles. This can save several kb per thumbnail. - - - For example: - - -$ vipsthumbnail shark.jpg -$ ls -l tn_shark.jpg --rw-r–r– 1 john john 7295 Nov  9 14:33 tn_shark.jpg - - - Now transform to sRGB and don’t attach a profile (you can also use keep=none, though that will remove all metadata from the image): - - -$ vipsthumbnail shark.jpg --export-profile srgb -o tn_shark.jpg[profile=none] -$ ls -l tn_shark.jpg --rw-r–r– 1 john john 4229 Nov  9 14:33 tn_shark.jpg - - - (You can use the filename of any RGB profile. The magic string srgb selects a high-quality sRGB profile that’s built into libvips.) - - - tn_shark.jpg will look identical to a user, but it’s almost half the size. - - - You can also specify a fallback input profile to use if the image has no embedded one. For example, perhaps you somehow know that a JPEG is in Adobe98 space, even though it has no embedded profile. - - -$ vipsthumbnail kgdev.jpg --import-profile /my/profiles/a98.icm - - - - Codestin Search App - - Putting all this together, I suggest this as a sensible set of options: - - -$ vipsthumbnail fred.jpg \ - --size 128 \ - --export-profile srgb \ - -o tn_%s.jpg[optimize_coding,keep=none] - - - - - diff --git a/doc/binding.md b/doc/binding.md index e35ebe63ac..84337c299d 100644 --- a/doc/binding.md +++ b/doc/binding.md @@ -1,45 +1,39 @@ - - How to write bindings - 3 - libvips - +Title: Writing bindings for libvips - - Binding - Writing bindings for libvips - +# Writing bindings for libvips -There are full libvips bindings for quite a few environments now: C, C++, -command-line, Ruby, PHP, Lua, Python and JavaScript (node). +There are full libvips bindings for quite a few environments now, including +C, C++, command-line, Ruby, PHP, Lua, Python, Crystal, Elixir, and JavaScript +(Node.js). This chapter runs through the four main styles that have been found to work well. If you want to write a new binding, one of these should be close to what you need. -# Don't bind the top-level C API +## Don't bind the top-level C API -The libvips C API (vips_add() and so on) was designed to be easy for humans -to write. It is inconvenient and dangerous to use from other languages due -to its heavy use of varargs. +The libvips C API ([method@Image.add] and so on) was designed to be easy +for humans to write. It is inconvenient and dangerous to use from other +languages due to its heavy use of varargs. It's much better to use the layer below. This lower layer is structured as: -- Create operator. You can use vips_operation_new() to make a new - `VipsOperation` object from an operator nickname, like `"add"`. +- Create operator. You can use [ctor@Operation.new] to make a new + [class@Operation] object from an operator nickname, like `"add"`. -- Set parameters. You can loop over the operation with vips_argument_map() to - get the name and type of each input argument. For each argument, you - need to get the value from your language, convert to a `GValue`, then - use g_object_set_property() to set that value on the operator. +- Set parameters. You can use [method@Object.get_args] to + get the name and type of all arguments. For each argument, you need to + get the value from your language, convert to a [struct@GObject.Value], then + use [method@GObject.Object.set_property] to set that value on the operator. -- Execute with vips_cache_operation_build(). +- Execute with [func@cache_operation_build]. -- Extract results. Again, you loop over the operator arguments with - vips_argument_map(), but instead of inputs, this time you look for output - arguments. You extract their value with g_object_get_property(), and pass +- Extract results. Again, you loop over the arguments, + but instead of inputs, this time you look for output arguments. You + extract their value with [method@GObject.Object.get_property], and pass the value back to your language. -For example, you can execute vips_invert() like this: +For example, you can execute [method@Image.invert] like this: ```c /* compile with @@ -60,7 +54,7 @@ main(int argc, char **argv) GValue gvalue = G_VALUE_INIT; if (VIPS_INIT(argv[0])) - /* This shows the vips error buffer and quits with a fail exit + /* This shows the libvips error buffer and quits with a fail exit * code. */ vips_error_exit(NULL); @@ -94,7 +88,7 @@ main(int argc, char **argv) */ g_object_unref(in); - /* Call the operation. This will look up the operation+args in the vips + /* Call the operation. This will look up the operation+args in the libvips * operation cache and either return a previous operation, or build * this one. In either case, we have a new ref we must release. */ @@ -129,7 +123,7 @@ main(int argc, char **argv) } ``` -# Compiled language which can call C +## Compiled language which can call C The C++ binding uses this lower layer to define a function called `VImage::call()` which can call any libvips operator with a set of variable @@ -159,7 +153,7 @@ to get type-checked calls for at least the required operator arguments. The `VImage` class also adds automatic reference counting, constant expansion, operator overloads, and various other useful features. -# Dynamic language with FFI +## Dynamic language with FFI Languages like Ruby, Python, JavaScript and LuaJIT can't call C directly, but they do support FFI. The bindings for these languages work rather like C++, @@ -167,8 +161,8 @@ but use FFI to call into libvips and run operations. Since these languages are dynamic, they can add another trick: they intercept the method-missing hook and attempt to run any method calls not implemented by -the `Image` class as libvips operators. In effect, the binding is generated at -runtime. +the [class@Image] class as libvips operators. In effect, the binding is generated +at runtime. # gobject-introspection @@ -195,11 +189,11 @@ users is likely to be tricky. If you have a choice, I would recommend simply using FFI. -# Documentation +## Documentation -You can generate searchable docs from a .gir (the thing that -is built from scanning libvips and which in turn turn the typelib is -made from) with g-ir-doc-tool, for example: +You can generate searchable docs from a `.gir` (the thing that is built +from scanning libvips and which in turn the typelib is made from) with +`g-ir-doc-tool`, for example: ```bash $ g-ir-doc-tool --language=Python -o ~/mydocs Vips-8.0.gir diff --git a/doc/binding.xml b/doc/binding.xml deleted file mode 100644 index ecaa616dc9..0000000000 --- a/doc/binding.xml +++ /dev/null @@ -1,222 +0,0 @@ - - - - - - - How to write bindings 3 libvips - - - Binding Writing bindings for libvips - - - There are full libvips bindings for quite a few environments now: C, C++, command-line, Ruby, PHP, Lua, Python and JavaScript (node). - - - This chapter runs through the four main styles that have been found to work well. If you want to write a new binding, one of these should be close to what you need. - - - Codestin Search App - - The libvips C API (vips_add() and so on) was designed to be easy for humans to write. It is inconvenient and dangerous to use from other languages due to its heavy use of varargs. - - - It’s much better to use the layer below. This lower layer is structured as: - - - - - Create operator. You can use vips_operation_new() to make a new VipsOperation object from an operator nickname, like "add". - - - - - Set parameters. You can loop over the operation with vips_argument_map() to get the name and type of each input argument. For each argument, you need to get the value from your language, convert to a GValue, then use g_object_set_property() to set that value on the operator. - - - - - Execute with vips_cache_operation_build(). - - - - - Extract results. Again, you loop over the operator arguments with vips_argument_map(), but instead of inputs, this time you look for output arguments. You extract their value with g_object_get_property(), and pass the value back to your language. - - - - - For example, you can execute vips_invert() like this: - - -/* compile with - * - * gcc -g -Wall callvips.c `pkg-config vips --cflags --libs` - * - */ - -#include <vips/vips.h> - -int -main(int argc, char **argv) -{ - VipsImage *in; - VipsImage *out; - VipsOperation *op; - VipsOperation *new_op; - GValue gvalue = G_VALUE_INIT; - - if (VIPS_INIT(argv[0])) - /* This shows the vips error buffer and quits with a fail exit - * code. - */ - vips_error_exit(NULL); - - /* This will print a table of any ref leaks on exit, very handy for - * development. - */ - vips_leak_set(TRUE); - - if (argc != 3) - vips_error_exit("usage: %s input-filename output-filename", - argv[0]); - - if (!(in = vips_image_new_from_file(argv[1], NULL))) - vips_error_exit(NULL); - - /* Create a new operator from a nickname. NULL for unknown operator. - */ - op = vips_operation_new("invert"); - - /* Init a gvalue as an image, set it to in, use the gvalue to set the - * operator property. - */ - g_value_init(&gvalue, VIPS_TYPE_IMAGE); - g_value_set_object(&gvalue, in); - g_object_set_property(G_OBJECT(op), "in", &gvalue); - g_value_unset(&gvalue); - - /* We no longer need in: op will hold a ref to it as long as it needs - * it. - */ - g_object_unref(in); - - /* Call the operation. This will look up the operation+args in the vips - * operation cache and either return a previous operation, or build - * this one. In either case, we have a new ref we must release. - */ - if (!(new_op = vips_cache_operation_build(op))) { - g_object_unref(op); - vips_error_exit(NULL); - } - g_object_unref(op); - op = new_op; - - /* Now get the result from op. g_value_get_object() does not ref the - * object, so we need to make a ref for out to hold. - */ - g_value_init(&gvalue, VIPS_TYPE_IMAGE); - g_object_get_property(G_OBJECT(op), "out", &gvalue); - out = VIPS_IMAGE(g_value_get_object(&gvalue)); - g_object_ref(out); - g_value_unset(&gvalue); - - /* All done: we can unref op. The output objects from op actually hold - * refs back to it, so before we can unref op, we must unref them. - */ - vips_object_unref_outputs(VIPS_OBJECT(op)); - g_object_unref(op); - - if (vips_image_write_to_file(out, argv[2], NULL)) - vips_error_exit(NULL); - - g_object_unref(out); - - return 0; -} - - - - Codestin Search App - - The C++ binding uses this lower layer to define a function called VImage::call() which can call any libvips operator with a set of variable arguments. - - - A small Python program walks the set of all libvips operators and generates a set of static bindings. For example: - - -VImage -VImage::invert(VOption *options) const -{ - VImage out; - - call("invert", (options ? options : VImage::option()) - ->set("in", *this) - ->set("out", &out)); - - return out; -} - - - So from C++ you can call any libvips operator (though without static typechecking) with VImage::call(), or use the member functions on VImage to get type-checked calls for at least the required operator arguments. - - - The VImage class also adds automatic reference counting, constant expansion, operator overloads, and various other useful features. - - - - Codestin Search App - - Languages like Ruby, Python, JavaScript and LuaJIT can’t call C directly, but they do support FFI. The bindings for these languages work rather like C++, but use FFI to call into libvips and run operations. - - - Since these languages are dynamic, they can add another trick: they intercept the method-missing hook and attempt to run any method calls not implemented by the Image class as libvips operators. In effect, the binding is generated at runtime. - - - - Codestin Search App - - The C source code to libvips has been marked up with special comments describing the interface in a standard way. These comments are read by the gobject-introspection package when libvips is compiled and used to generate a typelib, a description of how to call the library. Many languages have gobject-introspection packages: all you need to do to call libvips from your favorite language is to start g-o-i, load the libvips typelib, and you should have the whole library available. For example, from Python it’s as simple as: - - -from gi.repository import Vips - - - You can now use all of the libvips introspection machinery, as noted above. - - - Unfortunately g-o-i has some strong disadvantages. It is not very portable, since you will need a g-o-i layer for whatever platform you are targeting; it does not cross-compile well, since typelibs include a lot of very-low level data (such as exact structure layouts); and installation for your users is likely to be tricky. - - - If you have a choice, I would recommend simply using FFI. - - - - Codestin Search App - - You can generate searchable docs from a .gir (the thing that is built from scanning libvips and which in turn turn the typelib is made from) with g-ir-doc-tool, for example: - - -$ g-ir-doc-tool --language=Python -o ~/mydocs Vips-8.0.gir - - - Then to view them, either: - - -$ yelp ~/mydocs - - - Or perhaps: - - -$ cd ~/mydocs -$ yelp-build html . - - - To make HTML docs. This is an easy way to see what you can call in the library. - - - - - diff --git a/doc/cite.md b/doc/cite.md new file mode 100644 index 0000000000..6006a7d104 --- /dev/null +++ b/doc/cite.md @@ -0,0 +1,12 @@ +Title: References to cite for libvips + +# libvips References + +Martinez, K. and Cupitt, J. (2005) +[VIPS -- a highly tuned image processing software architecture]( +http://eprints.ecs.soton.ac.uk/12371). In Proceedings of IEEE +International Conference on Image Processing 2, pp. 574-577, Genova. + +Cupitt, J. and Martinez, K. (1996) +[VIPS: An image processing system for large images]( +http://eprints.soton.ac.uk/252227), Proc. SPIE, vol. 2663, pp. 19--28. diff --git a/doc/Developer-checklist.md b/doc/developer-checklist.md similarity index 80% rename from doc/Developer-checklist.md rename to doc/developer-checklist.md index e2057ffac6..d385d2ce0d 100644 --- a/doc/Developer-checklist.md +++ b/doc/developer-checklist.md @@ -1,40 +1,32 @@ - - Developer checklist - 3 - libvips - +Title: Checklist for libvips users - - Dev checklist - Checklist for libvips users - +## Checklist for libvips users libvips is a slightly unusual library and you may need to take some of its stranger features into account when you design software that uses it. -## If you can, use `thumbnail`, not `resize` +## If you can, use [func@thumbnail], not [method@Image.resize] -The `thumbnail` operation combines load and resize into one step. This lets it -take advantage of format library features, such as shrink on load, and can -lead to a large improvement in speed and a large drop in memory use. +The [func@thumbnail] operation combines load and resize into one step. This +lets it take advantage of format library features, such as shrink on load, +and can lead to a large improvement in speed and a large drop in memory use. For example, with this JPEG image: -``` +```bash $ vipsheader nina.jpg nina.jpg: 6048x4032 uchar, 3 bands, srgb, jpegload ``` I see: -``` -$ /usr/bin/time -f %M:%e vips resize nina.jpg x.jpg 0.1 +```bash/usr/bin/time -f %M:%e vips resize nina.jpg x.jpg 0.1 123648:0.23 ``` 124 MB of RAM and 0.23s to shink by a factor of 10. With `thumbnail` it's: -``` +```bash $ /usr/bin/time -f %M:%e vips thumbnail nina.jpg x.jpg 605 68864:0.08 ``` @@ -43,30 +35,30 @@ Now it's 68 MB of memory and 0.08s -- half the memory use, and 3x faster. In fact the improvement is better than that, since the `vips` command takes a while to start and needs a fair amount of memory: -``` +```bash $ /usr/bin/time -f %M:%e vips > /dev/null 31232:0.02 ``` -31 MB and 0.02s, so `thumbnail` is really 2.5x less memory and 4x faster. +31 MB and 0.02s, so [func@thumbnail] is really 2.5x less memory and 4x faster. You can see much larger improvements with other formats, and quality will -often be better as well, since `thumbnail` will automatically premultiply and -can render vector images directly at the correct size. +often be better as well, since [func@thumbnail] will automatically premultiply +and can render vector images directly at the correct size. -## Don't use `thumbnail_image` +## Don't use [method@Image.thumbnail_image] It's just there for emergencies. It can't do any of the rendering tricks, -so it's no faster than `resize`. Use `thumbnail` if you can. +so it's no faster than [method@Image.resize]. Use [func@thumbnail] if you can. ## Use sequential mode if you can -This is a hint you pass to `new_from_file` and friends that signals that you +This is a hint you pass to [ctor@Image.new_from_file] and friends that signals that you will only scan this image in the direction that the underlying load library supports. This can give a useful improvement in speed and reduction in memory use in many cases. -See [the "How it opens files" chapter](How-it-opens-files.html) for background +See [the "How it opens files" chapter](how-it-opens-files.html) for background on this feature. ## Use longer pipelines if you can @@ -93,7 +85,7 @@ This can raise memory use, of course. ## Adjust the order of operations in pipelines -If you can, put large resizes right at the start (see `thumbnail` above), +If you can, put large resizes right at the start (see [func@thumbnail] above), then area filters (sharpen, for example), and finally any point operations. ## Only enable the load libraries you need @@ -131,7 +123,7 @@ There are two main checks that are very worthwhile: is in memory, which prevents any streaming processing and hugely increases memory use. For example: -``` +```bash $ /usr/bin/time -f %M:%e vipsthumbnail big-progressive.jpg 3732224:4.23 $ vips copy big-progressive.jpg x.jpg diff --git a/doc/Examples.md b/doc/examples.md similarity index 61% rename from doc/Examples.md rename to doc/examples.md index 7e501effc8..bd5535c7e2 100644 --- a/doc/Examples.md +++ b/doc/examples.md @@ -1,13 +1,6 @@ - - Examples - 3 - libvips - +Title: A few example Python programs using libvips - - libvips examples - A few example Python programs using libvips - +# A few example Python programs using libvips This page shows a few libvips examples using Python. They will work with small syntax changes in any language with a libvips binding. @@ -15,7 +8,7 @@ small syntax changes in any language with a libvips binding. The libvips test suite is written in Python and exercises every operation in the API. It's also a useful source of examples. -# Average a region of interest box on an image +## Average a region of interest box on an image ```python #!/usr/bin/python3 @@ -33,7 +26,50 @@ roi = image.crop(left, top, width, height) print('average:', roi.avg()) ``` -# Build huge image mosaic +## libvips and numpy + +You can use `pyvips.Image.new_from_memory()` to make a libvips image from +an area of memory. The memory array needs to be laid out band-interleaved, +as a set of scanlines, with no padding between lines. + +```python +#!/usr/bin/python3 + +import sys +import time + +import pyvips +from PIL import Image +import numpy as np + +if len(sys.argv) != 3: + print(f'usage: {sys.argv[0]} input-filename output-filename') + sys.exit(-1) + +# load with PIL +start_pillow = time.time() +pillow_img = np.asarray(Image.open(sys.argv[1])) +print('Pillow Time:', time.time()-start_pillow) +print('original shape', pillow_img.shape) + +# load with vips to a numpy array +start_vips = time.time() +img = pyvips.Image.new_from_file(sys.argv[1], access='sequential') +np_3d = img.numpy() +print('Vips Time:', time.time()-start_vips) +print('final shape', np_3d.shape) + +# verify we have the same result +print('Sum of the Differences:', np.sum(np_3d-pillow_img)) + +# make a vips image from the numpy array +vi = pyvips.Image.new_from_array(np_3d) + +# and write back to disc for checking +vi.write_to_file(sys.argv[2]) +``` + +## Build huge image mosaic This makes a 100,000 x 100,000 black image, then inserts all the images you pass on the command-line into it at random positions. libvips is able to run @@ -66,7 +102,7 @@ sys 0m8.936s It completes in just under two minutes on this laptop, and needs about 7gb of RAM to run. It would need about the same amount of memory for a -full-colour RGB image, I was just keen to keep disc usage down. +full-colour RGB image, I was just keen to keep disc usage down. If you wanted to handle transparency, or if you wanted mixed CMYK and RGB images, you'd need to do some more work to convert them all into the same diff --git a/doc/extending.md b/doc/extending.md new file mode 100644 index 0000000000..c1d9a614f2 --- /dev/null +++ b/doc/extending.md @@ -0,0 +1,350 @@ +Title: How to add operations to libvips + +# How to add operations to libvips + +This section runs quickly through adding a simple operator to libvips. +For more information, see [class@Operation] and [class@Region]. A good +starting point for a new operation is a similar one in libvips. + +All libvips operations are subclasses of [class@Operation], which in turn +subclasses [class@Object] and then [class@GObject.Object]. You add an +operation to libvips by defining a new subclass of [class@Operation] and +arranging for its `class_init()` to be called, perhaps by calling its +`get_type()` function. + +## The class and object structures + +First you need to define a new object struct and a new class struct. + +```c +typedef struct _Negative { + VipsOperation parent_instance; + + VipsImage *in; + VipsImage *out; + + int image_max; + +} Negative; + +typedef struct _NegativeClass { + VipsOperationClass parent_class; + + /* No new class members needed for this op. + */ + +} NegativeClass; +``` + +This operation will find the photographic negative of an unsigned 8-bit +image, optionally letting you specify the value which the pixels "pivot" +about. It doesn't need any class members (ie. values common to all operations +of this type), so the second struct is empty. See the source to +[method@Image.invert] for a more complete version of this operation that's +actually in the library. + +[class@GObject.Object] has a handy macro to write some of the boilerplate for +you. + +```c +G_DEFINE_TYPE(Negative, negative, VIPS_TYPE_OPERATION); +``` + +[func@GObject.DEFINE_TYPE] defines a function called `negative_get_type()`, +which registers this new class and returns its [alias@GObject.Type] (a +pointer-sized integer). `negative_get_type()` in turn needs two functions, +`negative_init()`, to initialise a new instance, and `negative_class_init()`, +to initialise a new class. + +## Class and object initialisation + +`negative_init()` is very simple, it just sets the default value for our +optional parameter. + +```c +static void +negative_init(Negative *negative) +{ + negative->image_max = 255; +} +``` + +`negative_class_init()` is more complicated: it has to set various fields in +various superclasses and define the operation's parameters. + +```c +static void +negative_class_init(NegativeClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(class); + VipsObjectClass *object_class = VIPS_OBJECT_CLASS(class); + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + object_class->nickname = "negative"; + object_class->description = "photographic negative"; + object_class->build = negative_build; + + VIPS_ARG_IMAGE(class, "in", 1, + "Input", + "Input image", + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET(Negative, in)); + + VIPS_ARG_IMAGE(class, "out", 2, + "Output", + "Output image", + VIPS_ARGUMENT_REQUIRED_OUTPUT, + G_STRUCT_OFFSET(Negative, out)); + + VIPS_ARG_INT(class, "image_max", 4, + "Image maximum", + "Maximum value in image: pivot about this", + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET(Negative, image_max), + 0, 255, 255); +} +``` + +In [class@GObject.Object], it needs to set the getters and setters for this +class. libvips has a generic get/set system, so any subclass of +[class@VipsObject] needs to use the libvips ones. + +In [class@VipsObject], it needs to set the operation +[property@VipsObject:nickname] and [property@VipsObject:description], and set +a build function (see below). [property@VipsObject:nickname] is used to refer +to this operation in the API, [property@VipsObject:description] is used to +explain this operation to users and will be translated into their language. + +Finally, it needs to define the arguments the constructor for this class +takes. There are a set of handy macros for doing this, see [func@ARG_INT] +and friends. + +The first few parameters are always the same and mean: class pointer for +argument, argument name, argument priority (bindings expect required arguments +in order of priority), long argument name (this one is internationalised +and displayed to users), description (again, users can see this), some flags +describing the argument, and finally the position of the member in the struct. + +Integer arguments take three more values: the minimum, maximum and +default value for the argument. + +## The `build()` function + +The build function is the thing [class@VipsObject] calls during object construction, +after all arguments have been supplied and before the object is used. It +has two roles: to verify that arguments are correct, and then to construct +the object. After `build()`, the object is expected to be ready for use. + +```c +static int +negative_build(VipsObject *object) +{ + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); + Negative *negative = (Negative *) object; + + if (VIPS_OBJECT_CLASS(negative_parent_class)->build(object)) + return -1; + + if (vips_check_uncoded(class->nickname, negative->in) || + vips_check_format(class->nickname, negative->in, VIPS_FORMAT_UCHAR)) + return -1; + + g_object_set(object, "out", [ctor@Image.new], NULL); + + if (vips_image_pipelinev(negative->out, + VIPS_DEMAND_STYLE_THINSTRIP, negative->in, NULL)) + return -1; + + if (vips_image_generate(negative->out, + vips_start_one, + negative_generate, + vips_stop_one, + negative->in, negative)) + return -1; + + return 0; +} +``` + +`negative_build()` first chains up to the superclass: this will check that +all input arguments have been supplied and are sane. + +Next, it adds its own checks. This is a demo operation, so we just work for +uncoded, unsigned 8-bit images. There are a lot of convenience functions +like [func@check_format], see the docs. + +Next, it creates the output image. This needs to be set with [method@Object.set] +so that libvips can see that it has been assigned. libvips will also handle the +reference counting for you. + +[method@Image.pipelinev] links our new image onto the input image and notes +that this operation prefers to work in lines. You can request other input +geometries, see [enum@DemandStyle]. + +The geometry hint is just a hint, an operation needs to be able to supply any +size [class@Region] on request. If you must have a certain size request, you +can put a cache in the pipeline after your operation, see +[method@Image.linecache] and [method@Image.tilecache]. You can also make requests +to your operation ordered, see [method@Image.sequential]. + +Finally, [method@Image.generate] attaches a set of callbacks to the output +image to generate chunks of it on request. [func@start_one] and [func@stop_one] +are convenience functions that make the input region for you, see below. + +## The `generate()` function + +The `generate()` function does the actual image processing. `negative_generate()` +(of type [callback@GenerateFn], supplied to [method@Image.generate] above) is +called whenever some pixels of our output image are required. + +```c +static int +negative_generate(VipsRegion *out_region, + void *vseq, void *a, void *b, gboolean *stop) +{ + /* The area of the output region we have been asked to make. + */ + VipsRect *r = &out_region->valid; + + /* The sequence value ... the thing returned by [func@start_one]. + */ + VipsRegion *ir = (VipsRegion *) vseq; + + VipsImage *in = (VipsImage *) a; + Negative *negative = (Negative *) b; + int line_size = r->width * negative->in->Bands; + + int x, y; + + /* Request matching part of input region. + */ + if (vips_region_prepare(ir, r)) + return -1; + + for (y = 0; y < r->height; y++) { + unsigned char *p = (unsigned char *) + VIPS_REGION_ADDR(ir, r->left, r->top + y); + unsigned char *q = (unsigned char *) + VIPS_REGION_ADDR(out_region, r->left, r->top + y); + + for (x = 0; x < line_size; x++) + q[x] = negative->image_max - p[x]; + } + + return 0; +} +``` + +This has to calculate a section of the output image. The output +[class@Region], `out_region`, contains a [struct@Rect] called `valid` +which is the area needing calculation. This call to `negative_generate()` +must somehow make this part of `out_region` contain pixel data. + +`vseq` is the sequence value. This is the per-thread state for this generate, +created (in this example) by [func@start_one]. In this simple case it's +just a [class@Region] defined on the input image. If you need more per-thread +state you can write your own start and stop functions and have a struct +you create and pass as a sequence value. There are plenty of examples in +the libvips source code, see [method@Image.rank]. + +`a` and `b` are the last two arguments to [method@Image.generate] above. +`stop` is a bool pointer you can set to stop computation early. +[method@Image.min] on an unsigned int image, for example, will set `stop` +as soon as it sees a zero, and will not scan the entire image. + +The first thing `negative_generate()` does is use [method@Region.prepare] to +ask for the corresponding pixels from the input image. Operations which do +coordinate transforms or which need an area of input for each output point +will need to calculate a new rect before calling [method@Region.prepare]. + +Finally, it can calculate some pixels. `negative_generate()` loops over the +valid area of the output and calls [func@REGION_ADDR] for each line. This +macro is reasonably quick, but it's best not to call it for each pixel. Once +per line is fine though. + +## Adding to libvips + +To add the operation to libvips, just call `negative_get_type()`. You can +include the source in your program, or use [GModule]( +https://docs.gtk.org/gmodule/) to make a binary plugin that will be loaded +by libvips at startup. There are some [example plugins available]( +https://github.com/jcupitt/vips-gmic). + +You can then use `negative` from any of the libvips interfaces. For example, +in Python you'd use it like this: + +```python +out = in.negative(image_max=128) +``` + +From the command-line it'd look like this: + +```bash +$ vips negative in.png out.tif --image-max 128 +``` + +And from C like this: + +```c +VipsImage *in; +VipsImage *out; +if (vips_call("negative", in, &out, "image_max", 128, NULL)) + ... error +``` + +Unfortunately that will do almost no compile-time type checking, so all +libvips operations have a tiny extra wrapper to add a bit of safety. For +example: + +```c +static int +negative(VipsImage *in, VipsImage **out, ...) +{ + va_list ap; + int result; + + va_start(ap, out); + result = vips_call_split("negative", ap, in, out); + va_end(ap); + + return result; +} +``` + +And now you can write: + +```c +if (negative(in, &out, "image_max", 128, NULL)) + ... error +``` + +and it's at least a bit safer. + +## Other types of operation + +Change the `_build()` function to make other types of operation. + +Use [method@Image.generate] with [func@start_many] to make operations which +demand pixels from more than one image at once, such as image plus image. + +Use [method@Image.sink] instead of [method@Image.generate] to loop over an +image and calculate a value. libvips uses this for the statistics operations, +like [method@Image.avg]. + +Use [method@Image.wio_input] to get an entire image into memory so you can +read it with a pointer. This will obviously not scale well to very large +images, but some operations, like FFTs or flood-fill, need the whole image +to be available at once. + +Make area operations, like filters, by enlarging the [struct@Rect] that +`_generate()` is given before calling [method@Region.prepare]. You can enlarge +the input image, so that the output image is the same size as the original +input, by using [method@Image.embed] within the `_build()` function. + +Make things like flips and rotates by making larger changes to the [struct@Rect] +in `_generate()`. + +Make zero-copy operations, like [method@Image.insert], with +[method@Region.region]. diff --git a/doc/extending.xml b/doc/extending.xml deleted file mode 100644 index 492efa76a7..0000000000 --- a/doc/extending.xml +++ /dev/null @@ -1,462 +0,0 @@ - - - - - Extending VIPS - 3 - VIPS Library - - - - Extending - How to add operations to VIPS - - - - Codestin Search App - - This section runs quickly through adding a simple operator to VIPS. - For more information, see #VipsOperation and #VipsRegion. A good - starting point for a new operation is a similar one in the VIPS library. - - - - All VIPS operations are subclasses of #VipsOperation, which in turn - subclasses #VipsObject and then %GObject. You add an operation to VIPS - by defining a new subclass of #VipsOperation and arranging for its - class_init() to be called, perhaps by calling its get_type() - function. - - - - - Codestin Search App - - - First you need to define a new - object struct and a new class struct. - - -typedef struct _Negative { - VipsOperation parent_instance; - - VipsImage *in; - VipsImage *out; - - int image_max; - -} Negative; - -typedef struct _NegativeClass { - VipsOperationClass parent_class; - - /* No new class members needed for this op. - */ - -} NegativeClass; - - - - - This operation will find the photographic negative of an unsigned - 8-bit image, optionally letting you specify the value which the pixels - "pivot" about. It doesn't need any class members (ie. values common - to all operations of this type), so the second struct is empty. See - the source to vips_invert() for a more complete version of this - operation that's actually in the library. - - - - %GObject has a handy macro to write some of the boilerplate for you. - - -G_DEFINE_TYPE(Negative, negative, VIPS_TYPE_OPERATION); - - - G_DEFINE_TYPE() defines a function called negative_get_type(), - which registers this new class and returns its %GType (a - pointer-sized integer). negative_get_type() in turn needs two - functions, negative_init(), to initialise a new instance, and - negative_class_init(), to initialise a new class. - - - - - Codestin Search App - - negative_init() is very simple, it just sets the default value for - our optional parameter. - - -static void -negative_init(Negative *negative) -{ - negative->image_max = 255; -} - - - - - negative_class_init() is more complicated: it has to set various - fields in various superclasses and define the operation's parameters. - - -static void -negative_class_init(NegativeClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(class); - VipsObjectClass *object_class = VIPS_OBJECT_CLASS(class); - - gobject_class->set_property = vips_object_set_property; - gobject_class->get_property = vips_object_get_property; - - object_class->nickname = "negative"; - object_class->description = "photographic negative"; - object_class->build = negative_build; - - VIPS_ARG_IMAGE(class, "in", 1, - "Input", - "Input image", - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET(Negative, in)); - - VIPS_ARG_IMAGE(class, "out", 2, - "Output", - "Output image", - VIPS_ARGUMENT_REQUIRED_OUTPUT, - G_STRUCT_OFFSET(Negative, out)); - - VIPS_ARG_INT(class, "image_max", 4, - "Image maximum", - "Maximum value in image: pivot about this", - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET(Negative, image_max), - 0, 255, 255); -} - - - - - In %GObject, it needs to set the getters and setters for this class. vips - has a generic get/set system, so any subclass of #VipsObject needs to - use the vips ones. - - - - In #VipsObject, it needs to set the operation @nickname and @description, - and set a build function (see below). @nickname is used to refer to - this operation in the API, @description is used to explain this - operation to users and will be translated into their language. - - - - Finally, it needs to define the arguments the constructor for this class - takes. There are a set of handy macros for doing this, see - VIPS_ARG_INT() and friends. - - - - The first few - parameters are always the same and mean: class pointer for argument, - argument name, argument priority (bindings expect required arguments in - order of priority), long argument name (this one is internationalised - and displayed to users), description (again, users can see this), - some flags describing the argument, and finally the position of the - member in the struct. - - - - Integer arguments take three more values: the minimum, maximum and - default value for the argument. - - - - - Codestin Search App - - The build function is the thing #VipsObject calls during object - construction, after all arguments have been supplied and before the - object is used. It has two roles: to verify that arguments are correct, - and then to construct the object. After build(), the object is expected - to be ready for use. - - -static int -negative_build(VipsObject *object) -{ - VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); - Negative *negative = (Negative *) object; - - if (VIPS_OBJECT_CLASS(negative_parent_class)->build(object)) - return -1; - - if (vips_check_uncoded(class->nickname, negative->in) || - vips_check_format(class->nickname, negative->in, VIPS_FORMAT_UCHAR)) - return -1; - - g_object_set(object, "out", vips_image_new(), NULL); - - if (vips_image_pipelinev(negative->out, - VIPS_DEMAND_STYLE_THINSTRIP, negative->in, NULL)) - return -1; - - if (vips_image_generate(negative->out, - vips_start_one, - negative_generate, - vips_stop_one, - negative->in, negative)) - return -1; - - return 0; -} - - - - - negative_build() first chains up to the superclass: this will check - that all input arguments have been supplied and are sane. - - - - Next, it adds its own checks. This is a demo operation, so we just - work for uncoded, unsigned 8-bit images. There are a lot of - convenience functions like vips_check_format(), see the docs. - - - - Next, it creates the output image. This needs to be set with - g_object_set() so that vips can see that it has been assigned. vips - will also handle the reference counting for you. - - - - vips_image_pipelinev() links our new image onto the input image and - notes that this operation prefers to work in lines. You can request - other input geometries, see #VipsDemandStyle. - - - - The geometry hint is just a hint, an operation needs to be able to - supply any size - #VipsRegion on request. If you must have a certain size request, you can - put a cache in the pipeline after your operation, see vips_linecache() - and vips_tilecache(). You can also make requests to your operation - ordered, see vips_sequential(). - - - - Finally, vips_image_generate() attaches a set of callbacks to the - output image to generate chunks of it on request. vips_start_one() - and vips_stop_one() are convenience functions that make the input - region for you, see below. - - - - - Codestin Search App - - - The generate() function does the actual image processing. - negative_generate() (of type #VipsGenerateFn, supplied to - vips_image_generate() above) is - called whenever some pixels of our output image are required. - - -static int -negative_generate(VipsRegion *out_region, - void *vseq, void *a, void *b, gboolean *stop) -{ - /* The area of the output region we have been asked to make. - */ - VipsRect *r = &out_region->valid; - - /* The sequence value ... the thing returned by vips_start_one(). - */ - VipsRegion *ir = (VipsRegion *) vseq; - - VipsImage *in = (VipsImage *) a; - Negative *negative = (Negative *) b; - int line_size = r->width * negative->in->Bands; - - int x, y; - - /* Request matching part of input region. - */ - if (vips_region_prepare(ir, r)) - return -1; - - for (y = 0; y < r->height; y++) { - unsigned char *p = (unsigned char *) - VIPS_REGION_ADDR(ir, r->left, r->top + y); - unsigned char *q = (unsigned char *) - VIPS_REGION_ADDR(out_region, r->left, r->top + y); - - for (x = 0; x < line_size; x++) - q[x] = negative->image_max - p[x]; - } - - return 0; -} - - - - - This has to calculate a section of the output image. The output - #VipsRegion, @out_region, contains a #VipsRect called @valid which is the - area needing calculation. This call to negative_generate() must - somehow make this part of @out_region contain pixel data. - - - - @vseq is the sequence value. This is the - per-thread state for this generate, created (in this example) by - vips_start_one(). In this simple case it's just a #VipsRegion defined on - the input image. If you need more per-thread state you can write your - own start and stop functions and have a struct you create and pass as a - sequence value. There are plenty of examples in the VIPS source code, - see vips_rank(). - - - - @a and @b are the last two arguments to vips_image_generate() above. - @stop is a bool pointer you can set to stop computation early. vips_min() - on an unsigned int image, for example, will set @stop as soon as it sees - a zero, and will not scan the entire image. - - - - The first thing negative_generate() does is - use vips_region_prepare() to - ask for the corresponding pixels from the input image. Operations which - do coordinate transforms or which need an area of input for each output - point will need to calculate a new rect before calling - vips_region_prepare(). - - - - Finally, it can calculate some pixels. negative_generate() loops - over the valid area of the output and calls VIPS_REGION_ADDR() for each - line. This macro is reasonaly quick, but it's best not to call it for - each pixel. Once per line is fine though. - - - - - Codestin Search App - - To add the operation to vips, just call negative_get_type(). You can - include the source in your program, or use %GModule to make a binary - plugin that will be loaded by libvips at startup. There are some example - plugins available. - - - - You - can then use @negative from any of the vips interfaces. For example, - in Python you'd use it like this: - - -out = in.negative(image_max = 128) - - - - - From the command-line it'd look like this: - - -$ vips negative in.png out.tif --image-max 128 - - - - - And from C like this: - - -VipsImage *in; -VipsImage *out; -if (vips_call("negative", in, &out, "image_max", 128, NULL)) -... error - - - - - Unfortunately that will do almost no compile-time type checking, - so all vips operations have a tiny extra wrapper to add a bit of - safety. For example: - - -static int -negative(VipsImage *in, VipsImage **out, ...) -{ - va_list ap; - int result; - - va_start(ap, out); - result = vips_call_split("negative", ap, in, out); - va_end(ap); - - return result; -} - - - - - And now you can write: - - -if (negative(in, &out, "image_max", 128, NULL)) -... error - - - and it's at least a bit safer. - - - - - Codestin Search App - - Change the _build() function to make other types of operation. - - - - Use vips_image_generate() with vips_start_many() to make operations - which demand pixels from more than one image at once, such as image - plus image. - - - - Use vips_sink() instead of vips_image_generate() to loop over an image - and calculate a value. vips uses this for the statistics operations, - like vips_avg(). - - - - Use vips_image_wio_input() to get an entire image into memory so you - can read it with a pointer. This will obviously not scale well to - very large images, but some operations, like FFTs or flood-fill, need - the whole image to be available at once. - - - - Make area operations, like filters, by enlarging the #VipsRect that - _generate() is given before calling vips_region_prepare(). You can - enlarge the input image, so that the output image is the same size as - the original input, by using vips_embed() within the _build() function. - - - - Make things like flips and rotates by making larger changes to the - #VipsRect in _generate(). - - - - Make zero-copy operations, like vips_insert(), with vips_region_region(). - - - - - diff --git a/doc/file-format.md b/doc/file-format.md new file mode 100644 index 0000000000..4a7691c463 --- /dev/null +++ b/doc/file-format.md @@ -0,0 +1,91 @@ +Title: The libvips file format + +# The libvips file format + +libvips has a simple, native file format. It's very fast, there is no image +size limit, and it supports arbitrary metadata. Although few other programs +can read these images (though recent versions of ImageMagick do have basic +support for the `.v` format), it can be useful as an intermediate format +for command-line processing. For example: + +```bash +$ vips invert input.tif t.v +$ vips gamma t.v output.tif +``` + +is faster than using `.tif` for the temporary intermediate image. This +section documents the libvips file format. + +libvips comes with a command-line program called `vipsedit` which is useful +for destructively changing fields in a `.v` image. The `vipsheader` program +can be used to extract any metadata. + +libvips files come in three parts. First, there is a 64-byte header, containing +an identifying magic number and a set of very basic fields, such as image +width in pixels. Next, the image data is stored as a set of band-interleaved +scanlines, from the top of the image to the bottom. Finally, after the +pixel data comes an optional block of XML containing any extra metadata, +such as an ICC profile or the EXIF data. + +## The header + +The fields in the libvips header are always stored least-significant byte first +(Intel ordering). Only the most basic information about the image is in +the header: most metadata is stored in the XML extension block after the +pixel data. + +If the first four bytes of the file are in order 08 f2 a6 b6, the image +data (see the next section) is stored in Intel byte order (LSB first) +and will need to be swapped if read on a SPARC-style machine (MSB first). +If the magic number is b6 a6 f2 08, the image data is in SPARC order and +will need to swapped if read on an Intel-style machine. libvips does this +swapping automatically. + +| Bytes | Type | libvips name | Meaning | +|---------|-----------------------|------------------|-------------------------------------------| +| 0 - 3 | | | Magic number: 08 f2 a6 b6, or b6 a6 f2 08 | +| 4 - 7 | int32 | `width` | Width of image, in pixels | +| 8 - 11 | int32 | `height` | Height of image, in pixels | +| 12 - 15 | int32 | `bands` | Number of image bands (channels) | +| 16 - 19 | | | Unused | +| 20 - 23 | [enum@BandFormat] | `format` | Band format | +| 24 - 27 | [enum@Coding] | `coding` | Image coding | +| 28 - 31 | [enum@Interpretation] | `interpretation` | Pixel interpretation | +| 32 - 35 | float32 | `xres` | Horizontal resolution, in pixels per mm | +| 36 - 39 | float32 | `yres` | Vertical resolution, in pixels per mm | +| 40 - 47 | | | Unused | +| 48 - 51 | int32 | `xoffset` | Horizontal offset of origin, in pixels | +| 52 - 55 | int32 | `yoffset` | Vertical offset of origin, in pixels | +| 56 - 63 | | | Unused | + +## The image data + +If `coding` is set to [enum@Vips.Coding.none], pixels are stored in native C +format, that is, the native format of the machine that wrote the data. If you +open a big-endian image on a little-endian machine, libvips will automatically +byte-swap for you. libvips has 10 band formats, see [enum@BandFormat]. +Image data is stored as a simple list of scanlines, from the top of the +image to the bottom. Pixels are band-interleaved, so RGBRGBRGBRGB, for +example. There is no padding at the end of scanlines. + +If `coding` is set to [enum@Vips.Coding.labq], each pixel is four bytes, with +10 bits for L\* and 11 bits for each of a\* and b\*. These 32 bits are packed +into 4 bytes, with the most significant 8 bits of each value in the first +3 bytes, and the left-over bits packed into the final byte as 2:3:3. + +If `coding` is set to [enum@Vips.Coding.rad], each pixel is RGB or XYZ float, +with 8 bits of mantissa and then 8 bits of exponent, shared between the +three channels. This coding style is used by the Radiance family of programs +(and the HDR format) commonly used for HDR imaging. + +Other values of `coding` can set other coding styles. Use +[func@IMAGE_SIZEOF_IMAGE] to calculate the size of the image data section. + +## The metadata + +Following the image data is a chunk of XML holding a simple list of name-value +pairs. Binary data is encoded with base64. Use [method@Image.image_set] and +friends to set and get image metadata. + +You can use `vipsheader -f getext some_file.v` to get the XML from a libvips +image, and `vipsedit --setext some_file.v < file.xml` to replace the XML. diff --git a/doc/file-format.xml b/doc/file-format.xml deleted file mode 100644 index dc9afe0d15..0000000000 --- a/doc/file-format.xml +++ /dev/null @@ -1,245 +0,0 @@ - - - - - - The VIPS file format - 3 - VIPS Library - - - - File format - The VIPS file format - - - - Codestin Search App - - VIPS has a simple, native file format. It's very fast, there is no image - size limit, and it supports - arbitrary metadata. Although few other programs can read these images - (though recent versions of ImageMagick do have basic support for - .vips - format), it can be useful as an intermediate format for command-line - processing. For example: - - -$ vips invert input.tif t.v -$ vips gamma t.v output.tif - - - is faster than using .tif for the temporary intermediate - image. This section documents the VIPS file format. - - - - VIPS comes with a command-line program called - vipsedit which is useful for destructively changing - fields in a vips image. The vipsheader program can be - used to extract any metadata. - - - - VIPS files come in three parts. First, there is a 64-byte header, - containing an identifying magic number and a set of very basic fields, - such as image width in pixels. Next, the image data is stored as a set - of band-interleaved scanlines, from the top of the image to the bottom. - Finally, after the pixel data comes an optional block of XML containing - any extra metadata, such as an ICC profile or the EXIF data. - - - - - Codestin Search App - - The fields in the VIPS header are always stored least-significant byte - first (Intel ordering). Only the most basic information about the image - is in the header: most metadata is stored in the XML extension block - after the pixel data. - - - - If the first four bytes of the file are in order 08 f2 a6 b6, the image - data (see the next section) - is stored in Intel byte order (LSB first) and will need to be swapped - if read on a SPARC-style machine (MSB first). - If the magic number is b6 a6 f2 08, the image data is in SPARC order - and will need to swapped if read on an Intel-style machine. libvips does - this swapping automatically. - - - Codestin Search App - - - - Bytes - Type - VIPS name - Meaning - - - - - - 0 -- 3 - - - VIPS magic number: 08 f2 a6 b6, or b6 a6 f2 08 - - - - 4 -- 7 - int32 - width - Width of image, in pixels - - - - 8 -- 11 - int32 - height - Height of image, in pixels - - - - 12 -- 15 - int32 - bands - Number of image bands - - - - 16 -- 19 - - - Unused - - - - 20 -- 23 - #VipsBandFormat - format - Band format - - - - 24 -- 27 - #VipsCoding - coding - Image coding - - - - 28 -- 31 - #VipsInterpretation - interpretation - Pixel interpretation - - - - 32 -- 35 - float32 - xres - Horizontal resolution, in pixels per millimetre - - - - 36 -- 39 - float32 - yres - Vertical resolution, in pixels per millimetre - - - - 40 -- 47 - - - Unused - - - - 48 -- 51 - int32 - xoffset - Horizontal offset of origin, in pixels - - - - 52 -- 55 - int32 - yoffset - Vertical offset of origin, in pixels - - - - 56 -- 63 - - - Unused - - - - -
-
- -
- - - Codestin Search App - - If coding is set to #VIPS_CODING_NONE, pixels are stored in - native C format, that is, the native format of the - machine that wrote the data. If you open a big-endian image on a - little-endian machine, VIPS will automatically byte-swap for you. - VIPS has 10 band formats, see #VipsBandFormat. - Image data is stored as a simple list of scanlines, from the top of the - image to the bottom. Pixels are band-interleaved, so RGBRGBRGBRGB, - for example. There is no padding at the end of scanlines. - - - - If coding is set to #VIPS_CODING_LABQ, each pixel is four - bytes, with 10 bits for L* and 11 bits for each of a* and b*. These - 32 bits are packed into 4 bytes, with the most significant 8 bits of each - value in the first 3 bytes, and the left-over bits packed into the final - byte as 2:3:3. - - - - If coding is set to #VIPS_CODING_RAD, each pixel is - RGB or XYZ float, with 8 bits of mantissa - and then 8 bits of exponent, shared between the three channels. This - coding style is used by the Radiance family of programs (and the HDR - format) commonly used for HDR imaging. - - - - Other values of coding can set other coding styles. Use - VIPS_IMAGE_SIZEOF_IMAGE() to calculate the size of the image data - section. - - - - - - Codestin Search App - - Following the image data is a chunk of XML holding a simple list of - name-value pairs. Binary data is encoded with base64. Use - vips_image_set() and friends to set and get image metadata. - - - - You can use vipsheader -f getext some_file.v to get - the XML from a VIPS image, and - vipsedit --setext some_file.v < file.xml to - replace the XML. - - - - -
diff --git a/doc/function-list.md b/doc/function-list.md new file mode 100644 index 0000000000..34f49f94de --- /dev/null +++ b/doc/function-list.md @@ -0,0 +1,360 @@ +Title: All libvips functions and operators + +# Introduction + +libvips has a set of operators, each of which computes some useful image +processing operation. Each operator is implemented as a [class@GObject.Object] +class, for example `VipsGamma`. Classes are identified by their unique +[property@VipsObject:nickname], in this case `gamma`. + +From the command-line, C++ and most language bindings, you use the nickname +to call the operator. For example in C++: + +```c++ +vips::VImage fred = ...; +vips::VImage jim = fred.gamma(); +``` + +or Python: + +```python +fred = jim.gamma() +``` + +libvips has a set of C wrapper functions for calling operators, in this +case [method@Image.gamma]: + +```c + VipsImage *fred = ...; + VipsImage *jim; + + if (vips_gamma(fred, &jim, NULL)) + ...error; +``` + +Some operators have many C convenience functions. + +# All libvips operators + +This table lists all the libvips operators with their C convenience functions +and a short description. It's supposed to be useful for searching. See the +API docs each function links to for more details. + +| Operator | Description | C functions | +| -------- | ----------- | ----------- | +| `CMC2LCh` | Transform lch to cmc | [method@Image.CMC2LCh] | +| `CMYK2XYZ` | Transform cmyk to xyz | [method@Image.CMYK2XYZ] | +| `HSV2sRGB` | Transform hsv to srgb | [method@Image.HSV2sRGB] | +| `LCh2CMC` | Transform lch to cmc | [method@Image.LCh2CMC] | +| `LCh2Lab` | Transform lch to lab | [method@Image.LCh2Lab] | +| `Lab2LCh` | Transform lab to lch | [method@Image.Lab2LCh] | +| `Lab2LabQ` | Transform float lab to labq coding | [method@Image.Lab2LabQ] | +| `Lab2LabS` | Transform float lab to signed short | [method@Image.Lab2LabS] | +| `Lab2XYZ` | Transform cielab to xyz | [method@Image.Lab2XYZ] | +| `LabQ2Lab` | Unpack a labq image to float lab | [method@Image.LabQ2Lab] | +| `LabQ2LabS` | Unpack a labq image to short lab | [method@Image.LabQ2LabS] | +| `LabQ2sRGB` | Convert a labq image to srgb | [method@Image.LabQ2sRGB] | +| `LabS2Lab` | Transform signed short lab to float | [method@Image.LabS2Lab] | +| `LabS2LabQ` | Transform short lab to labq coding | [method@Image.LabS2LabQ] | +| `XYZ2CMYK` | Transform xyz to cmyk | [method@Image.XYZ2CMYK] | +| `XYZ2Lab` | Transform xyz to lab | [method@Image.XYZ2Lab] | +| `XYZ2Yxy` | Transform xyz to yxy | [method@Image.XYZ2Yxy] | +| `XYZ2scRGB` | Transform xyz to scrgb | [method@Image.XYZ2scRGB] | +| `Yxy2XYZ` | Transform yxy to xyz | [method@Image.Yxy2XYZ] | +| `abs` | Absolute value of an image | [method@Image.abs] | +| `add` | Add two images | [method@Image.add] | +| `addalpha` | Append an alpha channel | [method@Image.addalpha] | +| `affine` | Affine transform of an image | [method@Image.affine] | +| `analyzeload` | Load an analyze6 image | [func@analyzeload] | +| `arrayjoin` | Join an array of images | [func@arrayjoin] | +| `autorot` | Autorotate image by exif tag | [method@Image.autorot] | +| `avg` | Find image average | [method@Image.avg] | +| `bandbool` | Boolean operation across image bands | [method@Image.bandbool], [method@Image.bandand], [method@Image.bandor], [method@Image.bandeor], [method@Image.bandmean] | +| `bandfold` | Fold up x axis into bands | [method@Image.bandfold] | +| `bandjoin` | Bandwise join a set of images | [func@bandjoin], [method@Image.bandjoin2] | +| `bandjoin_const` | Append a constant band to an image | [method@Image.bandjoin_const], [method@Image.bandjoin_const1] | +| `bandmean` | Band-wise average | [method@Image.bandmean] | +| `bandrank` | Band-wise rank of a set of images | [func@bandrank] | +| `bandunfold` | Unfold image bands into x axis | [method@Image.bandunfold] | +| `black` | Make a black image | [func@black] | +| `boolean` | Boolean operation on two images | [method@Image.boolean], [method@Image.andimage], [method@Image.orimage], [method@Image.eorimage], [method@Image.lshift], [method@Image.rshift] | +| `boolean_const` | Boolean operations against a constant | [method@Image.boolean_const], [method@Image.andimage_const], [method@Image.orimage_const], [method@Image.eorimage_const], [method@Image.lshift_const], [method@Image.rshift_const], [method@Image.boolean_const1], [method@Image.andimage_const1], [method@Image.orimage_const1], [method@Image.eorimage_const1], [method@Image.lshift_const1], [method@Image.rshift_const1] | +| `buildlut` | Build a look-up table | [method@Image.buildlut] | +| `byteswap` | Byteswap an image | [method@Image.byteswap] | +| `canny` | Canny edge detector | [method@Image.canny] | +| `case` | Use pixel values to pick cases from an array of images | [method@Image.case] | +| `cast` | Cast an image | [method@Image.cast], [method@Image.cast_uchar], [method@Image.cast_char], [method@Image.cast_ushort], [method@Image.cast_short], [method@Image.cast_uint], [method@Image.cast_int], [method@Image.cast_float], [method@Image.cast_double], [method@Image.cast_complex], [method@Image.cast_dpcomplex] | +| `clamp` | Clamp values of an image | [method@Image.clamp] | +| `colourspace` | Convert to a new colorspace | [method@Image.colourspace] | +| `compass` | Convolve with rotating mask | [method@Image.compass] | +| `complex` | Perform a complex operation on an image | [method@Image.complex], [method@Image.polar], [method@Image.rect], [method@Image.conj] | +| `complex2` | Complex binary operations on two images | [method@Image.complex2], [method@Image.cross_phase] | +| `complexform` | Form a complex image from two real images | [method@Image.complexform] | +| `complexget` | Get a component from a complex image | [method@Image.complexget], [method@Image.real], [method@Image.imag] | +| `composite` | Blend an array of images with an array of blend modes | [func@composite] | +| `composite2` | Blend a pair of images with a blend mode | [method@Image.composite2] | +| `conv` | Convolution operation | [method@Image.conv] | +| `conva` | Approximate integer convolution | [method@Image.conva] | +| `convasep` | Approximate separable integer convolution | [method@Image.convasep] | +| `convf` | Float convolution operation | [method@Image.convf] | +| `convi` | Int convolution operation | [method@Image.convi] | +| `convsep` | Separable convolution operation | [method@Image.convsep] | +| `copy` | Copy an image | [method@Image.copy] | +| `countlines` | Count lines in an image | [method@Image.countlines] | +| `csvload` | Load csv | [func@csvload] | +| `csvload_source` | Load csv | [func@csvload_source] | +| `csvsave` | Save image to csv | [method@Image.csvsave] | +| `csvsave_target` | Save image to csv | [method@Image.csvsave_target] | +| `dE00` | Calculate de00 | [method@Image.dE00] | +| `dE76` | Calculate de76 | [method@Image.dE76] | +| `dECMC` | Calculate decmc | [method@Image.dECMC] | +| `deviate` | Find image standard deviation | [method@Image.deviate] | +| `divide` | Divide two images | [method@Image.divide] | +| `draw_circle` | Draw a circle on an image | [method@Image.draw_circle], [method@Image.draw_circle1] | +| `draw_flood` | Flood-fill an area | [method@Image.draw_flood], [method@Image.draw_flood1] | +| `draw_image` | Paint an image into another image | [method@Image.draw_image] | +| `draw_line` | Draw a line on an image | [method@Image.draw_line], [method@Image.draw_line1] | +| `draw_mask` | Draw a mask on an image | [method@Image.draw_mask], [method@Image.draw_mask1] | +| `draw_rect` | Paint a rectangle on an image | [method@Image.draw_rect], [method@Image.draw_rect1], [method@Image.draw_point], [method@Image.draw_point1] | +| `draw_smudge` | Blur a rectangle on an image | [method@Image.draw_smudge] | +| `dzsave` | Save image to deepzoom file | [method@Image.dzsave] | +| `dzsave_buffer` | Save image to dz buffer | [method@Image.dzsave_buffer] | +| `dzsave_target` | Save image to deepzoom target | [method@Image.dzsave_target] | +| `embed` | Embed an image in a larger image | [method@Image.embed] | +| `extract_area` | Extract an area from an image | [method@Image.extract_area], [method@Image.crop] | +| `extract_band` | Extract band from an image | [method@Image.extract_band] | +| `eye` | Make an image showing the eye's spatial response | [func@eye] | +| `falsecolour` | False-color an image | [method@Image.falsecolour] | +| `fastcor` | Fast correlation | [method@Image.fastcor] | +| `fill_nearest` | Fill image zeros with nearest non-zero pixel | [method@Image.fill_nearest] | +| `find_trim` | Search an image for non-edge areas | [method@Image.find_trim] | +| `fitsload` | Load a fits image | [method@Image.fitsload] | +| `fitsload_source` | Load fits from a source | [method@Image.fitsload_source] | +| `fitssave` | Save image to fits file | [method@Image.fitssave] | +| `flatten` | Flatten alpha out of an image | [method@Image.flatten] | +| `flip` | Flip an image | [method@Image.flip] | +| `float2rad` | Transform float rgb to radiance coding | [method@Image.float2rad] | +| `fractsurf` | Make a fractal surface | [func@fractsurf] | +| `freqmult` | Frequency-domain filtering | [method@Image.freqmult] | +| `fwfft` | Forward fft | [method@Image.fwfft] | +| `gamma` | Gamma an image | [method@Image.gamma] | +| `gaussblur` | Gaussian blur | [method@Image.gaussblur] | +| `gaussmat` | Make a gaussian image | [func@gaussmat] | +| `gaussnoise` | Make a gaussnoise image | [func@gaussnoise] | +| `getpoint` | Read a point from an image | [method@Image.getpoint] | +| `gifload` | Load gif with libnsgif | [func@gifload] | +| `gifload_buffer` | Load gif with libnsgif | [func@gifload_buffer] | +| `gifload_source` | Load gif from source | [func@gifload_source] | +| `gifsave` | Save as gif | [method@Image.gifsave] | +| `gifsave_buffer` | Save as gif | [method@Image.gifsave_buffer] | +| `gifsave_target` | Save as gif | [method@Image.gifsave_target] | +| `globalbalance` | Global balance an image mosaic | [method@Image.globalbalance] | +| `gravity` | Place an image within a larger image with a certain gravity | [method@Image.gravity] | +| `grey` | Make a grey ramp image | [func@grey] | +| `grid` | Grid an image | [method@Image.grid] | +| `heifload` | Load a heif image | [func@heifload] | +| `heifload_buffer` | Load a heif image | [func@heifload_buffer] | +| `heifload_source` | Load a heif image | [func@heifload_source] | +| `heifsave` | Save image in heif format | [method@Image.heifsave] | +| `heifsave_buffer` | Save image in heif format | [method@Image.heifsave_buffer] | +| `heifsave_target` | Save image in heif format | [method@Image.heifsave_target] | +| `hist_cum` | Form cumulative histogram | [method@Image.hist_cum] | +| `hist_entropy` | Estimate image entropy | [method@Image.hist_entropy] | +| `hist_equal` | Histogram equalisation | [method@Image.hist_equal] | +| `hist_find` | Find image histogram | [method@Image.hist_find] | +| `hist_find_indexed` | Find indexed image histogram | [method@Image.hist_find_indexed] | +| `hist_find_ndim` | Find n-dimensional image histogram | [method@Image.hist_find_ndim] | +| `hist_ismonotonic` | Test for monotonicity | [method@Image.hist_ismonotonic] | +| `hist_local` | Local histogram equalisation | [method@Image.hist_local] | +| `hist_match` | Match two histograms | [method@Image.hist_match] | +| `hist_norm` | Normalise histogram | [method@Image.hist_norm] | +| `hist_plot` | Plot histogram | [method@Image.hist_plot] | +| `hough_circle` | Find hough circle transform | [method@Image.hough_circle] | +| `hough_line` | Find hough line transform | [method@Image.hough_line] | +| `icc_export` | Output to device with icc profile | [method@Image.icc_export] | +| `icc_import` | Import from device with icc profile | [method@Image.icc_import] | +| `icc_transform` | Transform between devices with icc profiles | [method@Image.icc_transform] | +| `identity` | Make a 1d image where pixel values are indexes | [func@identity] | +| `ifthenelse` | Ifthenelse an image | [method@Image.ifthenelse] | +| `insert` | Insert image @sub into @main at @x, @y | [method@Image.insert] | +| `invert` | Invert an image | [method@Image.invert] | +| `invertlut` | Build an inverted look-up table | [method@Image.invertlut] | +| `invfft` | Inverse fft | [method@Image.invfft] | +| `join` | Join a pair of images | [method@Image.join] | +| `jp2kload` | Load jpeg2000 image | [func@jp2kload] | +| `jp2kload_buffer` | Load jpeg2000 image | [func@jp2kload_buffer] | +| `jp2kload_source` | Load jpeg2000 image | [func@jp2kload_source] | +| `jp2ksave` | Save image in jpeg2000 format | [method@Image.jp2ksave] | +| `jp2ksave_buffer` | Save image in jpeg2000 format | [method@Image.jp2ksave_buffer] | +| `jp2ksave_target` | Save image in jpeg2000 format | [method@Image.jp2ksave_target] | +| `jpegload` | Load jpeg from file | [func@jpegload] | +| `jpegload_buffer` | Load jpeg from buffer | [func@jpegload_buffer] | +| `jpegload_source` | Load image from jpeg source | [func@jpegload_source] | +| `jpegsave` | Save image to jpeg file | [method@Image.jpegsave] | +| `jpegsave_buffer` | Save image to jpeg buffer | [method@Image.jpegsave_buffer] | +| `jpegsave_mime` | Save image to jpeg mime | [method@Image.jpegsave_mime] | +| `jpegsave_target` | Save image to jpeg target | [method@Image.jpegsave_target] | +| `jxlload` | Load jpeg-xl image | [method@Image.jxlload] | +| `jxlload_buffer` | Load jpeg-xl image | [func@jxlload_buffer] | +| `jxlload_source` | Load jpeg-xl image | [func@jxlload_source] | +| `jxlsave` | Save image in jpeg-xl format | [method@Image.jxlsave] | +| `jxlsave_buffer` | Save image in jpeg-xl format | [method@Image.jxlsave_buffer] | +| `jxlsave_target` | Save image in jpeg-xl format | [method@Image.jxlsave_target] | +| `labelregions` | Label regions in an image | [method@Image.labelregions] | +| `linear` | Calculate (a * in + b) | [method@Image.linear], [method@Image.linear1] | +| `linecache` | Cache an image as a set of lines | [method@Image.linecache] | +| `logmat` | Make a laplacian of gaussian image | [func@logmat] | +| `magickload` | Load file with imagemagick | [func@magickload] | +| `magickload_buffer` | Load buffer with imagemagick | [func@magickload_buffer] | +| `magicksave` | Save file with imagemagick | [method@Image.magicksave] | +| `magicksave_buffer` | Save image to magick buffer | [method@Image.magicksave_buffer] | +| `mapim` | Resample with a map image | [method@Image.mapim] | +| `maplut` | Map an image though a lut | [method@Image.maplut] | +| `mask_butterworth` | Make a butterworth filter | [func@mask_butterworth] | +| `mask_butterworth_band` | Make a butterworth_band filter | [func@mask_butterworth_band] | +| `mask_butterworth_ring` | Make a butterworth ring filter | [func@mask_butterworth_ring] | +| `mask_fractal` | Make fractal filter | [func@mask_fractal] | +| `mask_gaussian` | Make a gaussian filter | [func@mask_gaussian] | +| `mask_gaussian_band` | Make a gaussian filter | [func@mask_gaussian_band] | +| `mask_gaussian_ring` | Make a gaussian ring filter | [func@mask_gaussian_ring] | +| `mask_ideal` | Make an ideal filter | [func@mask_ideal] | +| `mask_ideal_band` | Make an ideal band filter | [func@mask_ideal_band] | +| `mask_ideal_ring` | Make an ideal ring filter | [func@mask_ideal_ring] | +| `match` | First-order match of two images | [method@Image.match] | +| `math` | Apply a math operation to an image | [method@Image.math], [method@Image.sin], [method@Image.cos], [method@Image.tan], [method@Image.asin], [method@Image.acos], [method@Image.atan], [method@Image.sinh], [method@Image.cosh], [method@Image.tanh], [method@Image.asinh], [method@Image.acosh], [method@Image.atanh], [method@Image.exp], [method@Image.exp10], [method@Image.log], [method@Image.log10] | +| `math2` | Binary math operations | [method@Image.math2], [method@Image.pow], [method@Image.wop], [method@Image.atan2] | +| `math2_const` | Binary math operations with a constant | [method@Image.math2_const], [method@Image.andimage_const], [method@Image.orimage_const], [method@Image.eorimage_const], [method@Image.lshift_const], [method@Image.rshift_const], [method@Image.math2_const1], [method@Image.andimage_const1], [method@Image.orimage_const1], [method@Image.eorimage_const1], [method@Image.lshift_const1], [method@Image.rshift_const1] | +| `matload` | Load mat from file | [func@matload] | +| `matrixinvert` | Invert a matrix | [method@Image.matrixinvert] | +| `matrixload` | Load matrix | [func@matrixload] | +| `matrixload_source` | Load matrix | [func@matrixload_source] | +| `matrixmultiply` | Multiply two matrices | [method@Image.matrixmultiply] | +| `matrixprint` | Print matrix | [method@Image.matrixprint] | +| `matrixsave` | Save image to matrix | [method@Image.matrixsave] | +| `matrixsave_target` | Save image to matrix | [method@Image.matrixsave_target] | +| `max` | Find image maximum | [method@Image.max] | +| `maxpair` | Maximum of a pair of images | [method@Image.maxpair] | +| `measure` | Measure a set of patches on a color chart | [method@Image.measure] | +| `merge` | Merge two images | [method@Image.merge] | +| `min` | Find image minimum | [method@Image.min] | +| `minpair` | Minimum of a pair of images | [method@Image.minpair] | +| `morph` | Morphology operation | [method@Image.morph] | +| `mosaic` | Mosaic two images | [method@Image.mosaic] | +| `mosaic1` | First-order mosaic of two images | [method@Image.mosaic1] | +| `msb` | Pick most-significant byte from an image | [method@Image.msb] | +| `multiply` | Multiply two images | [method@Image.multiply] | +| `niftiload` | Load nifti volume | [func@niftiload] | +| `niftiload_source` | Load nifti volumes | [func@niftiload_source] | +| `niftisave` | Save image to nifti file | [method@Image.niftisave] | +| `openexrload` | Load an openexr image | [func@openexrload] | +| `openslideload` | Load file with openslide | [func@openslideload] | +| `openslideload_source` | Load source with openslide | [func@openslideload_source] | +| `pdfload` | Load pdf from file | [func@pdfload] | +| `pdfload_buffer` | Load pdf from buffer | [func@pdfload_buffer] | +| `pdfload_source` | Load pdf from source | [func@pdfload_source] | +| `percent` | Find threshold for percent of pixels | [method@Image.percent] | +| `perlin` | Make a perlin noise image | [func@perlin] | +| `phasecor` | Calculate phase correlation | [method@Image.phasecor] | +| `pngload` | Load png from file | [func@pngload] | +| `pngload_buffer` | Load png from buffer | [func@pngload_buffer] | +| `pngload_source` | Load png from source | [func@pngload_source] | +| `pngsave` | Save image to file as png | [method@Image.pngsave] | +| `pngsave_buffer` | Save image to buffer as png | [method@Image.pngsave_buffer] | +| `pngsave_target` | Save image to target as png | [method@Image.pngsave_target] | +| `ppmload` | Load ppm from file | [func@ppmload] | +| `ppmload_source` | Load ppm base class | [func@ppmload_source] | +| `ppmsave` | Save image to ppm file | [method@Image.ppmsave] | +| `ppmsave_target` | Save to ppm | [method@Image.ppmsave_target] | +| `premultiply` | Premultiply image alpha | [method@Image.premultiply] | +| `prewitt` | Prewitt edge detector | [method@Image.prewitt] | +| `profile` | Find image profiles | [method@Image.profile] | +| `profile_load` | Load named icc profile | [func@profile_load] | +| `project` | Find image projections | [method@Image.project] | +| `quadratic` | Resample an image with a quadratic transform | [method@Image.quadratic] | +| `rad2float` | Unpack radiance coding to float rgb | [method@Image.rad2float] | +| `radload` | Load a radiance image from a file | [func@radload] | +| `radload_buffer` | Load rad from buffer | [func@radload_buffer] | +| `radload_source` | Load rad from source | [func@radload_source] | +| `radsave` | Save image to radiance file | [method@Image.radsave] | +| `radsave_buffer` | Save image to radiance buffer | [method@Image.radsave_buffer] | +| `radsave_target` | Save image to radiance target | [method@Image.radsave_target] | +| `rank` | Rank filter | [method@Image.rank], [method@Image.median] | +| `rawload` | Load raw data from a file | [func@rawload] | +| `rawsave` | Save image to raw file | [method@Image.rawsave] | +| `rawsave_buffer` | Write raw image to buffer | [method@Image.rawsave_buffer] | +| `rawsave_target` | Write raw image to target | [method@Image.rawsave_target] | +| `recomb` | Linear recombination with matrix | [method@Image.recomb] | +| `reduce` | Reduce an image | [method@Image.reduce] | +| `reduceh` | Shrink an image horizontally | [method@Image.reduceh] | +| `reducev` | Shrink an image vertically | [method@Image.reducev] | +| `relational` | Relational operation on two images | [method@Image.relational], [method@Image.equal], [method@Image.notequal], [method@Image.less], [method@Image.lesseq], [method@Image.more], [method@Image.moreeq] | +| `relational_const` | Relational operations against a constant | [method@Image.relational_const], [method@Image.equal_const], [method@Image.notequal_const], [method@Image.less_const], [method@Image.lesseq_const], [method@Image.more_const], [method@Image.moreeq_const], [method@Image.relational_const1], [method@Image.equal_const1], [method@Image.notequal_const1], [method@Image.less_const1], [method@Image.lesseq_const1], [method@Image.more_const1], [method@Image.moreeq_const1] | +| `remainder` | Remainder after integer division of two images | [method@Image.remainder] | +| `remainder_const` | Remainder after integer division of an image and a constant | [method@Image.remainder_const], [method@Image.remainder_const1] | +| `replicate` | Replicate an image | [method@Image.replicate] | +| `resize` | Resize an image | [method@Image.resize] | +| `rot` | Rotate an image | [method@Image.rot] | +| `rot45` | Rotate an image | [method@Image.rot45] | +| `rotate` | Rotate an image by a number of degrees | [method@Image.rotate] | +| `round` | Perform a round function on an image | [method@Image.round], [method@Image.floor], [method@Image.ceil], [method@Image.rint] | +| `sRGB2HSV` | Transform srgb to hsv | [method@Image.sRGB2HSV] | +| `sRGB2scRGB` | Convert an srgb image to scrgb | [method@Image.sRGB2scRGB] | +| `scRGB2BW` | Convert scrgb to bw | [method@Image.scRGB2BW] | +| `scRGB2XYZ` | Transform scrgb to xyz | [method@Image.scRGB2XYZ] | +| `scRGB2sRGB` | Convert an scrgb image to srgb | [method@Image.scRGB2sRGB] | +| `scale` | Scale an image to uchar | [method@Image.scale] | +| `scharr` | Scharr edge detector | [method@Image.scharr] | +| `sdf` | Create an sdf image | [func@sdf] | +| `sequential` | Check sequential access | [method@Image.sequential] | +| `sharpen` | Unsharp masking for print | [method@Image.sharpen] | +| `shrink` | Shrink an image | [method@Image.shrink] | +| `shrinkh` | Shrink an image horizontally | [method@Image.shrinkh] | +| `shrinkv` | Shrink an image vertically | [method@Image.shrinkv] | +| `sign` | Unit vector of pixel | [method@Image.sign] | +| `similarity` | Similarity transform of an image | [method@Image.similarity] | +| `sines` | Make a 2d sine wave | [func@sines] | +| `smartcrop` | Extract an area from an image | [method@Image.smartcrop] | +| `sobel` | Sobel edge detector | [method@Image.sobel] | +| `spcor` | Spatial correlation | [method@Image.spcor] | +| `spectrum` | Make displayable power spectrum | [method@Image.spectrum] | +| `stats` | Find many image stats | [method@Image.stats] | +| `stdif` | Statistical difference | [method@Image.stdif] | +| `subsample` | Subsample an image | [method@Image.subsample] | +| `subtract` | Subtract two images | [method@Image.subtract] | +| `sum` | Sum an array of images | [func@sum] | +| `svgload` | Load svg with rsvg | [func@svgload] | +| `svgload_buffer` | Load svg with rsvg | [func@svgload_buffer] | +| `svgload_source` | Load svg from source | [func@svgload_source] | +| `switch` | Find the index of the first non-zero pixel in tests | [func@switch] | +| `system` | Run an external command | [func@system] | +| `text` | Make a text image | [func@text] | +| `thumbnail` | Generate thumbnail from file | [func@thumbnail] | +| `thumbnail_buffer` | Generate thumbnail from buffer | [func@thumbnail_buffer] | +| `thumbnail_image` | Generate thumbnail from image | [method@Image.thumbnail_image] | +| `thumbnail_source` | Generate thumbnail from source | [func@thumbnail_source] | +| `tiffload` | Load tiff from file | [func@tiffload] | +| `tiffload_buffer` | Load tiff from buffer | [func@tiffload_buffer] | +| `tiffload_source` | Load tiff from source | [func@tiffload_source] | +| `tiffsave` | Save image to tiff file | [method@Image.tiffsave] | +| `tiffsave_buffer` | Save image to tiff buffer | [method@Image.tiffsave_buffer] | +| `tiffsave_target` | Save image to tiff target | [method@Image.tiffsave_target] | +| `tilecache` | Cache an image as a set of tiles | [method@Image.tilecache] | +| `tonelut` | Build a look-up table | [func@tonelut] | +| `transpose3d` | Transpose3d an image | [method@Image.transpose3d] | +| `unpremultiply` | Unpremultiply image alpha | [method@Image.unpremultiply] | +| `vipsload` | Load vips from file | [func@vipsload] | +| `vipsload_source` | Load vips from source | [func@vipsload_source] | +| `vipssave` | Save image to file in vips format | [method@Image.vipssave] | +| `vipssave_target` | Save image to target in vips format | [method@Image.vipssave_target] | +| `webpload` | Load webp from file | [func@webpload] | +| `webpload_buffer` | Load webp from buffer | [func@webpload_buffer] | +| `webpload_source` | Load webp from source | [func@webpload_source] | +| `webpsave` | Save as webp | [method@Image.webpsave] | +| `webpsave_buffer` | Save as webp | [method@Image.webpsave_buffer] | +| `webpsave_mime` | Save image to webp mime | [method@Image.webpsave_mime] | +| `webpsave_target` | Save as webp | [method@Image.webpsave_target] | +| `worley` | Make a worley noise image | [func@worley] | +| `wrap` | Wrap image origin | [method@Image.wrap] | +| `xyz` | Make an image where pixel values are coordinates | [func@xyz] | +| `zone` | Make a zone plate | [func@zone] | +| `zoom` | Zoom an image | [method@Image.zoom] | diff --git a/doc/function-list.xml b/doc/function-list.xml deleted file mode 100644 index 3699839199..0000000000 --- a/doc/function-list.xml +++ /dev/null @@ -1,1657 +0,0 @@ - - - - - - VIPS function list - 3 - VIPS Library - - - - Using VIPS - List of VIPS functions and operators - - - - Codestin Search App - - VIPS has a set of operators each of which computes some useful image - processing operation. Each operator is - implemented as a %GObject class, for example VipsGamma. - Classes are identified by their unique nickname, in this - case gamma. - - From the command-line, C++ and most language bindings, you use the - nickname to call the operator. For example in C++: - - - vips::VImage fred = ...; - vips::VImage jim = fred.gamma(); - - - or Python: - - - fred = jim.gamma() - - - VIPS has a set of C wrapper functions for calling operators, in this - case vips_gamma(): - - - VipsImage *fred = ...; - VipsImage *jim; - - if (vips_gamma(fred, &jim, NULL)) - ...error; - - - Some operators have many C convenience functions. - - - - This table lists all the VIPS operators with their C convenience - functions and a short description. It's supposed to be useful for - searching. See the API docs each function links to for more details. - - - - - Codestin Search App - - - - Operator - Description - C functions - - - - - - CMC2LCh - Transform lch to cmc - vips_CMC2LCh() - - - CMYK2XYZ - Transform cmyk to xyz - vips_CMYK2XYZ() - - - HSV2sRGB - Transform hsv to srgb - vips_HSV2sRGB() - - - LCh2CMC - Transform lch to cmc - vips_LCh2CMC() - - - LCh2Lab - Transform lch to lab - vips_LCh2Lab() - - - Lab2LCh - Transform lab to lch - vips_Lab2LCh() - - - Lab2LabQ - Transform float lab to labq coding - vips_Lab2LabQ() - - - Lab2LabS - Transform float lab to signed short - vips_Lab2LabS() - - - Lab2XYZ - Transform cielab to xyz - vips_Lab2XYZ() - - - LabQ2Lab - Unpack a labq image to float lab - vips_LabQ2Lab() - - - LabQ2LabS - Unpack a labq image to short lab - vips_LabQ2LabS() - - - LabQ2sRGB - Convert a labq image to srgb - vips_LabQ2sRGB() - - - LabS2Lab - Transform signed short lab to float - vips_LabS2Lab() - - - LabS2LabQ - Transform short lab to labq coding - vips_LabS2LabQ() - - - XYZ2CMYK - Transform xyz to cmyk - vips_XYZ2CMYK() - - - XYZ2Lab - Transform xyz to lab - vips_XYZ2Lab() - - - XYZ2Yxy - Transform xyz to yxy - vips_XYZ2Yxy() - - - XYZ2scRGB - Transform xyz to scrgb - vips_XYZ2scRGB() - - - Yxy2XYZ - Transform yxy to xyz - vips_Yxy2XYZ() - - - abs - Absolute value of an image - vips_abs() - - - add - Add two images - vips_add() - - - addalpha - Append an alpha channel - vips_addalpha() - - - affine - Affine transform of an image - vips_affine() - - - analyzeload - Load an analyze6 image - vips_analyzeload() - - - arrayjoin - Join an array of images - vips_arrayjoin() - - - autorot - Autorotate image by exif tag - vips_autorot() - - - avg - Find image average - vips_avg() - - - bandbool - Boolean operation across image bands - vips_bandbool(), vips_bandand(), vips_bandor(), vips_bandeor(), vips_bandmean() - - - bandfold - Fold up x axis into bands - vips_bandfold() - - - bandjoin - Bandwise join a set of images - vips_bandjoin(), vips_bandjoin2() - - - bandjoin_const - Append a constant band to an image - vips_bandjoin_const(), vips_bandjoin_const1() - - - bandmean - Band-wise average - vips_bandmean() - - - bandrank - Band-wise rank of a set of images - vips_bandrank() - - - bandunfold - Unfold image bands into x axis - vips_bandunfold() - - - black - Make a black image - vips_black() - - - boolean - Boolean operation on two images - vips_boolean(), vips_andimage(), vips_orimage(), vips_eorimage(), vips_lshift(), vips_rshift() - - - boolean_const - Boolean operations against a constant - vips_boolean_const(), vips_andimage_const(), vips_orimage_const(), vips_eorimage_const(), vips_lshift_const(), vips_rshift_const(), vips_boolean_const1(), vips_andimage_const1(), vips_orimage_const1(), vips_eorimage_const1(), vips_lshift_const1(), vips_rshift_const1() - - - buildlut - Build a look-up table - vips_buildlut() - - - byteswap - Byteswap an image - vips_byteswap() - - - canny - Canny edge detector - vips_canny() - - - case - Use pixel values to pick cases from an array of images - vips_case() - - - cast - Cast an image - vips_cast(), vips_cast_uchar(), vips_cast_char(), vips_cast_ushort(), vips_cast_shortcast_uint(), vips_cast_int(), vips_cast_float(), vips_cast_double(), vips_cast_complex(), vips_cast_dpcomplex() - - - clamp - Clamp values of an image - vips_clamp() - - - colourspace - Convert to a new colorspace - vips_colourspace() - - - compass - Convolve with rotating mask - vips_compass() - - - complex - Perform a complex operation on an image - vips_complex(), vips_polar(), vips_rect(), vips_conj() - - - complex2 - Complex binary operations on two images - vips_complex2(), vips_cross_phase() - - - complexform - Form a complex image from two real images - vips_complexform() - - - complexget - Get a component from a complex image - vips_complexget(), vips_real(), vips_imag() - - - composite - Blend an array of images with an array of blend modes - vips_composite() - - - composite2 - Blend a pair of images with a blend mode - vips_composite2() - - - conv - Convolution operation - vips_conv() - - - conva - Approximate integer convolution - vips_conva() - - - convasep - Approximate separable integer convolution - vips_convasep() - - - convf - Float convolution operation - vips_convf() - - - convi - Int convolution operation - vips_convi() - - - convsep - Separable convolution operation - vips_convsep() - - - copy - Copy an image - vips_copy() - - - countlines - Count lines in an image - vips_countlines() - - - csvload - Load csv - vips_csvload() - - - csvload_source - Load csv - vips_csvload_source() - - - csvsave - Save image to csv - vips_csvsave() - - - csvsave_target - Save image to csv - vips_csvsave_target() - - - dE00 - Calculate de00 - vips_dE00() - - - dE76 - Calculate de76 - vips_dE76() - - - dECMC - Calculate decmc - vips_dECMC() - - - deviate - Find image standard deviation - vips_deviate() - - - divide - Divide two images - vips_divide() - - - draw_circle - Draw a circle on an image - vips_draw_circle(), vips_draw_circle1() - - - draw_flood - Flood-fill an area - vips_draw_flood(), vips_draw_flood1() - - - draw_image - Paint an image into another image - vips_draw_image() - - - draw_line - Draw a line on an image - vips_draw_line(), vips_draw_line1() - - - draw_mask - Draw a mask on an image - vips_draw_mask(), vips_draw_mask1() - - - draw_rect - Paint a rectangle on an image - vips_draw_rect(), vips_draw_rect1(), vips_draw_point(), vips_draw_point1() - - - draw_smudge - Blur a rectangle on an image - vips_draw_smudge() - - - dzsave - Save image to deepzoom file - vips_dzsave() - - - dzsave_buffer - Save image to dz buffer - vips_dzsave_buffer() - - - dzsave_target - Save image to deepzoom target - vips_dzsave_target() - - - embed - Embed an image in a larger image - vips_embed() - - - extract_area - Extract an area from an image - vips_extract_area(), vips_crop() - - - extract_band - Extract band from an image - vips_extract_band() - - - eye - Make an image showing the eye's spatial response - vips_eye() - - - falsecolour - False-color an image - vips_falsecolour() - - - fastcor - Fast correlation - vips_fastcor() - - - fill_nearest - Fill image zeros with nearest non-zero pixel - vips_fill_nearest() - - - find_trim - Search an image for non-edge areas - vips_find_trim() - - - fitsload - Load a fits image - vips_fitsload() - - - fitsload_source - Load fits from a source - vips_fitsload_source() - - - fitssave - Save image to fits file - vips_fitssave() - - - flatten - Flatten alpha out of an image - vips_flatten() - - - flip - Flip an image - vips_flip() - - - float2rad - Transform float rgb to radiance coding - vips_float2rad() - - - fractsurf - Make a fractal surface - vips_fractsurf() - - - freqmult - Frequency-domain filtering - vips_freqmult() - - - fwfft - Forward fft - vips_fwfft() - - - gamma - Gamma an image - vips_gamma() - - - gaussblur - Gaussian blur - vips_gaussblur() - - - gaussmat - Make a gaussian image - vips_gaussmat() - - - gaussnoise - Make a gaussnoise image - vips_gaussnoise() - - - getpoint - Read a point from an image - vips_getpoint() - - - gifload - Load gif with libnsgif - vips_gifload() - - - gifload_buffer - Load gif with libnsgif - vips_gifload_buffer() - - - gifload_source - Load gif from source - vips_gifload_source() - - - gifsave - Save as gif - vips_gifsave() - - - gifsave_buffer - Save as gif - vips_gifsave_buffer() - - - gifsave_target - Save as gif - vips_gifsave_target() - - - globalbalance - Global balance an image mosaic - vips_globalbalance() - - - gravity - Place an image within a larger image with a certain gravity - vips_gravity() - - - grey - Make a grey ramp image - vips_grey() - - - grid - Grid an image - vips_grid() - - - heifload - Load a heif image - vips_heifload() - - - heifload_buffer - Load a heif image - vips_heifload_buffer() - - - heifload_source - Load a heif image - vips_heifload_source() - - - heifsave - Save image in heif format - vips_heifsave() - - - heifsave_buffer - Save image in heif format - vips_heifsave_buffer() - - - heifsave_target - Save image in heif format - vips_heifsave_target() - - - hist_cum - Form cumulative histogram - vips_hist_cum() - - - hist_entropy - Estimate image entropy - vips_hist_entropy() - - - hist_equal - Histogram equalisation - vips_hist_equal() - - - hist_find - Find image histogram - vips_hist_find() - - - hist_find_indexed - Find indexed image histogram - vips_hist_find_indexed() - - - hist_find_ndim - Find n-dimensional image histogram - vips_hist_find_ndim() - - - hist_ismonotonic - Test for monotonicity - vips_hist_ismonotonic() - - - hist_local - Local histogram equalisation - vips_hist_local() - - - hist_match - Match two histograms - vips_hist_match() - - - hist_norm - Normalise histogram - vips_hist_norm() - - - hist_plot - Plot histogram - vips_hist_plot() - - - hough_circle - Find hough circle transform - vips_hough_circle() - - - hough_line - Find hough line transform - vips_hough_line() - - - icc_export - Output to device with icc profile - vips_icc_export() - - - icc_import - Import from device with icc profile - vips_icc_import() - - - icc_transform - Transform between devices with icc profiles - vips_icc_transform() - - - identity - Make a 1d image where pixel values are indexes - vips_identity() - - - ifthenelse - Ifthenelse an image - vips_ifthenelse() - - - insert - Insert image @sub into @main at @x, @y - vips_insert() - - - invert - Invert an image - vips_invert() - - - invertlut - Build an inverted look-up table - vips_invertlut() - - - invfft - Inverse fft - vips_invfft() - - - join - Join a pair of images - vips_join() - - - jp2kload - Load jpeg2000 image - vips_jp2kload() - - - jp2kload_buffer - Load jpeg2000 image - vips_jp2kload_buffer() - - - jp2kload_source - Load jpeg2000 image - vips_jp2kload_source() - - - jp2ksave - Save image in jpeg2000 format - vips_jp2ksave() - - - jp2ksave_buffer - Save image in jpeg2000 format - vips_jp2ksave_buffer() - - - jp2ksave_target - Save image in jpeg2000 format - vips_jp2ksave_target() - - - jpegload - Load jpeg from file - vips_jpegload() - - - jpegload_buffer - Load jpeg from buffer - vips_jpegload_buffer() - - - jpegload_source - Load image from jpeg source - vips_jpegload_source() - - - jpegsave - Save image to jpeg file - vips_jpegsave() - - - jpegsave_buffer - Save image to jpeg buffer - vips_jpegsave_buffer() - - - jpegsave_mime - Save image to jpeg mime - vips_jpegsave_mime() - - - jpegsave_target - Save image to jpeg target - vips_jpegsave_target() - - - jxlload - Load jpeg-xl image - vips_jxlload() - - - jxlload_buffer - Load jpeg-xl image - vips_jxlload_buffer() - - - jxlload_source - Load jpeg-xl image - vips_jxlload_source() - - - jxlsave - Save image in jpeg-xl format - vips_jxlsave() - - - jxlsave_buffer - Save image in jpeg-xl format - vips_jxlsave_buffer() - - - jxlsave_target - Save image in jpeg-xl format - vips_jxlsave_target() - - - labelregions - Label regions in an image - vips_labelregions() - - - linear - Calculate (a * in + b) - vips_linear(), vips_linear1() - - - linecache - Cache an image as a set of lines - vips_linecache() - - - logmat - Make a laplacian of gaussian image - vips_logmat() - - - magickload - Load file with imagemagick - vips_magickload() - - - magickload_buffer - Load buffer with imagemagick - vips_magickload_buffer() - - - magicksave - Save file with imagemagick - vips_magicksave() - - - magicksave_buffer - Save image to magick buffer - vips_magicksave_buffer() - - - mapim - Resample with a map image - vips_mapim() - - - maplut - Map an image though a lut - vips_maplut() - - - mask_butterworth - Make a butterworth filter - vips_mask_butterworth() - - - mask_butterworth_band - Make a butterworth_band filter - vips_mask_butterworth_band() - - - mask_butterworth_ring - Make a butterworth ring filter - vips_mask_butterworth_ring() - - - mask_fractal - Make fractal filter - vips_mask_fractal() - - - mask_gaussian - Make a gaussian filter - vips_mask_gaussian() - - - mask_gaussian_band - Make a gaussian filter - vips_mask_gaussian_band() - - - mask_gaussian_ring - Make a gaussian ring filter - vips_mask_gaussian_ring() - - - mask_ideal - Make an ideal filter - vips_mask_ideal() - - - mask_ideal_band - Make an ideal band filter - vips_mask_ideal_band() - - - mask_ideal_ring - Make an ideal ring filter - vips_mask_ideal_ring() - - - match - First-order match of two images - vips_match() - - - math - Apply a math operation to an image - vips_math(), vips_sin(), vips_cos(), vips_tan(), vips_asin(), vips_acos(), vips_atan(), vips_sinh(), vips_cosh(), vips_tanh(), vips_asinh(), vips_acosh(), vips_atanh(), vips_exp(), vips_exp10(), vips_log(), vips_log10() - - - math2 - Binary math operations - vips_math2(), vips_pow(), vips_wop(), vips_atan2() - - - math2_const - Binary math operations with a constant - vips_math2_const(), vips_andimage_const(), vips_orimage_const(), vips_eorimage_const(), vips_lshift_const(), vips_rshift_const(), vips_math2_const1(), vips_andimage_const1(), vips_orimage_const1(), vips_eorimage_const1(), vips_lshift_const1(), vips_rshift_const1() - - - matload - Load mat from file - vips_matload() - - - matrixinvert - Invert an matrix - vips_matrixinvert() - - - matrixload - Load matrix - vips_matrixload() - - - matrixload_source - Load matrix - vips_matrixload_source() - - - matrixprint - Print matrix - vips_matrixprint() - - - matrixsave - Save image to matrix - vips_matrixsave() - - - matrixsave_target - Save image to matrix - vips_matrixsave_target() - - - max - Find image maximum - vips_max() - - - maxpair - Maximum of a pair of images - vips_maxpair() - - - measure - Measure a set of patches on a color chart - vips_measure() - - - merge - Merge two images - vips_merge() - - - min - Find image minimum - vips_min() - - - minpair - Minimum of a pair of images - vips_minpair() - - - morph - Morphology operation - vips_morph() - - - mosaic - Mosaic two images - vips_mosaic() - - - mosaic1 - First-order mosaic of two images - vips_mosaic1() - - - msb - Pick most-significant byte from an image - vips_msb() - - - multiply - Multiply two images - vips_multiply() - - - niftiload - Load nifti volume - vips_niftiload() - - - niftiload_source - Load nifti volumes - vips_niftiload_source() - - - niftisave - Save image to nifti file - vips_niftisave() - - - openexrload - Load an openexr image - vips_openexrload() - - - openslideload - Load file with openslide - vips_openslideload() - - - openslideload_source - Load source with openslide - vips_openslideload_source() - - - pdfload - Load pdf from file - vips_pdfload() - - - pdfload_buffer - Load pdf from buffer - vips_pdfload_buffer() - - - pdfload_source - Load pdf from source - vips_pdfload_source() - - - percent - Find threshold for percent of pixels - vips_percent() - - - perlin - Make a perlin noise image - vips_perlin() - - - phasecor - Calculate phase correlation - vips_phasecor() - - - pngload - Load png from file - vips_pngload() - - - pngload_buffer - Load png from buffer - vips_pngload_buffer() - - - pngload_source - Load png from source - vips_pngload_source() - - - pngsave - Save image to file as png - vips_pngsave() - - - pngsave_buffer - Save image to buffer as png - vips_pngsave_buffer() - - - pngsave_target - Save image to target as png - vips_pngsave_target() - - - ppmload - Load ppm from file - vips_ppmload() - - - ppmload_source - Load ppm base class - vips_ppmload_source() - - - ppmsave - Save image to ppm file - vips_ppmsave() - - - ppmsave_target - Save to ppm - vips_ppmsave_target() - - - premultiply - Premultiply image alpha - vips_premultiply() - - - prewitt - Prewitt edge detector - vips_prewitt() - - - profile - Find image profiles - vips_profile() - - - profile_load - Load named icc profile - vips_profile_load() - - - project - Find image projections - vips_project() - - - quadratic - Resample an image with a quadratic transform - vips_quadratic() - - - rad2float - Unpack radiance coding to float rgb - vips_rad2float() - - - radload - Load a radiance image from a file - vips_radload() - - - radload_buffer - Load rad from buffer - vips_radload_buffer() - - - radload_source - Load rad from source - vips_radload_source() - - - radsave - Save image to radiance file - vips_radsave() - - - radsave_buffer - Save image to radiance buffer - vips_radsave_buffer() - - - radsave_target - Save image to radiance target - vips_radsave_target() - - - rank - Rank filter - vips_rank(), vips_median() - - - rawload - Load raw data from a file - vips_rawload() - - - rawsave - Save image to raw file - vips_rawsave() - - - rawsave_buffer - Write raw image to buffer - vips_rawsave_buffer() - - - rawsave_target - Write raw image to target - vips_rawsave_target() - - - recomb - Linear recombination with matrix - vips_recomb() - - - reduce - Reduce an image - vips_reduce() - - - reduceh - Shrink an image horizontally - vips_reduceh() - - - reducev - Shrink an image vertically - vips_reducev() - - - relational - Relational operation on two images - vips_relational(), vips_equal(), vips_notequal(), vips_less(), vips_lesseq(), vips_more(), vips_moreeq() - - - relational_const - Relational operations against a constant - vips_relational_const(), vips_equal_const(), vips_notequal_const(), vips_less_const(), vips_lesseq_const(), vips_more_const(), vips_moreeq_const(), vips_relational_const1(), vips_equal_const1(), vips_notequal_const1(), vips_less_const1(), vips_lesseq_const1(), vips_more_const1(), vips_moreeq_const1() - - - remainder - Remainder after integer division of two images - vips_remainder() - - - remainder_const - Remainder after integer division of an image and a constant - vips_remainder_const(), vips_remainder_const1() - - - replicate - Replicate an image - vips_replicate() - - - resize - Resize an image - vips_resize() - - - rot - Rotate an image - vips_rot() - - - rot45 - Rotate an image - vips_rot45() - - - rotate - Rotate an image by a number of degrees - vips_rotate() - - - round - Perform a round function on an image - vips_round(), vips_floor(), vips_ceil(), vips_rint() - - - sRGB2HSV - Transform srgb to hsv - vips_sRGB2HSV() - - - sRGB2scRGB - Convert an srgb image to scrgb - vips_sRGB2scRGB() - - - scRGB2BW - Convert scrgb to bw - vips_scRGB2BW() - - - scRGB2XYZ - Transform scrgb to xyz - vips_scRGB2XYZ() - - - scRGB2sRGB - Convert an scrgb image to srgb - vips_scRGB2sRGB() - - - scale - Scale an image to uchar - vips_scale() - - - scharr - Scharr edge detector - vips_scharr() - - - sdf - Create an sdf image - vips_sdf() - - - sequential - Check sequential access - vips_sequential() - - - sharpen - Unsharp masking for print - vips_sharpen() - - - shrink - Shrink an image - vips_shrink() - - - shrinkh - Shrink an image horizontally - vips_shrinkh() - - - shrinkv - Shrink an image vertically - vips_shrinkv() - - - sign - Unit vector of pixel - vips_sign() - - - similarity - Similarity transform of an image - vips_similarity() - - - sines - Make a 2d sine wave - vips_sines() - - - smartcrop - Extract an area from an image - vips_smartcrop() - - - sobel - Sobel edge detector - vips_sobel() - - - spcor - Spatial correlation - vips_spcor() - - - spectrum - Make displayable power spectrum - vips_spectrum() - - - stats - Find many image stats - vips_stats() - - - stdif - Statistical difference - vips_stdif() - - - subsample - Subsample an image - vips_subsample() - - - subtract - Subtract two images - vips_subtract() - - - sum - Sum an array of images - vips_sum() - - - svgload - Load svg with rsvg - vips_svgload() - - - svgload_buffer - Load svg with rsvg - vips_svgload_buffer() - - - svgload_source - Load svg from source - vips_svgload_source() - - - switch - Find the index of the first non-zero pixel in tests - vips_switch() - - - system - Run an external command - vips_system() - - - text - Make a text image - vips_text() - - - thumbnail - Generate thumbnail from file - vips_thumbnail() - - - thumbnail_buffer - Generate thumbnail from buffer - vips_thumbnail_buffer() - - - thumbnail_image - Generate thumbnail from image - vips_thumbnail_image() - - - thumbnail_source - Generate thumbnail from source - vips_thumbnail_source() - - - tiffload - Load tiff from file - vips_tiffload() - - - tiffload_buffer - Load tiff from buffer - vips_tiffload_buffer() - - - tiffload_source - Load tiff from source - vips_tiffload_source() - - - tiffsave - Save image to tiff file - vips_tiffsave() - - - tiffsave_buffer - Save image to tiff buffer - vips_tiffsave_buffer() - - - tiffsave_target - Save image to tiff target - vips_tiffsave_target() - - - tilecache - Cache an image as a set of tiles - vips_tilecache() - - - tonelut - Build a look-up table - vips_tonelut() - - - transpose3d - Transpose3d an image - vips_transpose3d() - - - unpremultiply - Unpremultiply image alpha - vips_unpremultiply() - - - vipsload - Load vips from file - vips_vipsload() - - - vipsload_source - Load vips from source - vips_vipsload_source() - - - vipssave - Save image to file in vips format - vips_vipssave() - - - vipssave_target - Save image to target in vips format - vips_vipssave_target() - - - webpload - Load webp from file - vips_webpload() - - - webpload_buffer - Load webp from buffer - vips_webpload_buffer() - - - webpload_source - Load webp from source - vips_webpload_source() - - - webpsave - Save as webp - vips_webpsave() - - - webpsave_buffer - Save as webp - vips_webpsave_buffer() - - - webpsave_mime - Save image to webp mime - vips_webpsave_mime() - - - webpsave_target - Save as webp - vips_webpsave_target() - - - worley - Make a worley noise image - vips_worley() - - - wrap - Wrap image origin - vips_wrap() - - - xyz - Make an image where pixel values are coordinates - vips_xyz() - - - zone - Make a zone plate - vips_zone() - - - zoom - Zoom an image - vips_zoom() - - - - -
-
- -
- -
diff --git a/doc/gen-function-list.py b/doc/gen-function-list.py index a7f2d38b41..5755af59c4 100755 --- a/doc/gen-function-list.py +++ b/doc/gen-function-list.py @@ -30,11 +30,7 @@ def gen_function(operation_name, overloads): if overloads: c_operations += ', ' + (', '.join('vips_{}()'.format(n) for n in overloads)) - result = '\n' - result += ' {}\n'.format(operation_name) - result += ' {}\n'.format(intro.description.capitalize()) - result += ' {}\n'.format(c_operations) - result += '' + result = f"| `{operation_name}` | {intro.description.capitalize()} | {c_operations} |" return result @@ -70,8 +66,9 @@ def add_nickname(gtype, a, b): 'bandjoin': ['bandjoin2'], 'bandjoin_const': ['bandjoin_const1'], 'boolean': ['andimage', 'orimage', 'eorimage', 'lshift', 'rshift'], - 'cast': ['cast_uchar', 'cast_char', 'cast_ushort', 'cast_short' 'cast_uint', 'cast_int', 'cast_float', - 'cast_double', 'cast_complex', 'cast_dpcomplex'], + 'cast': ['cast_uchar', 'cast_char', 'cast_ushort', 'cast_short', + 'cast_uint', 'cast_int', 'cast_float', 'cast_double', + 'cast_complex', 'cast_dpcomplex'], 'complex': ['polar', 'rect', 'conj'], 'complex2': ['cross_phase'], 'complexget': ['real', 'imag'], @@ -82,7 +79,9 @@ def add_nickname(gtype, a, b): 'draw_rect': ['draw_rect1', 'draw_point', 'draw_point1'], 'extract_area': ['crop'], 'linear': ['linear1'], - 'math': ['sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'sinh', 'cosh', 'tanh', 'asinh', 'acosh', 'atanh', 'exp', 'exp10', 'log', 'log10'], + 'math': ['sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'sinh', + 'cosh', 'tanh', 'asinh', 'acosh', 'atanh', 'exp', 'exp10', + 'log', 'log10'], 'math2': ['pow', 'wop', 'atan2'], 'rank': ['median'], 'relational': ['equal', 'notequal', 'less', 'lesseq', 'more', 'moreeq'], @@ -90,19 +89,71 @@ def add_nickname(gtype, a, b): 'round': ['floor', 'ceil', 'rint'], } - overloads['boolean_const'] = [o + '_const' for o in overloads['boolean']] + ['boolean_const1'] + \ - [o + '_const1' for o in overloads['boolean']] + overloads['boolean_const'] = \ + [o + '_const' for o in overloads['boolean']] \ + + ['boolean_const1'] \ + + [o + '_const1' for o in overloads['boolean']] - overloads['math2_const'] = [o + '_const' for o in overloads['boolean']] + ['math2_const1'] + \ - [o + '_const1' for o in overloads['boolean']] + overloads['math2_const'] = \ + [o + '_const' for o in overloads['boolean']] \ + + ['math2_const1'] \ + + [o + '_const1' for o in overloads['boolean']] - overloads['relational_const'] = [o + '_const' for o in overloads['relational']] + ['relational_const1'] + \ - [o + '_const1' for o in overloads['relational']] + overloads['relational_const'] = \ + [o + '_const' for o in overloads['relational']] \ + + ['relational_const1'] \ + + [o + '_const1' for o in overloads['relational']] for nickname in all_nicknames: - result = gen_function(nickname, overloads[nickname] if nickname in overloads else None) + result = gen_function(nickname, + overloads[nickname] if nickname in overloads else None) print(result) if __name__ == '__main__': + print("""Title: All libvips functions and operators + +# Introduction + +libvips has a set of operators, each of which computes some useful image +processing operation. Each operator is implemented as a [class@GObject.Object] +class, for example `VipsGamma`. Classes are identified by their unique +[property@VipsObject:nickname], in this case `gamma`. + +From the command-line, C++ and most language bindings, you use the nickname +to call the operator. For example in C++: + +```c++ +vips::VImage fred = ...; +vips::VImage jim = fred.gamma(); +``` + +or Python: + +```python +fred = jim.gamma() +``` + +libvips has a set of C wrapper functions for calling operators, in this +case [method@Image.gamma]: + +```c + VipsImage *fred = ...; + VipsImage *jim; + + if (vips_gamma(fred, &jim, NULL)) + ...error; +``` + +Some operators have many C convenience functions. + +# All libvips operators + +This table lists all the libvips operators with their C convenience functions +and a short description. It's supposed to be useful for searching. See the +API docs each function links to for more details. + +| Operator | Description | C functions | +| -------- | ----------- | ----------- |""") + gen_function_list() diff --git a/doc/How-it-opens-files.md b/doc/how-it-opens-files.md similarity index 86% rename from doc/How-it-opens-files.md rename to doc/how-it-opens-files.md index 160cca2107..2c7c402d64 100644 --- a/doc/How-it-opens-files.md +++ b/doc/how-it-opens-files.md @@ -1,13 +1,6 @@ - - Opening files - 3 - libvips - +Title: How libvips opens files - - Opening - How libvips opens files - +# How libvips opens files libvips has at least four different ways of opening image files, each best for different file types, file sizes and image use cases. libvips tries @@ -16,18 +9,18 @@ know what it is doing behind the scenes, except unfortunately when you do. This page tries to explain what the different strategies are and when each is used. If you are running into unexpected memory, disc or CPU use, this might -be helpful. `vips_image_new_from_file()` has the official documentation. +be helpful. [ctor@Image.new_from_file] has the official documentation. -# Caching +## Caching libvips caches recent operations. This means that if a file changes between one load and the next, the second load will return the old image, even though the file has been replaced. You can force libvips to load a file and ignore any cached value by -setting the `revalidate` flag, see #VipsForeignLoad. +setting the `revalidate` flag, see [class@ForeignLoad]. -# Direct access +## Direct access This is the fastest and simplest one. The file is mapped directly into the process's address space and can be read with ordinary pointer access. Small @@ -39,14 +32,13 @@ system: your OS will use spare memory to cache recently used chunks of the file. For this to be possible, the file format needs to be a simple dump of a memory -array. libvips supports direct access for vips, 8-bit binary ppm/pbm/pnm, +array. libvips supports direct access for `.v`, 8-bit binary ppm/pbm/pnm, analyse and raw. libvips has a special direct write mode where pixels can be written directly -to the file image. This is used for the draw -operators. +to the file image. This is used for the [draw operators](?q=draw). -# Random access via load library +## Random access via load library Some image file formats have libraries which allow true random access to image pixels. For example, libtiff lets you read any tile out of a tiled @@ -64,7 +56,7 @@ same tile. libvips can load tiled tiff, tiled OpenEXR, FITS and OpenSlide images in this manner. -# Full decompression +## Full decompression Many image load libraries do not support random access. In order to use images of this type as inputs to pipelines, libvips has to convert them @@ -79,15 +71,14 @@ Note that on open libvips just reads the image header and is quick: the image decompress happens on the first pixel access. You can control this process with environment variables, command-line -flags and API calls as you choose, see -vips_image_new_from_file(). +flags and API calls as you choose, see [ctor@Image.new_from_file]. They let you set the threshold at which libvips switches between memory and disc and where on disc the temporary files are held. This is the slowest and most memory-hungry way to read files, but it's unavoidable for many file formats. Unless you can use the next one! -# Sequential access +## Sequential access This a fairly recent addition to libvips and is a hybrid of the previous two. @@ -127,4 +118,4 @@ small cache of the most recent 100 or so lines. This is done automatically in command-line operation. In programs, you need to set `access` to #VIPS_ACCESS_SEQUENTIAL in calls to functions like -vips_image_new_from_file(). +[ctor@Image.new_from_file]. diff --git a/doc/How-it-works.md b/doc/how-it-works.md similarity index 61% rename from doc/How-it-works.md rename to doc/how-it-works.md index a53082b377..1f344fc674 100644 --- a/doc/How-it-works.md +++ b/doc/how-it-works.md @@ -1,29 +1,22 @@ - - How libvips works - 3 - libvips - - - - Internals - A high-level technical overview of libvips's evaluation system - - -Compared to most image processing libraries, VIPS needs little RAM and runs -quickly, especially on machines with more than one CPU. VIPS achieves this +Title: A high-level technical overview of libvips's evaluation system + +# A high-level technical overview of libvips's evaluation system + +Compared to most image processing libraries, libvips needs little RAM and runs +quickly, especially on machines with more than one CPU. libvips achieves this improvement by only keeping the pixels currently being processed in RAM and by having an efficient, threaded image IO system. This page explains how these features are implemented. -**Images** +## Images -VIPS images have three dimensions: width, height and bands. Bands usually +libvips images have three dimensions: width, height and bands. Bands usually (though not always) represent colour. These three dimensions can be any size up to 2 ** 31 elements. Every band element in an image has to have the same format. A format is an 8-, 16- or 32-bit int, signed or unsigned, 32- or 64-bit float, and 64- or 128-bit complex. -**Regions** +## Regions An image can be very large, much larger than the available memory, so you can't just access pixels with a pointer \*. @@ -51,27 +44,28 @@ if (vips_region_prepare(region, &r)) // add VIPS_REGION_LSKIP() to move down a line VipsPel *pixel = VIPS_REGION_ADDR(region, x, y); -// you can call vips_region_prepare() many times +// you can call [method@Region.prepare] many times // everything in libvips is a GObject ... when you're done, // just free with g_object_unref(region); ``` -The action that `vips_region_prepare()` takes varies with the type of -image. If the image is a file on disc, for example, then VIPS will arrange +The action that [method@Region.prepare] takes varies with the type of +image. If the image is a file on disc, for example, then libvips will arrange for a section of the file to be read in. (\* there is an image access mode where you can just use a pointer, but it's rarely used) -**Partial images** +## Partial images -A partial image is one where, instead of storing a value for each pixel, VIPS -stores a function which can make any rectangular area of pixels on demand. +A partial image is one where, instead of storing a value for each pixel, +libvips stores a function which can make any rectangular area of pixels +on demand. -If you use `vips_region_prepare()` on a region created on a partial image, -VIPS will allocate enough memory to hold the pixels you asked for and use +If you use [method@Region.prepare] on a region created on a partial image, +libvips will allocate enough memory to hold the pixels you asked for and use the stored function to calculate values for just those pixels \*. The stored function comes in three parts: a start function, a generate @@ -82,47 +76,45 @@ function into three parts is good for SMP scaling: resource allocation and synchronisation mostly happens in start functions, so generate functions can run without having to talk to each other. -VIPS makes a set of guarantees about parallelism that make this simple to +libvips makes a set of guarantees about parallelism that make this simple to program. Start and stop functions are mutually exclusive and a state is never used by more than one generate. In other words, a start / generate / generate / stop sequence works like a thread. -![](Sequence.png) +![Sequence](Sequence.png) -(\* in fact VIPS keeps a cache of calculated pixel buffers and will return +(\* in fact libvips keeps a cache of calculated pixel buffers and will return a pointer to a previously-calculated buffer if it can) -**Operations** +# Operations -VIPS operations read input images and write output images, performing some +libvips operations read input images and write output images, performing some transformation on the pixels. When an operation writes to an image the action it takes depends upon the image type. For example, if the image is a -file on disc then VIPS will start a data sink to stream pixels to the file, +file on disc then libvips will start a data sink to stream pixels to the file, or if the image is a partial one then it will just attach start / generate / stop functions. -Like most threaded image processing systems, all VIPS operations have to +Like most threaded image processing systems, all libvips operations have to be free of side-effects. In other words, operations cannot modify images, they can only create new images. This could result in a lot of copying if -an operation is only making a small change to a large image so VIPS has a +an operation is only making a small change to a large image so libvips has a set of mechanisms to copy image areas by just adjusting pointers. Most of the time no actual copying is necessary and you can perform operations on large images at low cost. -**SIMD optimisations** +## SIMD optimisations -VIPS uses -Highway, a -C++ library, to optimise various operations with SIMD/vector -instructions. These optimised code paths are flexible and can adapt to -different instruction sets, including those with 'scalable' vectors -(size unknown at compile time). At runtime, dynamic dispatch selects -the best available implementation based on the processor's capabilities, -ensuring optimal performance. +libvips uses [Highway](https://github.com/google/highway), a C++ library, +to optimise various operations with SIMD/vector instructions. These optimised +code paths are flexible and can adapt to different instruction sets, including +those with 'scalable' vectors (size unknown at compile time). At runtime, +dynamic dispatch selects the best available implementation based on the +processor's capabilities, ensuring optimal performance. SIMD typically speeds operations up by a factor of three or four. -**Joining operations together** +## Joining operations together The region create / prepare / prepare / free calls you use to get pixels from an image are an exact parallel to the start / generate / generate / @@ -130,62 +122,62 @@ stop calls that images use to create pixels. In fact, they are the same: a region on a partial image holds the state created by that image for the generate function that will fill the region with pixels. -![](Combine.png) +![Combine](Combine.png) -VIPS joins image processing operations together by linking the output of one +libvips joins image processing operations together by linking the output of one operation (the start / generate / stop sequence) to the input of the next (the region it uses to get pixels for processing). This link is a single function call, and very fast. Additionally, because of the the split between allocation and processing, once a pipeline of operations has been set up, -VIPS is able to run without allocating and freeing memory. +libvips is able to run without allocating and freeing memory. -This graph (generated by `vipsprofile`, the vips profiler) shows memory use -over time for a vips pipeline running on a large image. The bottom trace +This graph (generated by `vipsprofile`, the libvips profiler) shows memory use +over time for a libvips pipeline running on a large image. The bottom trace shows total memory, the upper traces show threads calculating useful results (green), threads blocked on synchronisation (red) and memory allocations (white ticks). -![](Memtrace.png) +![Memtrace](Memtrace.png) Because the intermediate image is just a small region in memory, a pipeline of operations running together needs very little RAM. In fact, intermediates are small enough that they can fit in L2 cache on most machines, so an entire pipeline can run without touching main memory. And finally, because each thread runs a very cheap copy of just the writeable state of the -entire pipeline, threads can run with few locks. VIPS needs just four lock +entire pipeline, threads can run with few locks. libvips needs just four lock operations per output tile, regardless of the pipeline length or complexity. -**Data sources** +## Data sources -VIPS has data sources which can supply pixels for processing from a variety -of sources. VIPS can stream images from files in VIPS native format, from +libvips has data sources which can supply pixels for processing from a variety +of sources. libvips can stream images from files in libvips native format, from tiled TIFF files, from binary PPM/PGM/PBM/PFM, from Radiance (HDR) files, -from FITS images and from tiled OpenEXR images. VIPS will automatically +from FITS images and from tiled OpenEXR images. libvips will automatically unpack other formats to temporary disc files for you but this can obviously generate a lot of disc traffic. It also has a special sequential mode for streaming operations on non-random-access formats. Another -section in these docs explains how -libvips opens a file. One of the sources uses the ImageMagick (or optionally GraphicsMagick library, so VIPS -can read any image format that these libraries can read. +section in these docs explains [how libvips opens files]( +how-it-opens-files.html). One of the sources uses the [ImageMagick]( +https://imagemagick.org/) (or optionally [GraphicsMagick]( +http://graphicsmagick.org)) library, so libvips can read any image format +that these libraries can read. -VIPS images are held on disc as a 64-byte header containing basic image +libvips images are held on disc as a 64-byte header containing basic image information like width, height, bands and format, then the image data as a single large block of pixels, left-to-right and top-to-bottom, then an XML extension block holding all the image metadata, such as ICC profiles and EXIF blocks. -When reading from a large VIPS image (or any other format with the same -structure on disc, such as binary PPM), VIPS keeps a set of small rolling +When reading from a large libvips image (or any other format with the same +structure on disc, such as binary PPM), libvips keeps a set of small rolling windows into the file, some small number of scanlines in size. As pixels -are demanded by different threads VIPS will move these windows up and down -the file. As a result, VIPS can process images much larger than RAM, even +are demanded by different threads libvips will move these windows up and down +the file. As a result, libvips can process images much larger than RAM, even on 32-bit machines. -**Data sinks** +## Data sinks -In a demand-driven system, something has to do the demanding. VIPS has a +In a demand-driven system, something has to do the demanding. libvips has a variety of data sinks that you can use to pull image data though a pipeline in various situations. There are sinks that will build a complete image in memory, sinks to draw to a display, sinks to loop over an image (useful @@ -193,25 +185,25 @@ for statistical operations, for example) and sinks to stream an image to disc. The disc sink looks something like this: -![](Sink.png) +![Sink](Sink.png) The sink keeps two buffers\*, each as wide as the image. It starts threads as rapidly as it can up to the concurrency limit, filling each buffer with tiles\*\* of calculated pixels, each thread calculating one tile at once. A separate background thread watches each buffer and, as soon as the last tile in a buffer finishes, writes that complete set of scanlines to disc using -whatever image write library is appropriate. VIPS can write with libjpeg, +whatever image write library is appropriate. libvips can write with libjpeg, libtiff, libpng and others. It then wipes the buffer and repositions it further down the image, ready for the next set of tiles to stream in. These features in combination mean that, once a pipeline of image processing -operations has been built, VIPS can run almost lock-free. This is very +operations has been built, libvips can run almost lock-free. This is very important for SMP scaling: you don't want the synchronization overhead to scale with either the number of threads or the complexity of the pipeline -of operations being performed. As a result, VIPS scales almost linearly +of operations being performed. As a result, libvips scales almost linearly with increasing numbers of threads: -![](Vips-smp.png) +![SMP scaling](Vips-smp.png) Number of CPUs is on the horizontal axis, speedup is on the vertical axis. Taken from the [[Benchmarks]] page. @@ -219,48 +211,48 @@ axis. Taken from the [[Benchmarks]] page. (\* there can actually be more than one, it allocate enough buffers to ensure that there are at least two tiles for every thread) -(\*\* tiles can be any shape and size, VIPS has a tile hint system that +(\*\* tiles can be any shape and size, libvips has a tile hint system that operations use to tell sinks what tile geometry they prefer) -**Operation cache** +## Operation cache -Because VIPS operations are free of side-effects\*, you can cache them. Every -time you call an operation, VIPS searches the cache for a previous call to +Because libvips operations are free of side-effects\*, you can cache them. Every +time you call an operation, libvips searches the cache for a previous call to the same operation with the same arguments. If it finds a match, you get the previous result again. This can give a huge speedup. -By default, VIPS caches the last 100 operation calls. You can also control +By default, libvips caches the last 100 operation calls. You can also control the cache size by memory use or by files opened. -(\* Some vips operations DO have side effects, for example, -`vips_draw_circle()` will draw a circle on an image. These operations emit an +(\* Some libvips operations DO have side effects, for example, +[method@Image.draw_circle] will draw a circle on an image. These operations emit an "invalidate" signal on the image they are called on and this signal makes all downstream operations and caches drop their contents.) -**Operation database and APIs** +## Operation database and APIs -VIPS has around 300 image processing operations written in this style. Each +libvips has around 300 image processing operations written in this style. Each operation is a GObject class. You can use the standard GObject calls to walk the class hierarchy and discover operations, and libvips adds a small amount of extra introspection metadata to handle things like optional arguments. -The C API is a set of simple wrappers -which create class instances for you. The C++ -API is a little fancier and adds things like automatic object lifetime -management. The command-line interface -uses introspection to run any vips operation in the class hierarchy. +The [C API](using-from-c.md) is a set of simple wrappers +which create class instances for you. The [C++ API](using-from-cplusplus.md) +is a little fancier and adds things like automatic object lifetime +management. The [command-line interface](using-the-cli.md) +uses introspection to run any libvips operation in the class hierarchy. -There are bindings for many -other languages on many platforms. Most of these bindings use the -introspection system to generate the binding at run-time. +There are bindings for [many other languages](https://www.libvips.org/) on +many platforms. Most of these bindings use the introspection system to +generate the binding at run-time. -**Snip** +## Snip -The VIPS GUI, nip2, has its own scripting language called Snip. Snip is a +The libvips GUI, nip2, has its own scripting language called Snip. Snip is a lazy, higher-order, purely functional, object oriented language. Almost all of nip2's menus are implemented in it, and nip2 workspaces are Snip programs. -VIPS operations listed in the operation database appear as Snip functions. For +libvips operations listed in the operation database appear as Snip functions. For example, `abs` can be used from Snip as: ``` @@ -268,9 +260,9 @@ example, `abs` can be used from Snip as: a = vips_call "abs" [b] []; ``` -However, `abs` won't work on anything except the primitive vips image type. It -can't be used on any class, or list or number. Definitions in `_stdenv.dev` -wrap each VIPS operation as a higher level Snip operation. For example: +However, `abs` won't work on anything except the primitive `.v` image type. +It can't be used on any class, or list or number. Definitions in `_stdenv.dev` +wrap each libvips operation as a higher level Snip operation. For example: ``` abs x @@ -312,16 +304,15 @@ You can write Snip classes which present functions to the user as menu items. For example, `Math.def` has this: ``` -Math_arithmetic_item = class +Math_arithmetic_item = class Menupullright "_Arithmetic" "basic arithmetic for objects" { Absolute_value_item = class Menuaction "A_bsolute Value" "absolute value of x" { action x = map_unary abs x; } -} +} ``` Now the user can select an object and click `Math / Abs` to find the absolute value of that object. - diff --git a/doc/images/x.jpg b/doc/images/x.jpg deleted file mode 100644 index 4269c8216739a2c2f0413ddbb5fce91054f9c8e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6861 zcmeH~XH-*Nm&b1i5UPj}gwTu9O8}87NKX)ugx-`cAV@C(M3JIY>4@}RgY=GoR4F1= z0w@?D0)hepN|A}r^S#n=cKb$WE7m=C>O#lP} z01)v3&R1xQGy^&jElW@9&)-5%a+Rrin{p&0x^qQF7wypEXkvA^utOC8GZKnn5Ig z=fjBaN&cb3X#VU40NTX)hyS1c{J%Q41waiTCnX~%BPAy%BZol9DX1<|QBhJ-FF`;{Yi=*(GlHO>zbU8wiglqvYende@Qt%f{yJ-u{n+!=sHUYJIvm zO^1F}mT~*DaAGuu3MgkZQJmo36f$C*feNtANf*F31sCq!)aNODPLW|~Z#XI#jyCMm zipE64^~`6`7neIw&{8VOYF>6q-nR0n!Lu*eb=Qm#~4txwV8Kp%n> z-g?9^>MUw45iOHO_{Qe>asW@UOQ#klo$dn4`x;YQ9es-U>?+M0oRwk3xAS(z5A^KtlL)dxPyNBEqq zSWNW0nP7O316?llo51^lmsIBQbL=kQ{3UbCMT_cDuQwcyP4nJEilDl1Ez1%_qs2HU}y(xLJ4L;!nsM~ z11LSQ{$K-iN(r>mKs|Ph7lsmyGb|wet>37*YugYTP{xN$z3nG8FWBxfQYsyGLs&!d zKHAeDx>3l;tEGYf+8R@&(w?p2F-9e7+m^Vx_Ga2{W^NZ3#TwZ^^pMJ;!T+eBg!+7h z&046Ku1@6{Ph+hLuU{%z3zGoZLZ*`RZ4%7;hkd0>A%bSGH2JT#$AQ-ZC#B=%t~m5? zLrqtG2qh5jFRtVGDMj(}pT*ZKq&&EjLm6(y(u7R-+a;z#SWW{g9|}x2%+7u8biU&@ z&R%#k#Y9d-k8WuZ659Paf%TKwho6p&Q@mk*MJZjctoY^O+FcuRVo{p0R{lj@BKi=pePQo6vVf`?!ql`L*VD&vgqa`Xos; z;R`G2wFG8t<5%1)wV~660g4aLy~7Oc9|mIO$8qshKDXZ8+q@dzKxHVFnp9?E8>3~Q z=o^w$;8STt(ofJ6>Ud^OlVvE*?o|Xv{k3Xl1V~k}Ai?H72YpF%UeDBTqq!h?`q!Rk#vz3Ii+UvA& zvPn1B85#>zZ}tE?kP@L^6+vh+O@=MXJZMkukYrPBOw0O;GzE^_6>x{xv^@3}<{%N<|McxlD2j_9* z`C&y+4dNe+pey;*{7`DGv3rbVnezLo=(K(?yXO1ZCt3#5zQp5gtdEW>tmI{+&+NZ7 z*$;`qy;wUjIz-yUm*0{@ie7G%8YUFq3-l=vdN?76OnkGA773`-VG{gkWg_eKT*#<$ zL^#AkBYJjS0}ZYRUqx1A-Nm;KOOG`w6$VNbMW_LR==V{cdf9pi%d!(Jfvi%qjXYnp zD4u)I?nK?uVKB>V8j4;7Bq7$i4o%ex&v*ldgI7GK5<>gtihdp;rcQMkXM1FNfs1gq ze3FjDZC_Cmofs?Co}D6r;BtR_0CNw=S?5{89ph9}<2H+eR4q=myeVr72T>N|)JW6Z zRpEmAFq}mF=$`b`{BGKa@z8-5cK*KI#e^#&nM>n<$^GQTN1o&GjhvvFt!zj2Ms@mI zw=a=Cn-9_dX^hQEu9uF}xZ>T`)?7b*H1Lhj-Lo~y5)%|X`FzpBel&5I*;jRf8|-@5 zowt@Y%yV!Q;{+YOx35v*yao+h(qO@joZi!v`u1tjL@j^I!*bqY!*K#z%ODXrn!CHt z0uk_1lDGe^1_}panbHa3FBDs*BVOMt|;NS?C1y~nFJh` zu_Wbl1l-gB^rQ4CU9lUrzDq#EVU5-%zBS^|dqZnpzxY9nvWrLkVex@y*3ZTpDZ4Hq z!og-IsIz2T`b>8()5qz7X5PjJjZF|_q)sr29&o_Vn0<}RkDMijF--mw%iuoh!n47G_#l&9MF(LV$NnCR)q}6qo;03Uc8XRXZe)aq+k1Uj zJ$RSLTqE$a_H+AishcG8T{9a`!Ha#b`I!fnrH+q{U&s0`^v{K7h8|15p<=(h%1r9s zbJ9n%zmR}jbKfqAd}}OZZNlr#kn}Yu`BUbh*Kv?hu64wCgPa^Ud(aEx<}`V1PH^Ae zgOsqhtdPeebQ81LaX%xu4`7NWXh2~=Rm(&>)hA6FdO`2O;RLj}0mzAXY zgF;Q(+ML*2r4N*36e>H#j#;X%a2WfG%co>CXJMBERbx{KH9vH z<&aKVuh-Q1bu$N7C%@&w>l`okVJ%{pe?M&8#`#B9iQNDAk=owy?oApHezHZ___kkD zsa;11i{;3*v$2`crz5PRy%M4Ax#xft$Ia^gda68uZZJtgU64tladP=}1$Q-nNBT!o zx5%60N*kqdLB^rR^kq#Sr&rvzO~_<@Yl0H#z4Dq4iZTQv_-Ao_zk%F4$W2AJBPSx9=xHS(PcXW7R45Z?#;T_412X1N`{%De#3=g9upGGkcSM8=ScIkfnR zm_zxV#6LP@!|a;`U;AB$Kl`@n`k?pD?(X%8bKrW7m$dUFLRFC7b;lb~eCOroq@~OD zEWRSZ(i|I`A!fTLnv?sPRh2$CNx?*e|1{i@SPtPFxCtF{{S>17v3hxDk`*be_Oj&> z68mdoTp5NH9ejS}N3f?kVpji{U^sVt4n+8sOM&lb=Y0Oq<9YwLWvw?Ef#D0O2 zl7fnck(P#M#>U3QC&tgkBf`tZCU9L)L;@}?EzQXC?+K> z`B%3=Nl8gVO~Xt}%Ph&w#x40jw!gcLN5G^1?>7GGqW;f!8|%!|x?_r&HZ@mgWm;K^ zO6gUgv?R8VQ6OECVv<)$0=H#L%Ss;Wn-BLvKsrq+sL3@@I2w+k*X^ewX&FU*PK$0N z(O}$ec!b{krBb0G#WwX$I^4wc=};b3Afs(@>`m0;%)1;j8s;iGc{I8&HJ|lbWzu)-QW503No>taQZTq|oSdE?y+}^?est~i{BqSEL`k+tCcY}YQ^j$Z6aG$9yc#sTX*F71ph@SW=~S42cmA7v0GGvLlA0wbcnMqSqoDd|vCz z1pwV(zO2K8a*LPf1a#c4`iPA;tI~qG#2S|A;#lM|jc0rm|Af&yT4qI!0$rMOpet#q z<4ds-&LX>LIpjuaA)f#HdbP)K@SOU`?sh)a&x!wUK%HZ#To4UStbgq!G{Mr5itom#_13#-ZLfAXZ5b#fBib!XOuY zI{zAL6xpM#1Op=gD{g6^*{i`5>U_~Nz6D$o^qq3U?4^*7KtbK~b~gUrx?b#8 z8Dv)!KO|>)`W*|+JgQVNOhUtJd^oyba?Pq?vZN~Ib0#V&F*~{stzAhbbxSb1J)hCg zu%aQlWBP5QflZ z_ZC(aN3Ab9!R6h8vmR#4p1LBvW=A)|8RFj87jMY>#LtOd(!m(oWCllVjYCL-PS`x8 zEM=O@5MpIq4H6(7IuetlxPH3mKT^mV+mQ?$)V_olrjq`s!K)4i$2JJgl7vok9(tVQJs zNOqOe;CRMo7dlkeQtzs9;R};w=vu}h2R^g9G$cu#1R-{7+`|BP<2m8aB3pD=4~yv> zt`;ZAoC9BuDEPx!@`gl`I6tEl>}fdWp_TS^BPIPlyD12(UU91yr5jHagN&`lY8Jk^ z#Uf`*NX+Olby;k5)-SM+*}HnkTFwE(7Y-bRYHuSy4c(w(uhx>(N>=9x*X&!}RmK^{ zRnU@@3N$oYD6-hFoJl^_u6Uf1M!kH-`EAaOfce-^fkn)(s$f|g2fEj)kaFnFDIV< zyf#C&!!Es)#JsK(6e>TjmCbxrq|9w3xkW-5rF9Nizv`O4v;^b3pU_43+E%!sJrd_1 zGZd}O1Lc!8|MGE1DE7?m|VI(+CfU*Kz#@REfSX>ZMTr$NQd(J1lz7sVC#8+%dW+BS&$XlHnJ9P$#5;8-&=a%6MO&*`v@rxFbF&;H4nqiSFA-dhea1JrmXSw33J}NPq#Nbi4&pp4|8NO<2HIvsGaS?{H=RIOAj(%ulYZ*+~G&npT^QTv^ zhqwrEbPzsvywsQgwq%`RoUXC(z0qDpHxV2FKm9T7Ld53<7dLxpk3=n&e@9B(+1z*?08w6 zo-=23`C~839svonx%IfDcRFz0lSTR7!MEU863Cr9)z*7TWPvR&4W085DSj~37uzPM z(fYi&){tbr_Yy&djwIfXO?Ipm?wOk`i+aO8Jrk`i2r#yf!F(Ur=KsXr)i`yBo_S=x z$6D3eVS~RZ(hX}+_u}MDLTIt!%f2?FBCigS8Xl)3JIFauW9?Mtn%pMYSIMVGeHlfL zIQSOt5`m2uzkX{@gC&a3Db}}Nb!5%Lyx#AtzOr3Y%Wg9cfQt`R*O}SNQG_mi!?lk2 z8#Q%V7ULc_*vDe^S>(3oik)QA=2TgOq$Ml%sGCR#tp^+GnKUw!8tyB%qTAPmv*`3N zu&?=H`G|5YRf}X%^ZWMt0+&F{TgmYdv?*-lf!~`@4){jD`;xi{o|XBAWB~KH>x))T z-c;&=K&5@FhNG6^g4zV3)n(96v|Vfz%U0$@CX}M8u=*OFM8M2rEcO+)QHkcOPY!J6 zC1Uo{vAr3WXp`Y!4Rej}W8MIR6~2K@mcXH&RogD#Fvva1RT)XTnrmOI8Fmrh4~lME zNjEcz - - - -]> - - - Codestin Search App - - For libvips &version;. The latest version of this documentation - can be found on the libvips - website. - - - - - Codestin Search App - - libvips is a free image processing system. It is good with large - images (images larger than the amount of RAM you have available), with - many CPUs (speed scales linearly to at least 32 threads), for working - with colour, for scientific analysis and for general research - and development. As well as JPEG, TIFF and PNG images, it also - supports scientific formats like FITS, Matlab, Analyze, PFM, - Radiance and OpenSlide. It works on many UNIX-like platforms, - as well as Windows and OS X. libvips is released under the GNU Library - General Public License (GNU LGPL). - - - - - - - - - - - - - - - - - - - - - - Codestin Search App - - - - - - - - - - - - - - - - - - - - Codestin Search App - - - - - - - - - - - - - - - - - Codestin Search App - - - - - - - - Codestin Search App - - - - - Codestin Search App - - - - - - diff --git a/doc/libvips-from-C++.md b/doc/libvips-from-C++.md deleted file mode 100644 index b1f5063042..0000000000 --- a/doc/libvips-from-C++.md +++ /dev/null @@ -1,19 +0,0 @@ - - libvips from C++ - 3 - libvips - - - - C++ - Using libvips from C++ - - -libvips comes with a convenient C++ API. It is a very thin wrapper over the -C API and adds automatic reference counting, exceptions, operator -overloads, and automatic constant expansion. - -See the - -C++ API documentation -for more details. diff --git a/doc/libvips-from-C++.xml b/doc/libvips-from-C++.xml deleted file mode 100644 index a90293cea2..0000000000 --- a/doc/libvips-from-C++.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - libvips from C++ 3 libvips - - - C++ Using libvips from C++ - - - libvips comes with a convenient C++ API. It is a very thin wrapper over the C API and adds automatic reference counting, exceptions, operator overloads, and automatic constant expansion. - - - See the C++ API documentation for more details. - - - - diff --git a/doc/libvips-header.md b/doc/libvips-header.md new file mode 100644 index 0000000000..f0be088dcb --- /dev/null +++ b/doc/libvips-header.md @@ -0,0 +1,122 @@ +Title: Image headers + +# Image headers + +libvips supports getting and setting image header data (including metadata) +in a uniform way. + +Use [method@Image.image_get_typeof] to test for the existence and +[alias@GObject.Type] of a header field. + +You can attach arbitrary metadata to images. Metadata is copied as images +are processed, so all images which used this image as input, directly or +indirectly, will have this same bit of metadata attached to them. Copying +is implemented with reference-counted pointers, so it is efficient, even for +large items of data. This does however mean that metadata items need to be +immutable. Metadata is handy for things like ICC profiles or EXIF data. + +Various convenience functions (e.g. [method@Image.set_int]) let you easily +attach simple types like numbers, strings and memory blocks to images. +Use [method@Image.map] to loop over an image's fields, including all metadata. + +Items of metadata are identified by strings. Some strings are reserved, for +example the ICC profile for an image is known by convention as +"icc-profile-data" (i.e. the [const@META_ICC_NAME] constant). + +If you save an image in `.v` format, all metadata (with a restriction, see +below) is automatically saved for you in a block of XML at the end of the +file. When you load a `.v` image, the metadata is restored. You can use the +`vipsedit` command-line tool to extract or replace this block of XML. + +`.v` metadata is based on [struct@GObject.Value]. See the docs for that +system if you want to do fancy stuff such as defining a new metadata type. +libvips defines a new [struct@GObject.Value] called [struct@SaveString], a +variety of string, see [func@value_set_save_string]. If your +[struct@GObject.Value] can be transformed to [struct@SaveString], it will +be saved and loaded to and from `.v` files for you. + +libvips provides a couple of base classes which implement reference-counted +areas of memory. If you base your metadata on one of these types, it can be +copied between images efficiently. + +## Header functions + +* [func@format_sizeof] +* [func@format_sizeof_unsafe] +* [func@Interpretation.max_alpha] +* [method@Image.get_width] +* [method@Image.get_height] +* [method@Image.get_bands] +* [method@Image.get_format] +* [func@Image.get_format_max] +* [method@Image.guess_format] +* [method@Image.get_coding] +* [method@Image.get_interpretation] +* [method@Image.guess_interpretation] +* [method@Image.get_xres] +* [method@Image.get_yres] +* [method@Image.get_xoffset] +* [method@Image.get_yoffset] +* [method@Image.get_filename] +* [method@Image.get_mode] +* [method@Image.get_scale] +* [method@Image.get_offset] +* [method@Image.get_page_height] +* [method@Image.get_n_pages] +* [method@Image.get_n_subifds] +* [method@Image.get_orientation] +* [method@Image.get_orientation_swap] +* [method@Image.get_concurrency] +* [method@Image.get_data] +* [method@Image.init_fields] +* [method@Image.image_set] +* [method@Image.image_get] +* [method@Image.get_as_string] +* [method@Image.image_get_typeof] +* [method@Image.remove] +* [method@Image.map] +* [method@Image.get_fields] +* [method@Image.set_area] +* [method@Image.get_area] +* [method@Image.set_blob] +* [method@Image.set_blob_copy] +* [method@Image.image_get_blob] +* [method@Image.image_get_int] +* [method@Image.set_int] +* [method@Image.image_get_double] +* [method@Image.set_double] +* [method@Image.get_string] +* [method@Image.set_string] +* [method@Image.print_field] +* [method@Image.image_get_image] +* [method@Image.set_image] +* [method@Image.set_array_int] +* [method@Image.get_array_int] +* [method@Image.get_array_double] +* [method@Image.set_array_double] +* [method@Image.history_printf] +* [method@Image.history_args] +* [method@Image.get_history] + +## Header callbacks + +* [callback@ImageMapFn] + +## Header constants + +* [const@META_EXIF_NAME] +* [const@META_XMP_NAME] +* [const@META_IPTC_NAME] +* [const@META_PHOTOSHOP_NAME] +* [const@META_ICC_NAME] +* [const@META_IMAGEDESCRIPTION] +* [const@META_RESOLUTION_UNIT] +* [const@META_BITS_PER_SAMPLE] +* [const@META_PALETTE] +* [const@META_LOADER] +* [const@META_SEQUENTIAL] +* [const@META_ORIENTATION] +* [const@META_PAGE_HEIGHT] +* [const@META_N_PAGES] +* [const@META_N_SUBIFDS] +* [const@META_CONCURRENCY] diff --git a/doc/Making-image-pyramids.md b/doc/making-image-pyramids.md similarity index 79% rename from doc/Making-image-pyramids.md rename to doc/making-image-pyramids.md index f6f99952cd..9bf627921b 100644 --- a/doc/Making-image-pyramids.md +++ b/doc/making-image-pyramids.md @@ -1,27 +1,20 @@ - - Image pyramids - 3 - libvips - - - - Pyramids - How to use libvips to make image pyramids - - -libvips includes `vips_dzsave()`, an operation -that can build image pyramids compatible with DeepZoom, Zoomify -and Google Maps -image viewers. It's fast and can generate pyramids for large images using -only a small amount of memory. - -The TIFF writer, `vips_tiffsave()` can also build tiled pyramidal TIFF images, -but that's very simple to use. This page concentrates on the DeepZoom builder. +Title: How to use libvips to make image pyramids + +# How to use libvips to make image pyramids + +libvips includes [method@Image.dzsave], an operation that can build image +pyramids compatible with [DeepZoom](http://en.wikipedia.org/wiki/Deep_Zoom), +Zoomify and [Google Maps](https://developers.google.com/maps) image viewers. +It's fast and can generate pyramids for large images using only a small amount +of memory. + +The TIFF writer, [method@Image.tiffsave] can also build tiled pyramidal TIFF +images, but that's very simple to use. This page concentrates on the DeepZoom +builder. Run dzsave with no arguments to see a summary: -``` +```bash $ vips dzsave save image to deepzoom file usage: @@ -72,10 +65,10 @@ optional arguments: operation flags: sequential nocache ``` -You can also call `vips_dzsave()` from any language with a libvips binding, or -by using `.dz` or `.szi` as an output file suffix. +You can also call [method@Image.dzsave] from any language with a libvips +binding, or by using `.dz` or `.szi` as an output file suffix. -# Writing DeepZoom pyramids +## Writing DeepZoom pyramids The `--layout` option sets the basic mode of operation. With no `--layout`, dzsave writes DeepZoom pyramids. For example: @@ -96,10 +89,10 @@ $ vips dzsave huge.tif mydz --suffix .jpg[Q=90] ``` will write JPEG tiles with the quality factor set to 90. You can set any -format write options you like, see the API docs for `vips_jpegsave()` +format write options you like, see the API docs for [method@Image.jpegsave] for details. -# Writing Zoomify pyramids +## Writing Zoomify pyramids Use `--layout zoomify` to put dzsave into zoomify mode. For example: @@ -113,11 +106,10 @@ directories called `TileGroupn`, each containing 256 image tiles. As with DeepZoom, you can use `--suffix` to set jpeg quality. -# Writing Google Maps pyramids +## Writing Google Maps pyramids Use `--layout google` to write Google maps-style pyramids. These are -compatible with Leaflet. For -example: +compatible with [Leaflet](http://leafletjs.com). For example: ```bash $ vips dzsave wtc.tif gmapdir --layout google @@ -144,7 +136,7 @@ For example: $ vips dzsave wtc.tif gmapdir --layout google --background 0 --centre ``` -# Other options +## Other options You can use `--tile-size` and `--overlap` to control how large the tiles are and how they overlap (obviously). They default to the correct values @@ -172,11 +164,11 @@ $ vips dzsave wtc.tif mypyr.zip to write a zipfile containing the tiles. You can use `.szi` as a suffix to enable zip output as well. -# Preprocessing images +## Preprocessing images You can use `.dz` as a filename suffix, meaning send the image to -`vips_dzsave()`. This means you can write the output of any vips operation to a -pyramid. For example: +[method@Image.dzsave]. This means you can write the output of any libvips +operation to a pyramid. For example: ```bash $ vips extract_area huge.svs mypy.dz[layout=google] 100 100 10000 10000 @@ -197,10 +189,8 @@ $ vips dzsave CMU-1.mrxs[level=1] x Will pull out level 1 (the half-resolution level of an MRXS slide) and make a pyramid from that. -# Troubleshooting +## Troubleshooting -If you are building vips from source you do need to check the summary at +If you are building libvips from source you do need to check the summary at the end of configure carefully. You must have the `libarchive-dev` package -for `vips_dzsave()` to work. - - +for [method@Image.dzsave] to work. diff --git a/doc/meson.build b/doc/meson.build index b1177743f4..e0f1aad115 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -1,160 +1,73 @@ -private_libvips_headers = [ - 'arithmetic/binary.h', - 'arithmetic/hough.h', - 'arithmetic/nary.h', - 'arithmetic/parithmetic.h', - 'arithmetic/statistic.h', - 'arithmetic/unaryconst.h', - 'arithmetic/unary.h', - 'colour/pcolour.h', - 'colour/profiles.h', - 'conversion/bandary.h', - 'conversion/pconversion.h', - 'convolution/correlation.h', - 'convolution/pconvolution.h', - 'create/pcreate.h', - 'create/pmask.h', - 'create/point.h', - 'draw/drawink.h', - 'draw/pdraw.h', - 'foreign/dbh.h', - 'foreign/jpeg.h', - 'foreign/libnsgif/lzw.h', - 'foreign/libnsgif/nsgif.h', - 'foreign/libnsgif/test/cli.h', - 'foreign/magick.h', - 'foreign/pforeign.h', - 'foreign/quantise.h', - 'foreign/tiff.h', - 'freqfilt/pfreqfilt.h', - 'histogram/hist_unary.h', - 'histogram/phistogram.h', - 'include/vips/almostdeprecated.h', - 'include/vips/deprecated.h', - 'include/vips/dispatch.h', - 'include/vips/format.h', - 'include/vips/internal.h', - 'include/vips/intl.h', - 'include/vips/mask.h', - 'include/vips/private.h', - 'include/vips/thread.h', - 'include/vips/video.h', - 'include/vips/vips7compat.h', - 'iofuncs/sink.h', - 'morphology/pmorphology.h', - 'mosaicing/global_balance.h', - 'mosaicing/pmosaicing.h', - 'resample/presample.h', - 'resample/templates.h', -] +gidocgen = find_program('gi-docgen') -private_headers = [] -foreach private_libvips_header : private_libvips_headers - private_headers += [project_source_root / 'libvips' / private_libvips_header] -endforeach - -markdown_content_files = files( - 'binding.md', - 'Cite.md', - 'Developer-checklist.md', - 'Examples.md', - 'How-it-opens-files.md', - 'How-it-works.md', - 'libvips-from-C++.md', - 'Making-image-pyramids.md', - 'Using-vipsthumbnail.md', - 'multipage-and-animated-images.md', -) - -pandoc = find_program('pandoc', required: false) - -if pandoc.found() - # we have some files in markdown ... convert to docbook for gtk-doc - gen = generator(pandoc, - output: '@BASENAME@.xml', - arguments: [ - '@INPUT@', - '--template=@0@'.format(meson.current_source_dir() / 'pandoc-docbook-template.docbook'), - '--wrap=none', - '-V', 'title=@BASENAME@', - '-f', 'markdown+smart', - '-t', 'docbook', - '-o', '@OUTPUT@', - ] - ) - - markdown_content_files_generated = gen.process(markdown_content_files) - - # pandoc makes section headers, we want refsect3 for gtk-doc - markdown_content_files_docbook = custom_target('gen-docs', - output: 'generated', - input: markdown_content_files_generated, - command: [ 'sed', '-i', '-e', 's| - Multipage and animated images - 3 - libvips - +Title: Processing multipage and animated images - - Multipage and animated images - Processing multipage and animated images - +# Processing multipage and animated images libvips represents animated and multipage images as tall, thin strips of frames, like a strip of movie film (or a roll of toilet paper). Special image @@ -17,11 +10,11 @@ frame delay or loop settings. At least the JXL, GIF and WebP loaders and savers support animation, and the TIFF, PDF, HEIC, AVIF and VIPS loaders and savers support multipage. -# Reading multipage images +## Reading multipage images For example, at the command-line, try: -``` +```bash $ vipsheader -a silver-gear-cogs-animation-5.gif[n=-1] silver-gear-cogs-animation-5.gif: 281x2560 uchar, 4 bands, srgb, gifload width: 281 @@ -67,7 +60,7 @@ Points to note: You'll see a similar set of metadata for a multipage image, such as a PDF: -``` +```bash $ vipsheader -a nipguide.pdf[n=-1] nipguide.pdf: 595x48836 uchar, 4 bands, srgb, pdfload width: 595 @@ -97,12 +90,12 @@ This all assumes that every page (or frame) has the same dimensions. If they don't (this can commonly happen with PDF and TIFF), you have to read pages one by one. -# Writing multipage images +## Writing multipage images As long as these various pieces of metadata are set, you can write animated and multipage images in the obvious way. For example: -``` +```bash $ vips copy nipguide.pdf[n=-1] x.gif ``` @@ -113,14 +106,14 @@ handled like this. More usefully, you could convert a GIF to WebP with: -``` +```bash $ vips copy silver-gear-cogs-animation-5.gif[n=-1] silver.webp ``` To write an animated or multipage image programmatically, you need to construct the tall, thin image and set the metadata. For example: -``` +```bash $ vips arrayjoin "k2.jpg k4a.png" x.tif[page-height=2048] --across=1 ``` @@ -153,7 +146,7 @@ animation.write_to_file(sys.argv[1]) It's a little more fiddly in C: -```C +```c /* compile with * * gcc -g -Wall assemble-animated.c `pkg-config vips --cflags --libs` diff --git a/doc/multipage-and-animated-images.xml b/doc/multipage-and-animated-images.xml deleted file mode 100644 index 7d5edcc51e..0000000000 --- a/doc/multipage-and-animated-images.xml +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - - Multipage and animated images 3 libvips - - - Multipage and animated images Processing multipage and animated images - - - libvips represents animated and multipage images as tall, thin strips of frames, like a strip of movie film (or a roll of toilet paper). Special image metadata items are used to hold the page height, the number of frames, and any frame delay or loop settings. - - - At least the JXL, GIF and WebP loaders and savers support animation, and the TIFF, PDF, HEIC, AVIF and VIPS loaders and savers support multipage. - - - Codestin Search App - - For example, at the command-line, try: - - -$ vipsheader -a silver-gear-cogs-animation-5.gif[n=-1] -silver-gear-cogs-animation-5.gif: 281x2560 uchar, 4 bands, srgb, gifload -width: 281 -height: 2560 -bands: 4 -format: uchar -coding: none -interpretation: srgb -xoffset: 0 -yoffset: 0 -xres: 1 -yres: 1 -filename: silver-gear-cogs-animation-5.gif -vips-loader: gifload -page-height: 320 -n-pages: 8 -loop: 0 -delay: 100 100 100 100 100 100 100 100 -background: 0 0 0 -gif-palette: -12500671 -11447983 -723724 -3289651 -11974327 -11711155 -5395027 -13027015 -9276814 -9408400 -16777216 -14079703 -197380 -12237499 -5723992 -526345 -15592942 -12763843 -5921371 -13750738 -13553359 -10592674 -6908266 -7829368 -7960954 -8158333 -809254 -bits-per-sample: 7 -palette: 1 - - - Points to note: - - - - - By default, libvips will just read the first page from an animated or multipage image. You pass [n=-1] to the loader to get all pages (or frames) in the animation. You can pick out a single page or range of pages with perhaps [page=4] and [page=2,n=2]. - - - - - page-height is the vertical size of each frame within the overall image (2560 pixels high in this case). - - - - - n-pages is the number of pages (or frames) in this animation. Obviously n-pages * frame-height == height, or in this case 320 * 8 == 2560. - - - - - loop is the number of times the animation should loop before stopping. Zero means never stop looping. - - - - - delay is an optional array with a time in milliseconds which each frame should display for. - - - - - You’ll see a similar set of metadata for a multipage image, such as a PDF: - - -$ vipsheader -a nipguide.pdf[n=-1] -nipguide.pdf: 595x48836 uchar, 4 bands, srgb, pdfload -width: 595 -height: 48836 -bands: 4 -format: uchar -coding: none -interpretation: srgb -xoffset: 0 -yoffset: 0 -xres: 2.83465 -yres: 2.83465 -filename: nipguide.pdf -vips-loader: pdfload -page-height: 842 -pdf-n_pages: 58 -n-pages: 58 -pdf-creator: TeX -pdf-producer: pdfTeX-1.40.16 - - - Now there’s no loop or delay since this is not animated, but n-pages and page-height are set. In just the same way, you can load all pages, a single page or a range of pages. - - - This all assumes that every page (or frame) has the same dimensions. If they don’t (this can commonly happen with PDF and TIFF), you have to read pages one by one. - - - - Codestin Search App - - As long as these various pieces of metadata are set, you can write animated and multipage images in the obvious way. For example: - - -$ vips copy nipguide.pdf[n=-1] x.gif - - - This will take the 58-page PDF and render a 58-frame animation. This only works because this specific PDF has pages which are all the same size – PDFs with (for example) a mix of portrait and landscape pages can’t be handled like this. - - - More usefully, you could convert a GIF to WebP with: - - -$ vips copy silver-gear-cogs-animation-5.gif[n=-1] silver.webp - - - To write an animated or multipage image programmatically, you need to construct the tall, thin image and set the metadata. For example: - - -$ vips arrayjoin "k2.jpg k4a.png" x.tif[page-height=2048] --across=1 - - - Provided that the images are both 2048 pixels high, this will write a two-page TIFF. - - - In Python you could write something like: - - -#!/usr/bin/env python3 - -import sys -import pyvips - -# the input images -- assume these are all the same size -images = [pyvips.Image.new_from_file(filename, access="sequential") - for filename in sys.argv[2:]] - -# frame delays are in milliseconds -delay_array = [300] * len(images) - -animation = pyvips.Image.arrayjoin(images, across=1).copy() -animation.set_type(pyvips.GValue.gint_type, "loop", 10) -animation.set_type(pyvips.GValue.gint_type, "n-pages", len(images)) -animation.set_type(pyvips.GValue.gint_type, "page-height", images[0].height) -animation.set_type(pyvips.GValue.array_int_type, "delay", delay_array) -print(f"writing {sys.argv[1]} ...") -animation.write_to_file(sys.argv[1]) - - - It’s a little more fiddly in C: - - -/* compile with - * - * gcc -g -Wall assemble-animated.c `pkg-config vips --cflags --libs` - */ - -#include <stdlib.h> -#include <vips/vips.h> - -/* for libvips before 8.16, add this line: - * G_DEFINE_AUTOPTR_CLEANUP_FUNC(VipsImage, g_object_unref) - */ - -int -main(int argc, char *argv[]) -{ - if (VIPS_INIT(argv[0])) - vips_error_exit(NULL); - if (argc < 3) - vips_error_exit("usage: %s outfile infile1 infile2 ...", argv[0]); - - /* Load a set of input files. - */ - g_autoptr(GPtrArray) frames = g_ptr_array_new_full(argc, g_object_unref); - for (int i = 2; i < argc; i++) { - VipsImage *frame; - if (!(frame = vips_image_new_from_file(argv[i], - "access", VIPS_ACCESS_SEQUENTIAL, - NULL))) - vips_error_exit(NULL); - - g_ptr_array_add(frames, frame); - } - - /* Combine to form a vertical strip. - */ - g_autoptr(VipsImage) strip; - if (vips_arrayjoin((VipsImage **) frames->pdata, &strip, frames->len, - "across", 1, - NULL)) - vips_error_exit(NULL); - - /* Set the animation metadata. Delay times are in milliseconds. - */ - VipsImage *frame0 = VIPS_IMAGE(frames->pdata[0]); - vips_image_set_int(strip, "page-height", frame0->Ysize); - vips_image_set_int(strip, "loop", 10); - int delays[] = { 300, 300, 300 }; - vips_image_set_array_int(strip, "delay", delays, VIPS_NUMBER(delays)); - - if (vips_image_write_to_file(strip, argv[1], NULL)) - vips_error_exit(NULL); - - return 0; -} - - - - - diff --git a/doc/pandoc-docbook-template.docbook b/doc/pandoc-docbook-template.docbook deleted file mode 100644 index ef420a8d72..0000000000 --- a/doc/pandoc-docbook-template.docbook +++ /dev/null @@ -1,21 +0,0 @@ - -$if(mathml)$ - -$else$ - -$endif$ - - -$for(include-before)$ -$include-before$ -$endfor$ - -$body$ - -$for(include-after)$ -$include-after$ -$endfor$ - - diff --git a/doc/rename.sed b/doc/rename.sed new file mode 100644 index 0000000000..9ed1afb95e --- /dev/null +++ b/doc/rename.sed @@ -0,0 +1,347 @@ +s/vips_\([^(]*\)_new()/[ctor@\u\1.new]/g +s/vips_image_\(new_[^(]*\)()/[ctor@Image.\1]/g +s/vips_object_\([^(]*\)()/[method@Object.\1]/g +s/vips_image_\(generate\)()/[func@image_generate]/g +s/vips_image_\([^(]*\)()/[method@Image.\1]/g +s/vips_region_\([^(]*\)()/[method@Region.\1]/g + +s/vips_\(abs\)()/[method@Image.\1]/g +s/vips_\(acosh\)()/[method@Image.\1]/g +s/vips_\(acos\)()/[method@Image.\1]/g +s/vips_\(addalpha\)()/[method@Image.\1]/g +s/vips_\(addlpha\)()/[method@Image.\1]/g +s/vips_\(add\)()/[method@Image.\1]/g +s/vips_\(affine\)()/[method@Image.\1]/g +s/vips_\(andimage_const1\)()/[method@Image.\1]/g +s/vips_\(andimage_const\)()/[method@Image.\1]/g +s/vips_\(andimage\)()/[method@Image.\1]/g +s/vips_\(asinh\)()/[method@Image.\1]/g +s/vips_\(asin\)()/[method@Image.\1]/g +s/vips_\(atan2\)()/[method@Image.\1]/g +s/vips_\(atanh\)()/[method@Image.\1]/g +s/vips_\(atan\)()/[method@Image.\1]/g +s/vips_\(autorot\)()/[method@Image.\1]/g +s/vips_\(avg\)()/[method@Image.\1]/g +s/vips_\(bandand\)()/[method@Image.\1]/g +s/vips_\(bandbool\)()/[method@Image.\1]/g +s/vips_\(bandeor\)()/[method@Image.\1]/g +s/vips_\(bandfold\)()/[method@Image.\1]/g +s/vips_\(bandjoin2\)()/[method@Image.\1]/g +s/vips_\(bandjoin_const1\)()/[method@Image.\1]/g +s/vips_\(bandjoin_const\)()/[method@Image.\1]/g +s/vips_\(bandmean\)()/[method@Image.\1]/g +s/vips_\(bandor\)()/[method@Image.\1]/g +s/vips_\(bandunfold\)()/[method@Image.\1]/g +s/vips_\(boolean_const1\)()/[method@Image.\1]/g +s/vips_\(boolean_const\)()/[method@Image.\1]/g +s/vips_\(boolean\)()/[method@Image.\1]/g +s/vips_\(buildlut\)()/[method@Image.\1]/g +s/vips_\(byteswap\)()/[method@Image.\1]/g +s/vips_\(cache\)()/[method@Image.\1]/g +s/vips_\(canny\)()/[method@Image.\1]/g +s/vips_\(case\)()/[method@Image.\1]/g +s/vips_\(cast_char\)()/[method@Image.\1]/g +s/vips_\(cast_complex\)()/[method@Image.\1]/g +s/vips_\(cast_double\)()/[method@Image.\1]/g +s/vips_\(cast_dpcomplex\)()/[method@Image.\1]/g +s/vips_\(cast_float\)()/[method@Image.\1]/g +s/vips_\(cast_int\)()/[method@Image.\1]/g +s/vips_\(cast\)()/[method@Image.\1]/g +s/vips_\(cast_short\)()/[method@Image.\1]/g +s/vips_\(cast_uchar\)()/[method@Image.\1]/g +s/vips_\(cast_uint\)()/[method@Image.\1]/g +s/vips_\(cast_ushort\)()/[method@Image.\1]/g +s/vips_\(ceil\)()/[method@Image.\1]/g +s/vips_\(clamp\)()/[method@Image.\1]/g +s/vips_\(CMC2LCh\)()/[method@Image.\1]/g +s/vips_\(CMYK2XYZ\)()/[method@Image.\1]/g +s/vips_\(colourspace\)()/[method@Image.\1]/g +s/vips_\(compass\)()/[method@Image.\1]/g +s/vips_\(complex2\)()/[method@Image.\1]/g +s/vips_\(complexform\)()/[method@Image.\1]/g +s/vips_\(complexget\)()/[method@Image.\1]/g +s/vips_\(complex\)()/[method@Image.\1]/g +s/vips_\(composite2\)()/[method@Image.\1]/g +s/vips_\(conj\)()/[method@Image.\1]/g +s/vips_\(conva\)()/[method@Image.\1]/g +s/vips_\(convasep\)()/[method@Image.\1]/g +s/vips_\(convf\)()/[method@Image.\1]/g +s/vips_\(convi\)()/[method@Image.\1]/g +s/vips_\(conv\)()/[method@Image.\1]/g +s/vips_\(convsep\)()/[method@Image.\1]/g +s/vips_\(copy\)()/[method@Image.\1]/g +s/vips_\(cosh\)()/[method@Image.\1]/g +s/vips_\(cos\)()/[method@Image.\1]/g +s/vips_\(countlines\)()/[method@Image.\1]/g +s/vips_\(crop\)()/[method@Image.\1]/g +s/vips_\(cross_phase\)()/[method@Image.\1]/g +s/vips_\(csvsave\)()/[method@Image.\1]/g +s/vips_\(csvsave_target\)()/[method@Image.\1]/g +s/vips_\(dE00\)()/[method@Image.\1]/g +s/vips_\(dE76\)()/[method@Image.\1]/g +s/vips_\(dECMC\)()/[method@Image.\1]/g +s/vips_\(deviate\)()/[method@Image.\1]/g +s/vips_\(divide\)()/[method@Image.\1]/g +s/vips_\(draw_circle1\)()/[method@Image.\1]/g +s/vips_\(draw_circle\)()/[method@Image.\1]/g +s/vips_\(draw_flood1\)()/[method@Image.\1]/g +s/vips_\(draw_flood\)()/[method@Image.\1]/g +s/vips_\(draw_image\)()/[method@Image.\1]/g +s/vips_\(draw_line1\)()/[method@Image.\1]/g +s/vips_\(draw_line\)()/[method@Image.\1]/g +s/vips_\(draw_mask1\)()/[method@Image.\1]/g +s/vips_\(draw_mask\)()/[method@Image.\1]/g +s/vips_\(draw_point1\)()/[method@Image.\1]/g +s/vips_\(draw_point\)()/[method@Image.\1]/g +s/vips_\(draw_rect1\)()/[method@Image.\1]/g +s/vips_\(draw_rect\)()/[method@Image.\1]/g +s/vips_\(draw_smudge\)()/[method@Image.\1]/g +s/vips_\(dzsave_buffer\)()/[method@Image.\1]/g +s/vips_\(dzsave\)()/[method@Image.\1]/g +s/vips_\(dzsave_target\)()/[method@Image.\1]/g +s/vips_\(embed\)()/[method@Image.\1]/g +s/vips_\(eorimage_const1\)()/[method@Image.\1]/g +s/vips_\(eorimage_const\)()/[method@Image.\1]/g +s/vips_\(eorimage\)()/[method@Image.\1]/g +s/vips_\(equal_const1\)()/[method@Image.\1]/g +s/vips_\(equal_const\)()/[method@Image.\1]/g +s/vips_\(equal\)()/[method@Image.\1]/g +s/vips_\(exp10\)()/[method@Image.\1]/g +s/vips_\(exp\)()/[method@Image.\1]/g +s/vips_\(extract_area\)()/[method@Image.\1]/g +s/vips_\(extract_band\)()/[method@Image.\1]/g +s/vips_\(falsecolour\)()/[method@Image.\1]/g +s/vips_\(fastcor\)()/[method@Image.\1]/g +s/vips_\(fill_nearest\)()/[method@Image.\1]/g +s/vips_\(find_trim\)()/[method@Image.\1]/g +s/vips_\(fitsload\)()/[method@Image.\1]/g +s/vips_\(fitsload_source\)()/[method@Image.\1]/g +s/vips_\(fitssave\)()/[method@Image.\1]/g +s/vips_\(flatten\)()/[method@Image.\1]/g +s/vips_\(flip\)()/[method@Image.\1]/g +s/vips_\(float2rad\)()/[method@Image.\1]/g +s/vips_\(floor\)()/[method@Image.\1]/g +s/vips_\(freqmult\)()/[method@Image.\1]/g +s/vips_\(fwfft\)()/[method@Image.\1]/g +s/vips_\(gamma\)()/[method@Image.\1]/g +s/vips_\(gaussblur\)()/[method@Image.\1]/g +s/vips_\(getpoint\)()/[method@Image.\1]/g +s/vips_\(gifsave_buffer\)()/[method@Image.\1]/g +s/vips_\(gifsave\)()/[method@Image.\1]/g +s/vips_\(gifsave_target\)()/[method@Image.\1]/g +s/vips_\(globalbalance\)()/[method@Image.\1]/g +s/vips_\(gravity\)()/[method@Image.\1]/g +s/vips_\(grid\)()/[method@Image.\1]/g +s/vips_\(heifsave_buffer\)()/[method@Image.\1]/g +s/vips_\(heifsave\)()/[method@Image.\1]/g +s/vips_\(heifsave_target\)()/[method@Image.\1]/g +s/vips_\(hist_cum\)()/[method@Image.\1]/g +s/vips_\(hist_entropy\)()/[method@Image.\1]/g +s/vips_\(hist_equal\)()/[method@Image.\1]/g +s/vips_\(hist_find_indexed\)()/[method@Image.\1]/g +s/vips_\(hist_find\)()/[method@Image.\1]/g +s/vips_\(hist_find_ndim\)()/[method@Image.\1]/g +s/vips_\(hist_ismonotonic\)()/[method@Image.\1]/g +s/vips_\(hist_local\)()/[method@Image.\1]/g +s/vips_\(hist_match\)()/[method@Image.\1]/g +s/vips_\(hist_norm\)()/[method@Image.\1]/g +s/vips_\(hist_plot\)()/[method@Image.\1]/g +s/vips_\(hough_circle\)()/[method@Image.\1]/g +s/vips_\(hough_line\)()/[method@Image.\1]/g +s/vips_\(HSV2sRGB\)()/[method@Image.\1]/g +s/vips_\(icc_export\)()/[method@Image.\1]/g +s/vips_\(icc_import\)()/[method@Image.\1]/g +s/vips_\(icc_transform\)()/[method@Image.\1]/g +s/vips_\(ifthenelse\)()/[method@Image.\1]/g +s/vips_\(imag\)()/[method@Image.\1]/g +s/vips_\(insert\)()/[method@Image.\1]/g +s/vips_\(invertlut\)()/[method@Image.\1]/g +s/vips_\(invert\)()/[method@Image.\1]/g +s/vips_\(invfft\)()/[method@Image.\1]/g +s/vips_\(join\)()/[method@Image.\1]/g +s/vips_\(jp2ksave_buffer\)()/[method@Image.\1]/g +s/vips_\(jp2ksave\)()/[method@Image.\1]/g +s/vips_\(jp2ksave_target\)()/[method@Image.\1]/g +s/vips_\(jpegsave_buffer\)()/[method@Image.\1]/g +s/vips_\(jpegsave\)()/[method@Image.\1]/g +s/vips_\(jpegsave_mime\)()/[method@Image.\1]/g +s/vips_\(jpegsave_target\)()/[method@Image.\1]/g +s/vips_\(jxlload\)()/[method@Image.\1]/g +s/vips_\(jxlsave_buffer\)()/[method@Image.\1]/g +s/vips_\(jxlsave\)()/[method@Image.\1]/g +s/vips_\(jxlsave_target\)()/[method@Image.\1]/g +s/vips_\(Lab2LabQ\)()/[method@Image.\1]/g +s/vips_\(Lab2LabS\)()/[method@Image.\1]/g +s/vips_\(Lab2LCh\)()/[method@Image.\1]/g +s/vips_\(Lab2XYZ\)()/[method@Image.\1]/g +s/vips_\(labelregions\)()/[method@Image.\1]/g +s/vips_\(LabQ2Lab\)()/[method@Image.\1]/g +s/vips_\(LabQ2LabS\)()/[method@Image.\1]/g +s/vips_\(LabQ2sRGB\)()/[method@Image.\1]/g +s/vips_\(LabS2Lab\)()/[method@Image.\1]/g +s/vips_\(LabS2LabQ\)()/[method@Image.\1]/g +s/vips_\(LCh2CMC\)()/[method@Image.\1]/g +s/vips_\(LCh2Lab\)()/[method@Image.\1]/g +s/vips_\(less_const1\)()/[method@Image.\1]/g +s/vips_\(less_const\)()/[method@Image.\1]/g +s/vips_\(lesseq_const1\)()/[method@Image.\1]/g +s/vips_\(lesseq_const\)()/[method@Image.\1]/g +s/vips_\(lesseq\)()/[method@Image.\1]/g +s/vips_\(less\)()/[method@Image.\1]/g +s/vips_\(linear1\)()/[method@Image.\1]/g +s/vips_\(linear\)()/[method@Image.\1]/g +s/vips_\(linecache\)()/[method@Image.\1]/g +s/vips_\(log10\)()/[method@Image.\1]/g +s/vips_\(log\)()/[method@Image.\1]/g +s/vips_\(lshift_const1\)()/[method@Image.\1]/g +s/vips_\(lshift_const\)()/[method@Image.\1]/g +s/vips_\(lshift\)()/[method@Image.\1]/g +s/vips_\(magicksave_buffer\)()/[method@Image.\1]/g +s/vips_\(magicksave\)()/[method@Image.\1]/g +s/vips_\(mapim\)()/[method@Image.\1]/g +s/vips_\(maplut\)()/[method@Image.\1]/g +s/vips_\(match\)()/[method@Image.\1]/g +s/vips_\(math2_const1\)()/[method@Image.\1]/g +s/vips_\(math2_const\)()/[method@Image.\1]/g +s/vips_\(math2\)()/[method@Image.\1]/g +s/vips_\(math\)()/[method@Image.\1]/g +s/vips_\(matrixinvert\)()/[method@Image.\1]/g +s/vips_\(matrixmultiply\)()/[method@Image.\1]/g +s/vips_\(matrixprint\)()/[method@Image.\1]/g +s/vips_\(matrixsave\)()/[method@Image.\1]/g +s/vips_\(matrixsave_target\)()/[method@Image.\1]/g +s/vips_\(max\)()/[method@Image.\1]/g +s/vips_\(maxpair\)()/[method@Image.\1]/g +s/vips_\(measure\)()/[method@Image.\1]/g +s/vips_\(median\)()/[method@Image.\1]/g +s/vips_\(merge\)()/[method@Image.\1]/g +s/vips_\(min\)()/[method@Image.\1]/g +s/vips_\(minpair\)()/[method@Image.\1]/g +s/vips_\(more_const1\)()/[method@Image.\1]/g +s/vips_\(more_const\)()/[method@Image.\1]/g +s/vips_\(moreeq_const1\)()/[method@Image.\1]/g +s/vips_\(moreeq_const\)()/[method@Image.\1]/g +s/vips_\(moreeq\)()/[method@Image.\1]/g +s/vips_\(more\)()/[method@Image.\1]/g +s/vips_\(morph\)()/[method@Image.\1]/g +s/vips_\(mosaic1\)()/[method@Image.\1]/g +s/vips_\(mosaic\)()/[method@Image.\1]/g +s/vips_\(msb\)()/[method@Image.\1]/g +s/vips_\(multiply\)()/[method@Image.\1]/g +s/vips_\(niftisave\)()/[method@Image.\1]/g +s/vips_\(notequal_const1\)()/[method@Image.\1]/g +s/vips_\(notequal_const\)()/[method@Image.\1]/g +s/vips_\(notequal\)()/[method@Image.\1]/g +s/vips_\(orimage_const1\)()/[method@Image.\1]/g +s/vips_\(orimage_const\)()/[method@Image.\1]/g +s/vips_\(orimage\)()/[method@Image.\1]/g +s/vips_\(percent\)()/[method@Image.\1]/g +s/vips_\(phasecor\)()/[method@Image.\1]/g +s/vips_\(pngsave_buffer\)()/[method@Image.\1]/g +s/vips_\(pngsave\)()/[method@Image.\1]/g +s/vips_\(pngsave_target\)()/[method@Image.\1]/g +s/vips_\(polar\)()/[method@Image.\1]/g +s/vips_\(pow\)()/[method@Image.\1]/g +s/vips_\(ppmsave\)()/[method@Image.\1]/g +s/vips_\(ppmsave_target\)()/[method@Image.\1]/g +s/vips_\(premultiply\)()/[method@Image.\1]/g +s/vips_\(prewitt\)()/[method@Image.\1]/g +s/vips_\(profile\)()/[method@Image.\1]/g +s/vips_\(project\)()/[method@Image.\1]/g +s/vips_\(quadratic\)()/[method@Image.\1]/g +s/vips_\(rad2float\)()/[method@Image.\1]/g +s/vips_\(radsave_buffer\)()/[method@Image.\1]/g +s/vips_\(radsave\)()/[method@Image.\1]/g +s/vips_\(radsave_target\)()/[method@Image.\1]/g +s/vips_\(rank\)()/[method@Image.\1]/g +s/vips_\(rawsave_buffer\)()/[method@Image.\1]/g +s/vips_\(rawsave_fd\)()/[method@Image.\1]/g +s/vips_\(rawsave\)()/[method@Image.\1]/g +s/vips_\(rawsave\)()/[method@Image.\1]/g +s/vips_\(rawsave_target\)()/[method@Image.\1]/g +s/vips_\(real\)()/[method@Image.\1]/g +s/vips_\(recomb\)()/[method@Image.\1]/g +s/vips_\(rect\)()/[method@Image.\1]/g +s/vips_\(reduceh\)()/[method@Image.\1]/g +s/vips_\(reduce\)()/[method@Image.\1]/g +s/vips_\(reducev\)()/[method@Image.\1]/g +s/vips_\(relational_const1\)()/[method@Image.\1]/g +s/vips_\(relational_const\)()/[method@Image.\1]/g +s/vips_\(relational\)()/[method@Image.\1]/g +s/vips_\(remainder_const1\)()/[method@Image.\1]/g +s/vips_\(remainder_const\)()/[method@Image.\1]/g +s/vips_\(remainder\)()/[method@Image.\1]/g +s/vips_\(replicate\)()/[method@Image.\1]/g +s/vips_\(resize\)()/[method@Image.\1]/g +s/vips_\(rint\)()/[method@Image.\1]/g +s/vips_\(rot45\)()/[method@Image.\1]/g +s/vips_\(rotate\)()/[method@Image.\1]/g +s/vips_\(rot\)()/[method@Image.\1]/g +s/vips_\(round\)()/[method@Image.\1]/g +s/vips_\(rshift_const1\)()/[method@Image.\1]/g +s/vips_\(rshift_const\)()/[method@Image.\1]/g +s/vips_\(rshift\)()/[method@Image.\1]/g +s/vips_\(scale\)()/[method@Image.\1]/g +s/vips_\(scharr\)()/[method@Image.\1]/g +s/vips_\(scRGB2BW\)()/[method@Image.\1]/g +s/vips_\(scRGB2sRGB\)()/[method@Image.\1]/g +s/vips_\(scRGB2XYZ\)()/[method@Image.\1]/g +s/vips_\(sequential\)()/[method@Image.\1]/g +s/vips_\(sharpen\)()/[method@Image.\1]/g +s/vips_\(shrinkh\)()/[method@Image.\1]/g +s/vips_\(shrink\)()/[method@Image.\1]/g +s/vips_\(shrinkv\)()/[method@Image.\1]/g +s/vips_\(sign\)()/[method@Image.\1]/g +s/vips_\(similarity\)()/[method@Image.\1]/g +s/vips_\(sinh\)()/[method@Image.\1]/g +s/vips_\(sin\)()/[method@Image.\1]/g +s/vips_\(smartcrop\)()/[method@Image.\1]/g +s/vips_\(sobel\)()/[method@Image.\1]/g +s/vips_\(spcor\)()/[method@Image.\1]/g +s/vips_\(spectrum\)()/[method@Image.\1]/g +s/vips_\(sRGB2HSV\)()/[method@Image.\1]/g +s/vips_\(sRGB2scRGB\)()/[method@Image.\1]/g +s/vips_\(stats\)()/[method@Image.\1]/g +s/vips_\(stdif\)()/[method@Image.\1]/g +s/vips_\(subsample\)()/[method@Image.\1]/g +s/vips_\(subtract\)()/[method@Image.\1]/g +s/vips_\(tanh\)()/[method@Image.\1]/g +s/vips_\(tan\)()/[method@Image.\1]/g +s/vips_\(thumbnail_image\)()/[method@Image.\1]/g +s/vips_\(tiffsave_buffer\)()/[method@Image.\1]/g +s/vips_\(tiffsave\)()/[method@Image.\1]/g +s/vips_\(tiffsave_target\)()/[method@Image.\1]/g +s/vips_\(tilecache\)()/[method@Image.\1]/g +s/vips_\(transpose3d\)()/[method@Image.\1]/g +s/vips_\(unpremultiply\)()/[method@Image.\1]/g +s/vips_\(vipssave\)()/[method@Image.\1]/g +s/vips_\(vipssave_target\)()/[method@Image.\1]/g +s/vips_\(webpsave_buffer\)()/[method@Image.\1]/g +s/vips_\(webpsave\)()/[method@Image.\1]/g +s/vips_\(webpsave_mime\)()/[method@Image.\1]/g +s/vips_\(webpsave_target\)()/[method@Image.\1]/g +s/vips_\(wop\)()/[method@Image.\1]/g +s/vips_\(wrap\)()/[method@Image.\1]/g +s/vips_\(XYZ2CMYK\)()/[method@Image.\1]/g +s/vips_\(XYZ2Lab\)()/[method@Image.\1]/g +s/vips_\(XYZ2scRGB\)()/[method@Image.\1]/g +s/vips_\(XYZ2Yxy\)()/[method@Image.\1]/g +s/vips_\(Yxy2XYZ\)()/[method@Image.\1]/g +s/vips_\(zoom\)()/[method@Image.\1]/g + +s/vips_\([^(]*\)()/[func@\1]/g + +s/#Vips\(BandFormat\)/[enum@\1]/g +s/#Vips\(Interpretation\)/[enum@\1]/g +s/#Vips\(Coding\)/[enum@\1]/g +s/#Vips\(DemandStyle\)/[enum@\1]/g +s/#Vips\(Rect\)/[struct@\1]/g +s/#Vips\(Image\)/[class@\1]/g +s/#Vips\(Region\)/[class@\1]/g +s/#Vips\(Object\)/[class@\1]/g +s/#Vips\(Operation\)/[class@\1]/g +s/#Vips\(ForeignLoad\)/[class@\1]/g + +s/g_object_\([^(]*\)()/[method@GObject.Object.\1]/g +s/%GValue/[struct@GObject.Value]/g +s/%GObject/[class@GObject.Object]/g diff --git a/doc/rename.sh b/doc/rename.sh new file mode 100755 index 0000000000..eb32fffb09 --- /dev/null +++ b/doc/rename.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +for filename in "$@"; do + sed -i -f rename.sed $filename +done diff --git a/doc/urlmap.js b/doc/urlmap.js new file mode 100644 index 0000000000..11d27febcf --- /dev/null +++ b/doc/urlmap.js @@ -0,0 +1,6 @@ +// A map between namespaces and base URLs for their online documentation +baseURLs = [ + ['GLib', 'https://docs.gtk.org/glib/'], + ['GObject', 'https://docs.gtk.org/gobject/'], + ['GModule', 'https://docs.gtk.org/gmodule/'], +] diff --git a/doc/using-C.xml b/doc/using-C.xml deleted file mode 100644 index baf89fdac2..0000000000 --- a/doc/using-C.xml +++ /dev/null @@ -1,370 +0,0 @@ - - - - - - VIPS from C - 3 - VIPS Library - - - - Using VIPS - How to use the VIPS library from C - - - - Codestin Search App - - VIPS comes with a convenient, high-level C API. You should read the API - docs for full details, but this section will try to give a brief - overview. - - - - - Codestin Search App - - When your program starts, use VIPS_INIT() - to start up the VIPS library. You should pass it the name - of your program, usually argv[0]. If you call - vips_shutdown() just before you exit, libvips will attempt to free all - resources. This can help leak checking, but is not required. - - - - VIPS_INIT() is a macro to let it check - that the libvips library you have linked to matches the libvips headers - you included. - - - - You can add the VIPS flags to your %GObject command-line processing - with vips_add_option_entries(). - - - - - Codestin Search App - - The basic data object is the #VipsImage. You can create an - image from a file on disc or from an area of memory, either - as a C-style array, or as a formatted object, like JPEG. See - vips_image_new_from_file() and friends. Loading an - image is fast: VIPS read just enough of the image to be able to get - the various properties, such as width, but no decoding occurs until - pixel values are really needed. - - - - Once you have an image, you can get properties from it in the usual way. - You can use projection functions, like vips_image_get_width() or - g_object_get(), to get %GObject properties. All VIPS objects are - immutable, meaning you can only get properties, you can't set them. - See VIPS Header to read about - image properties. - - - - - Codestin Search App - - VIPS is based on the %GObject library and is therefore reference counted. - vips_image_new_from_file() returns an object with a count of 1. - When you are done with an image, use g_object_unref() to dispose of it. - If you pass an image to an operation and that operation needs to keep a - copy of the image, it will ref it. So you can unref an image as soon as - you no longer need it, you don't need to hang on to it in case anyone - else is still using it. - - - - See #VipsOperation for more detail on VIPS - reference counting conventions. See the Reference pools - section below for a way to automate reference counting in C. - - - - - - Codestin Search App - - Use things like vips_embed() to manipulate your images. You use it from - C like this: - - -const char *filename; -VipsImage *in = vips_image_new_from_file(filename, NULL); -const int x = 10; -const int y = 10; -const int width = 1000; -const int height = 1000; -VipsImage *out; - -if (vips_embed(in, &out, x, y, width, height, NULL)) - error_handling(); - - - Now out will hold a reference to a 1000 by 1000 pixel - image, with in pasted 10 right and 10 down from the top - left-hand corner. The remainder of the image will be black. If - in is too large, it will be clipped at the image edges. - - - - Operations can take optional arguments. You give these as a set of - NULL-terminated name-value pairs at the end of the call. For example, - you can write: - - -if (vips_embed(in, &out, x, y, width, height, - "extend", VIPS_EXTEND_COPY, - NULL)) - error_handling(); - - - And now the new edge pixels, which were black, will be filled with a copy - of the edge pixels of in. Operation options are listed - at the top of each operation's entry in the docs. Alternatively, - the vips program is handy for getting a - summary of an operation's parameters. For example: - - -$ vips embed -embed an image in a larger image -usage: - embed in out x y width height [--option-name option-value ...] -where: - in - Input image, input VipsImage - out - Output image, output VipsImage - x - Left edge of input in output, input gint - default: 0 - min: -1000000000, max: 1000000000 - y - Top edge of input in output, input gint - default: 0 - min: -1000000000, max: 1000000000 - width - Image width in pixels, input gint - default: 1 - min: 1, max: 1000000000 - height - Image height in pixels, input gint - default: 1 - min: 1, max: 1000000000 -optional arguments: - extend - How to generate the extra pixels, input VipsExtend - default enum: black - allowed enums: black, copy, repeat, mirror, white, background - background - Colour for background pixels, input VipsArrayDouble - - - See #VipsOperation for more information on running operations on images. - - - - The API docs have a handy table of all vips - operations, if you want to find out how to do something, try - searching that. - - - - When you are done, you can write - the final image to a disc file, to a formatted memory buffer, or to - C-style memory array. See vips_image_write_to_file() and friends. - - - - - Codestin Search App - - Use #VipsRegion to read pixels out of images. You can use - VIPS_IMAGE_ADDR() as well, but this can need a large amount of - memory to work. See extending - for an introduction to writing your own operations. - - - - - Codestin Search App - - - VIPS keeps a log of error message, see VIPS Error to find out how to get and - clear the error log. - - - - - - Codestin Search App - - - On *nix systems, you can compile the example code with something like: - - -$ gcc -g -Wall myprog.c `pkg-config vips --cflags --libs` - - - On Windows, you'll need to set the compiler flags by hand, perhaps: - - -x86_64-w64-mingw32-gcc-win32 -mms-bitfields \ - -Ic:/vips-8.6/include \ - -Ic:/vips-8.6/include/glib-2.0 \ - -Ic:/vips-8.6/lib/glib-2.0/include \ - myprog.c \ - -Lc:/vips-8.6/lib \ - -lvips -lz -ljpeg -lstdc++ -lxml2 -lfftw3 -lm -lMagickWand -llcms2 \ - -lopenslide -lcfitsio -lpangoft2-1.0 -ltiff -lpng14 -lexif \ - -lMagickCore -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 \ - -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl \ - -o myprog.exe - - - - - -Codestin Search App - -#include <stdio.h> -#include <vips/vips.h> - -int -main(int argc, char **argv) -{ - VipsImage *in; - double mean; - VipsImage *out; - - if (VIPS_INIT(argv[0])) - vips_error_exit(NULL); - - if (argc != 3) - vips_error_exit("usage: %s infile outfile", argv[0]); - - if (!(in = vips_image_new_from_file(argv[1], NULL))) - vips_error_exit(NULL); - - printf("image width = %d\n", vips_image_get_width(in)); - - if (vips_avg(in, &mean, NULL)) - vips_error_exit(NULL); - - printf("mean pixel value = %g\n", mean); - - if (vips_invert(in, &out, NULL)) - vips_error_exit(NULL); - - g_object_unref(in); - - if (vips_image_write_to_file(out, argv[2], NULL)) - vips_error_exit(NULL); - - g_object_unref(out); - - return 0; -} - - - - - - - Codestin Search App - - libvips has a simple system to automate at least some reference counting - issues. Reference pools are arrays of object pointers which will be - released automatically when some other object is finalized. - - - - The code below crops a many-page image (perhaps a GIF or PDF). It - splits the image into separate pages, crops each page, reassembles the - cropped areas, and saves again. It creates a context - object representing the state of processing, and - crop_animation allocates two reference pools off that using - vips_object_local_array, one to hold the cropped frames, - and one to assemble and copy the result. - - - - All unreffing is handled by main, and it doesn't need to - know anything about crop_animation. - - - -Codestin Search App - -#include <vips/vips.h> - -static int -crop_animation(VipsObject *context, VipsImage *image, VipsImage **out, - int left, int top, int width, int height) -{ - int page_height = vips_image_get_page_height(image); - int n_pages = image->Ysize / page_height; - VipsImage **page = (VipsImage **) vips_object_local_array(context, n_pages); - VipsImage **copy = (VipsImage **) vips_object_local_array(context, 1); - - int i; - - /* Split the image into cropped frames. - */ - for (i = 0; i < n_pages; i++) - if (vips_crop(image, &page[i], - left, page_height * i + top, width, height, NULL)) - return -1; - - /* Reassemble the frames and set the page height. You must copy before - * modifying metadata. - */ - if (vips_arrayjoin(page, &copy[0], n_pages, "across", 1, NULL) || - vips_copy(copy[0], out, NULL)) - return -1; - vips_image_set_int(*out, "page-height", height); - - return 0; -} - -int -main(int argc, char **argv) -{ - VipsImage *image; - VipsObject *context; - VipsImage *x; - - if (VIPS_INIT(NULL)) - vips_error_exit(NULL); - - if (!(image = vips_image_new_from_file(argv[1], - "access", VIPS_ACCESS_SEQUENTIAL, - NULL))) - vips_error_exit(NULL); - - context = VIPS_OBJECT(vips_image_new()); - if (crop_animation(context, image, &x, 10, 10, 500, 500)) { - g_object_unref(image); - g_object_unref(context); - vips_error_exit(NULL); - } - g_object_unref(image); - g_object_unref(context); - image = x; - - if (vips_image_write_to_file(image, argv[2], NULL)) { - g_object_unref(image); - vips_error_exit(NULL); - } - - g_object_unref(image); - - return 0; -} - - - - - - diff --git a/doc/using-command-line.xml b/doc/using-command-line.xml deleted file mode 100644 index bff7e22ebc..0000000000 --- a/doc/using-command-line.xml +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - VIPS from the command-line - 1 - VIPS Library - - - - Using VIPS - How to use the VIPS library from the command-line - - - - Codestin Search App - - Use the vips command to execute VIPS operations from - the command-line. For example: - - -$ vips rot k2.jpg x.jpg d90 - - - Will rotate the image k2.jpg by 90 degrees - anticlockwise and write the result to the file x.jpg. - If you don't give any arguments to an operation, - vips will give a short description, for example: - - -$ vips rot -rotate an image -usage: - rot in out angle -where: - in - Input image, input VipsImage - out - Output image, output VipsImage - angle - Angle to rotate image, input VipsAngle - default: d90 - allowed: d0, d90, d180, d270 - - - There's a straightforward relationship with the C API: compare this to - the API docs for vips_rot(). - - - - - Codestin Search App - - You can list all classes with: - - -$ vips -l -... -VipsOperation (operation), operations - VipsSystem (system), run an external command - VipsArithmetic (arithmetic), arithmetic operations - VipsBinary (binary), binary operations - VipsAdd (add), add two images - ... etc. - - - Each line shows the canonical name of the class (for example - VipsAdd), the class nickname - (add in this case), and a short description. - Some subclasses of operation will show more: for example, subclasses of - VipsForeign will show some of the extra flags - supported by the file load/save operations. - - - - The API docs have a handy table of all vips - operations, if you want to find out how to do something, try - searching that. - - - - - Codestin Search App - - Many operations take optional arguments. You can supply these as - command-line options. For example: - - -$ vips gamma -gamma an image -usage: - gamma in out [--option-name option-value ...] -where: - in - Input image, input VipsImage - out - Output image, output VipsImage -optional arguments: - exponent - Gamma factor, input gdouble - default: 0.416667 - min: 1e-06, max: 1000 -operation flags: sequential - - - vips_gamma() applies a gamma factor to an image. By - default, it uses 2.4, the sRGB gamma factor, but you can specify any - gamma with the exponent option. - - - - Use it from the command-line like this: - - -$ vips gamma k2.jpg x.jpg --exponent 0.42 - - - This will read file k2.jpg, un-gamma it, and - write the result to file x.jpg. - - - - - Codestin Search App - - Some operations take arrays of values as arguments. For example, - vips_affine() needs an array of four numbers for the - 2x2 transform matrix. You pass arrays as space-separated lists: - - -$ vips affine k2.jpg x.jpg "2 0 0 1" - - - You may need the quotes to stop your shell breaking the argument at - the spaces. vips_bandjoin() needs an array of input images to - join, run it like this: - - -$ vips bandjoin "k2.jpg k4.jpg" x.tif - - - - - - Codestin Search App - - vips will automatically convert between image file - formats for you. Input images are detected by sniffing their first few - bytes; output formats are set from the filename suffix. You can see a - list of all the supported file formats with something like: - - -$ vips -l foreign - - - Then get a list of the options a format supports with: - - -$ vips jpegsave - - - - - You can pass options to the implicit load and save operations enclosed - in square brackets after the filename: - - -vips affine k2.jpg x.jpg[Q=90,strip] "2 0 0 1" - - - Will write x.jpg at quality level 90 and will - strip all metadata from the image. - - - - - Codestin Search App - - - Because each operation runs in a separate process, you can't use - libvips's chaining system to join operations together, you have to use - intermediate files. The command-line interface is therefore quite a bit - slower than Python or C. - - - - The best alternative is to use vips files for intermediates. - Something like: - - -vips invert input.jpg t1.v -vips affine t1.v output.jpg "2 0 0 1" -rm t1.v - - - - - - - Codestin Search App - - - Finally, vips has a couple of useful extra options. - - - - - Use to get - vips to display a simple progress indicator. - - - - - - Use and vips will - leak-test on exit, and also display an estimate of peak memory use. - - - - - - Set G_MESSAGES_DEBUG=VIPS and GLib will display - informational and debug messages from libvips. - - - - - - - - VIPS comes with a couple of other useful programs. - vipsheader is a command which can print image header - fields. vipsedit can change fields in vips format - images. vipsthumbnail can make image thumbnails - quickly. - - - - diff --git a/doc/using-from-c.md b/doc/using-from-c.md new file mode 100644 index 0000000000..8621937f52 --- /dev/null +++ b/doc/using-from-c.md @@ -0,0 +1,288 @@ +Title: Using libvips from C + +# Using libvips from C + +libvips comes with a convenient, high-level C API. You should read the API +docs for full details, but this section will try to give a brief overview. + +## Library startup + +When your program starts, use [func@INIT] to start up libvips. You +should pass it the name of your program, usually `argv[0]`. If +you call [func@shutdown] just before you exit, libvips will attempt to free +all resources. This can help leak checking, but is not required. + +[func@INIT] is a macro to let it check that the libvips shared library you +have linked to matches the libvips headers you included. + +You can add the libvips flags to your [class@GObject.Object] command-line +processing with [func@add_option_entries]. + +## The [class@Image] class + +The basic data object is the [class@Image]. You can create an image from a +file on disc or from an area of memory, either as a C-style array, or as a +formatted object, like JPEG. See [ctor@Image.new_from_file] and friends. +Loading an image is fast: libvips read just enough of the image to be able +to get the various properties, such as width, but no decoding occurs until +pixel values are really needed. + +Once you have an image, you can get properties from it in the usual +way. You can use projection functions, like [method@Image.get_width] or +[method@GObject.Object.get], to get [class@GObject.Object] properties. All +libvips objects are immutable, meaning you can only get properties, you +can't set them. See [libvips Header](file-format.html) to read about image +properties. + +## Reference counting + +libvips is based on the [class@GObject.Object] library and is therefore +reference counted. [ctor@Image.new_from_file] returns an object with a count +of 1. When you are done with an image, use [method@GObject.Object.unref] to +dispose of it. If you pass an image to an operation and that operation needs +to keep a copy of the image, it will ref it. So you can unref an image as soon +as you no longer need it, you don't need to hang on to it in case anyone else +is still using it. + +See [class@Operation] for more details on libvips' reference counting +conventions. See the [Reference pools](#reference-pools) section below +for a way to automate reference counting in C. + +## libvips operations + +Use things like [method@Image.embed] to manipulate your images. You use it +from C like this: + +```c +const char *filename; +VipsImage *in = vips_image_new_from_file(filename, NULL); +const int x = 10; +const int y = 10; +const int width = 1000; +const int height = 1000; +VipsImage *out; + +if (vips_embed(in, &out, x, y, width, height, NULL)) + error_handling(); +``` + +Now `out` will hold a reference to a 1000 by 1000 pixel image, with `in` +pasted 10 right and 10 down from the top left-hand corner. The remainder +of the image will be black. If `in` is too large, it will be clipped at +the image edges. + +Operations can take optional arguments. You give these as a set of +NULL-terminated name-value pairs at the end of the call. For example, +you can write: + +```c +if (vips_embed(in, &out, x, y, width, height, + "extend", VIPS_EXTEND_COPY, + NULL)) + error_handling(); +``` + +And now the new edge pixels, which were black, will be filled with a copy +of the edge pixels of `in`. Operation options are listed at the top of each +operation's entry in the docs. Alternatively, the `vips` program is handy +for getting a summary of an operation's parameters. For example: + +```bash +$ vips embed +embed an image in a larger image +usage: + embed in out x y width height [--option-name option-value ...] +where: + in - Input image, input VipsImage + out - Output image, output VipsImage + x - Left edge of input in output, input gint + default: 0 + min: -1000000000, max: 1000000000 + y - Top edge of input in output, input gint + default: 0 + min: -1000000000, max: 1000000000 + width - Image width in pixels, input gint + default: 1 + min: 1, max: 1000000000 + height - Image height in pixels, input gint + default: 1 + min: 1, max: 1000000000 +optional arguments: + extend - How to generate the extra pixels, input VipsExtend + default enum: black + allowed enums: black, copy, repeat, mirror, white, background + background - Colour for background pixels, input VipsArrayDouble +``` + +See [class@Operation] for more information on running operations on images. + +The API docs have a [handy table of all libvips operations]( +function-list.html), if you want to find out how to do something, try +searching that. + +When you are done, you can write the final image to a disc file, +to a formatted memory buffer, or to C-style memory array. See +[method@Image.write_to_file] and friends. + +## Getting pixels + +Use [class@Region] to read pixels out of images. You can use [func@IMAGE_ADDR] +as well, but this can need a large amount of memory to work. See [extending]( +extending.html) for an introduction to writing your own operations. + +## Error handling + +libvips keeps a log of error message, see [func@error_buffer] and +[func@error_clear] to find out how to get and clear the error log. + +## Example + +On Unix systems, you can compile the [example code](#libvips-from-c-example) +with something like: + +```bash +$ gcc -g -Wall myprog.c `pkg-config vips --cflags --libs` +``` + +On Windows, you'll need to set the compiler flags by hand, perhaps: + +```bash +x86_64-w64-mingw32-gcc-win32 -mms-bitfields \ + -Ic:/vips-8.6/include \ + -Ic:/vips-8.6/include/glib-2.0 \ + -Ic:/vips-8.6/lib/glib-2.0/include \ + myprog.c \ + -Lc:/vips-8.6/lib \ + -lvips -lz -ljpeg -lstdc++ -lxml2 -lfftw3 -lm -lMagickWand -llcms2 \ + -lopenslide -lcfitsio -lpangoft2-1.0 -ltiff -lpng14 -lexif \ + -lMagickCore -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 \ + -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl \ + -o myprog.exe +``` + +## libvips from C example + +```c +#include +#include + +int +main(int argc, char **argv) +{ + VipsImage *in; + double mean; + VipsImage *out; + + if (VIPS_INIT(argv[0])) + vips_error_exit(NULL); + + if (argc != 3) + vips_error_exit("usage: %s infile outfile", argv[0]); + + if (!(in = vips_image_new_from_file(argv[1], NULL))) + vips_error_exit(NULL); + + printf("image width = %d\n", vips_image_get_width(in)); + + if (vips_avg(in, &mean, NULL)) + vips_error_exit(NULL); + + printf("mean pixel value = %g\n", mean); + + if (vips_invert(in, &out, NULL)) + vips_error_exit(NULL); + + g_object_unref(in); + + if (vips_image_write_to_file(out, argv[2], NULL)) + vips_error_exit(NULL); + + g_object_unref(out); + + return 0; +} +``` + +## Reference pools + +libvips has a simple system to automate at least some reference counting +issues. Reference pools are arrays of object pointers which will be released +automatically when some other object is finalized. + +The code below crops a many-page image (perhaps a GIF or PDF). It splits the +image into separate pages, crops each page, reassembles the cropped areas, +and saves again. It creates a `context` object representing the state of +processing, and `crop_animation` allocates two reference pools off that +using [method@Object.local_array], one to hold the cropped frames, and one +to assemble and copy the result. + +All unreffing is handled by `main`, and it doesn't need to know anything +about `crop_animation`. + +```c +#include + +static int +crop_animation(VipsObject *context, VipsImage *image, VipsImage **out, + int left, int top, int width, int height) +{ + int page_height = vips_image_get_page_height(image); + int n_pages = image->Ysize / page_height; + VipsImage **page = (VipsImage **) vips_object_local_array(context, n_pages); + VipsImage **copy = (VipsImage **) vips_object_local_array(context, 1); + + int i; + + /* Split the image into cropped frames. + */ + for (i = 0; i < n_pages; i++) + if (vips_crop(image, &page[i], + left, page_height * i + top, width, height, NULL)) + return -1; + + /* Reassemble the frames and set the page height. You must copy before + * modifying metadata. + */ + if (vips_arrayjoin(page, ©[0], n_pages, "across", 1, NULL) || + vips_copy(copy[0], out, NULL)) + return -1; + vips_image_set_int(*out, "page-height", height); + + return 0; +} + +int +main(int argc, char **argv) +{ + VipsImage *image; + VipsObject *context; + VipsImage *x; + + if (VIPS_INIT(NULL)) + vips_error_exit(NULL); + + if (!(image = vips_image_new_from_file(argv[1], + "access", VIPS_ACCESS_SEQUENTIAL, + NULL))) + vips_error_exit(NULL); + + context = VIPS_OBJECT([ctor@Image.new]); + if (crop_animation(context, image, &x, 10, 10, 500, 500)) { + g_object_unref(image); + g_object_unref(context); + vips_error_exit(NULL); + } + g_object_unref(image); + g_object_unref(context); + image = x; + + if (vips_image_write_to_file(image, argv[2], NULL)) { + g_object_unref(image); + vips_error_exit(NULL); + } + + g_object_unref(image); + + return 0; +} +``` diff --git a/doc/using-from-cplusplus.md b/doc/using-from-cplusplus.md new file mode 100644 index 0000000000..11671eb155 --- /dev/null +++ b/doc/using-from-cplusplus.md @@ -0,0 +1,10 @@ +Title: Using libvips from C++ + +# Using libvips from C++ + +libvips comes with a convenient C++ API. It is a very thin wrapper over the +C API and adds automatic reference counting, exceptions, operator +overloads, and automatic constant expansion. + +See the [C++ API documentation](https://www.libvips.org/API/current/cpp/) +for more details. diff --git a/doc/using-the-cli.md b/doc/using-the-cli.md new file mode 100644 index 0000000000..71c50a679d --- /dev/null +++ b/doc/using-the-cli.md @@ -0,0 +1,164 @@ +Title: Using libvips at the command-line + +# Using libvips at the command-line + +Use the `vips` command to execute libvips operations from the command-line. +For example: + +```bash +$ vips rot k2.jpg x.jpg d90 +``` + +Will rotate the image `k2.jpg` by 90 degrees anticlockwise and write the +result to the file `x.jpg`. If you don't give any arguments to an operation, +`vips` will give a short description, for example: + +```bash +$ vips rot +rotate an image +usage: + rot in out angle +where: + in - Input image, input VipsImage + out - Output image, output VipsImage + angle - Angle to rotate image, input VipsAngle + default: d90 + allowed: d0, d90, d180, d270 +``` + +There's a straightforward relationship with the C API: compare this to the +API docs for [method@Image.rot]. + +## Listing all operations + +You can list all classes with: + +```bash +$ vips -l +... +VipsOperation (operation), operations + VipsSystem (system), run an external command + VipsArithmetic (arithmetic), arithmetic operations + VipsBinary (binary), binary operations + VipsAdd (add), add two images + ... etc. +``` + +Each line shows the canonical name of the class (for example `VipsAdd`), the +class nickname (`add` in this case), and a short description. Some subclasses +of operation will show more: for example, subclasses of `VipsForeign` +will show some of the extra flags supported by the file load/save operations. + +The API docs have a [handy table of all libvips operations]( +function-list.html), if you want to find out how to do something, try +searching that. + +## Optional arguments + +Many operations take optional arguments. You can supply these as command-line +options. For example: + +```bash +$ vips gamma +gamma an image +usage: + gamma in out [--option-name option-value ...] +where: + in - Input image, input VipsImage + out - Output image, output VipsImage +optional arguments: + exponent - Gamma factor, input gdouble + default: 0.416667 + min: 1e-06, max: 1000 +operation flags: sequential +``` + +[method@Image.gamma] applies a gamma factor to an image. By +default, it uses 2.4, the sRGB gamma factor, but you can specify any +gamma with the `exponent` option. + +Use it from the command-line like this: + +```bash +$ vips gamma k2.jpg x.jpg --exponent 0.42 +``` + +This will read file `k2.jpg`, un-gamma it, and +write the result to file `x.jpg`. + +## Array arguments + +Some operations take arrays of values as arguments. For example, +[method@Image.affine] needs an array of four numbers for the +2x2 transform matrix. You pass arrays as space-separated lists: + +```bash +$ vips affine k2.jpg x.jpg "2 0 0 1" +``` + +You may need the quotes to stop your shell breaking the argument at +the spaces. [func@bandjoin] needs an array of input images to +join, run it like this: + +```bash +$ vips bandjoin "k2.jpg k4.jpg" x.tif +``` + +## Implicit file format conversion + +`vips` will automatically convert between image file +formats for you. Input images are detected by sniffing their first few +bytes; output formats are set from the filename suffix. You can see a +list of all the supported file formats with something like: + +```bash +$ vips -l foreign +``` + +Then get a list of the options a format supports with: + +```bash +$ vips jpegsave +``` + +You can pass options to the implicit load and save operations enclosed +in square brackets after the filename: + +```bash +$ vips affine k2.jpg x.jpg[Q=90,strip] "2 0 0 1" +``` + +Will write `x.jpg` at quality level 90 and will +strip all metadata from the image. + +## Chaining operations + +Because each operation runs in a separate process, you can't use +libvips's chaining system to join operations together, you have to use +intermediate files. The command-line interface is therefore quite a bit +slower than Python or C. + +The best alternative is to use libvips files for intermediates. +Something like: + +```bash +$ vips invert input.jpg t1.v +$ vips affine t1.v output.jpg "2 0 0 1" +$ rm t1.v +``` + +## Other features + +Finally, `vips` has a couple of useful extra options. + +- Use `--vips-progress` to get `vips` to display a simple progress indicator. + +- Use `--vips-leak` and `vips` will leak-test + on exit, and also display an estimate of peak memory use. + +- Set `G_MESSAGES_DEBUG=VIPS` and GLib will display informational + and debug messages from libvips. + +libvips comes with a couple of other useful programs. `vipsheader` is a +command which can print image header fields. `vipsedit` can change fields +in `.v` format images. `vipsthumbnail` can make image thumbnails quickly. diff --git a/doc/using-threads.md b/doc/using-threads.md new file mode 100644 index 0000000000..74e0bc45e1 --- /dev/null +++ b/doc/using-threads.md @@ -0,0 +1,180 @@ +Title: Using threads + +# Using threads + +This section tries to summarise the rules for threaded programs using +libvips. Generally, libvips is threaded and thread-safe, with a few +exceptions. + +## Images + +On startup, you need to call [func@INIT] single-threaded. After that, +you can freely create images in any thread and read them in any other +thread. See the example at the end of this chapter. +Note that results can also be shared between threads for you by the +libvips operation cache. + +The exception is the drawing operators, such as [method@Image.draw_circle]. +These operations modify their image argument so you can't call them on +the same image from more than one thread. Reading from an image while +another thread is writing to it with one of the draw operations will +obviously also fail. + +When libvips calculates an image, by default it will use as many +threads as you have CPU cores. Use [func@concurrency_set] to change this. + +## Error handling + +libvips has a single error code (-1 or %NULL) returned by all functions +on error. Error messages are not returned, instead they are logged +in a single global error buffer shared by all threads, see +[func@error_buffer]. + +This makes error handling very simple but the obvious downside is that +because error returns and error messages are separate, when you +detect an error return you can't be +sure that what's in the error buffer is the message that matches your +error. + +The simplest way to handle this is to present the whole error log to +the user on the next interaction and leave it to them to decide what +action caused the failure. + +## Using [class@Region] between threads + +[class@Image] objects are immutable and can be shared between +threads very simply. However the lower-level [class@Region] object +used to implement [class@Image] (see [extending libvips](extending.html)) is +mutable and you can only use a [class@Region] from one thread at once. + +In fact it's worse than that: to reduce locking, [class@Region] keeps a +lot of state in per-thread storage. If you want to create a region in +one thread and use it in another, you have to first tag the region as +unowned from the creating thread with `vips__region_no_ownership()`, then +in the receiving thread take ownership with +`vips__region_take_ownership()`. See the source for operations like +[method@Image.tilecache] if you're curious how this works. + +libvips includes a set of sanity checks for region ownership and will +fail if you don't pass ownership correctly. + +## Example + +This example runs many [method@Image.resize] in parallel from many threads. + +```c +/* Read from many threads. + * + * Compile with: + * + * gcc -g -Wall soak.c `pkg-config vips --cflags --libs` + * + * Run with: + * + * rm -rf x + * mkdir x + * for i in {0..10}; do ./a.out ~/pics/k2.jpg; done + * + */ + +#include +#include + +#include + +/* How many pings we run at once. + */ +#define NUM_IN_PARALLEL (50) + +/* Number of tests we do in total. + */ +#define TOTAL_TESTS (NUM_IN_PARALLEL * 20) + +/* Workers queue up on this. + */ +GMutex allocation_lock; + +/* Our set of threads. + */ +GThread *workers[NUM_IN_PARALLEL]; + +/* Number of calls so far. + */ +int n_calls = 0; + +/* Our test function. This is called by NUM_IN_PARALLEL threads a total of + * TOTAL_TESTS times. + */ +static int +test(const char *filename) +{ + VipsImage *im, *x; + char output_file[256]; + + snprintf(output_file, 256, "x/tmp-%p.jpg", g_thread_self()); + + if (!(im = vips_image_new_from_file(filename, + "access", VIPS_ACCESS_SEQUENTIAL, + NULL))) + return -1; + + if (vips_resize(im, &x, 0.1, NULL)) { + g_object_unref(im); + return -1; + } + g_object_unref(im); + im = x; + + if (vips_image_write_to_file(im, output_file, NULL)) { + g_object_unref(im); + return -1; + } + g_object_unref(im); + + return 0; +} + +/* What we run as a thread. + */ +static void * +worker(void *data) +{ + const char *filename = (const char *) data; + + for (;;) { + gboolean done; + + done = FALSE; + g_mutex_lock(&allocation_lock); + n_calls += 1; + if (n_calls > TOTAL_TESTS) + done = TRUE; + g_mutex_unlock(&allocation_lock); + + if (done) + break; + + if (test(filename)) + vips_error_exit(NULL); + } + + return NULL; +} + +int +main(int argc, char **argv) +{ + int i; + + if (VIPS_INIT(argv[0])) + vips_error_exit(NULL); + + for (i = 0; i < NUM_IN_PARALLEL; i++) + workers[i] = g_thread_new(NULL, (GThreadFunc) worker, argv[1]); + + for (i = 0; i < NUM_IN_PARALLEL; i++) + g_thread_join(workers[i]); + + return 0; +} +``` diff --git a/doc/using-threads.xml b/doc/using-threads.xml deleted file mode 100644 index 409dc2d8a2..0000000000 --- a/doc/using-threads.xml +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - VIPS and threads - 3 - VIPS Library - - - - Using VIPS - VIPS and threading - - - - Codestin Search App - - This section tries to summarise the rules for threaded programs using - libvips. Generally, libvips is threaded and thread-safe, with a few - exceptions. - - - - - Codestin Search App - - On startup, you need to call VIPS_INIT() single-threaded. After that, - you can freely create images in any thread and read them in any other - thread. See the example at the end of this chapter. - Note that results can also be shared between threads for you by the vips - operation cache. - - - - The exception is the drawing operators, such as vips_draw_circle(). - These operations modify their image argument so you can't call them on - the same image from more than one thread. Reading from an image while - another thread is writing to it with one of the draw operations will - obviously also fail. - - - - When libvips calculates an image, by default it will use as many - threads as you have CPU cores. Use vips_concurrency_set() to change this. - - - - - - Codestin Search App - - libvips has a single error code (-1 or %NULL) returned by all functions - on error. Error messages are not returned, instead they are logged - in a single global error buffer shared by all threads, see - vips_error_buffer(). - - - - This makes error handling very simple but the obvious downside is that - because error returns and error messages are separate, when you - detect an error return you can't be - sure that what's in the error buffer is the message that matches your - error. - - - - The simplest way to handle this is to present the whole error log to - the user on the next interaction and leave it to them to decide what - action caused the failure. - - - - - - Codestin Search App - - #VipsImage objects are immutable and can be shared between - threads very simply. - However the lower-level #VipsRegion object used to implement #VipsImage - (see Extending VIPS) is mutable and you - can only use a #VipsRegion from one thread at once. - - - - In fact it's worse than that: to reduce locking, #VipsRegion keeps a - lot of state in per-thread storage. If you want to create a region in - one thread and use it in another, you have to first tag the region as - unowned from the creating thread with vips__region_no_ownership(), then - in the receiving thread take ownership with - vips__region_take_ownership(). See the source for operations like - vips_tilecache() if you're curious how this works. - - - - libvips includes a set of sanity checks for region ownership and will - fail if you don't pass ownership correctly. - - - - - - Codestin Search App - - This example runs many vips_resize() in parallel from many threads. - - - -Codestin Search App - -/* Read from many threads. - * - * Compile with: - * - * gcc -g -Wall soak.c `pkg-config vips --cflags --libs` - * - * Run with: - * - * rm -rf x - * mkdir x - * for i in {0..10}; do ./a.out ~/pics/k2.jpg; done - * - */ - -#include <stdio.h> -#include <glib.h> - -#include <vips/vips.h> - -/* How many pings we run at once. - */ -#define NUM_IN_PARALLEL (50) - -/* Number of tests we do in total. - */ -#define TOTAL_TESTS (NUM_IN_PARALLEL * 20) - -/* Workers queue up on this. - */ -GMutex allocation_lock; - -/* Our set of threads. - */ -GThread *workers[NUM_IN_PARALLEL]; - -/* Number of calls so far. - */ -int n_calls = 0; - -/* Our test function. This is called by NUM_IN_PARALLEL threads a total of - * TOTAL_TESTS times. - */ -static int -test(const char *filename) -{ - VipsImage *im, *x; - char output_file[256]; - - snprintf(output_file, 256, "x/tmp-%p.jpg", g_thread_self()); - - if (!(im = vips_image_new_from_file(filename, - "access", VIPS_ACCESS_SEQUENTIAL, - NULL))) - return -1; - - if (vips_resize(im, &x, 0.1, NULL)) { - g_object_unref(im); - return -1; - } - g_object_unref(im); - im = x; - - if (vips_image_write_to_file(im, output_file, NULL)) { - g_object_unref(im); - return -1; - } - g_object_unref(im); - - return 0; -} - -/* What we run as a thread. - */ -static void * -worker(void *data) -{ - const char *filename = (const char *) data; - - for (;;) { - gboolean done; - - done = FALSE; - g_mutex_lock(&allocation_lock); - n_calls += 1; - if (n_calls > TOTAL_TESTS) - done = TRUE; - g_mutex_unlock(&allocation_lock); - - if (done) - break; - - if (test(filename)) - vips_error_exit(NULL); - } - - return NULL; -} - -int -main(int argc, char **argv) -{ - int i; - - if (VIPS_INIT(argv[0])) - vips_error_exit(NULL); - - for (i = 0; i < NUM_IN_PARALLEL; i++) - workers[i] = g_thread_new(NULL, (GThreadFunc) worker, argv[1]); - - for (i = 0; i < NUM_IN_PARALLEL; i++) - g_thread_join(workers[i]); - - return 0; -} - - - - - - diff --git a/doc/Using-vipsthumbnail.md b/doc/using-vipsthumbnail.md similarity index 91% rename from doc/Using-vipsthumbnail.md rename to doc/using-vipsthumbnail.md index 98266522e3..97b8e61f77 100644 --- a/doc/Using-vipsthumbnail.md +++ b/doc/using-vipsthumbnail.md @@ -1,23 +1,16 @@ - - Using `vipsthumbnail` - 3 - libvips - +Title: Using vipsthumbnail - - `vipsthumbnail` - Introduction to `vipsthumbnail`, with examples - +# Using vipsthumbnail libvips ships with a handy command-line image thumbnailer, `vipsthumbnail`. This page introduces it, with some examples. -The thumbnailing functionality is implemented by `vips_thumbnail()` and -`vips_thumbnail_buffer()` (which thumbnails an image held as a string), +The thumbnailing functionality is implemented by [func@thumbnail] and +[func@thumbnail_buffer] (which thumbnails an image held as a string), see the docs for details. You can use these functions from any language with a libvips binding. For example, from PHP you could write: -```php?start_inline=1 +```php $filename = "image.jpg"; $image = Vips\Image::thumbnail($filename, 200, ["height" => 200]); $image->writeToFile("my-thumbnail.jpg"); @@ -31,9 +24,9 @@ $ cat k2.jpg | \ cat > x.jpg ``` -# libvips options +## libvips options -`vipsthumbnail` supports the usual range of vips command-line options. A +`vipsthumbnail` supports the usual range of `vips` command-line options. A few of them are useful: `--vips-cache-trace` shows each operation as libvips starts it. It can be @@ -48,7 +41,7 @@ useful to see where libvips is looping and how often. `--vips-info` shows a higher level view of the operations that `vipsthumbnail` is running. -# Looping +## Looping `vipsthumbnail` can process many images in one command. For example: @@ -68,7 +61,7 @@ much load you want to put on your system. For example: $ parallel vipsthumbnail ::: *.jpg ``` -# Thumbnail size +## Thumbnail size You can set the bounding box of the generated thumbnail with the `--size` option. For example: @@ -93,7 +86,7 @@ than the target. You can append `!` to force a resize to the exact target size, breaking the aspect ratio. -# Cropping +## Cropping `vipsthumbnail` normally shrinks images to fit within the box set by `--size`. You can use the `--smartcrop` option to crop to fill the box instead. Excess @@ -105,18 +98,18 @@ $ vipsthumbnail owl.jpg --smartcrop attention -s 128 Where `owl.jpg` is an off-centre composition: -![](owl.jpg) +![Owl](owl.jpg) Gives this result: -![](tn_owl.jpg) +![Smartcrop](tn_owl.jpg) First it shrinks the image to get the vertical axis to 128 pixels, then crops down to 128 pixels across using the `attention` strategy. This one searches -the image for features which might catch a human eye, see `vips_smartcrop()` -for details. +the image for features which might catch a human eye, see +[method@Image.smartcrop] for details. -# Linear light +## Linear light Shrinking images involves combining many pixels into one. Arithmetic averaging really ought to be in terms of the number of photons, but (for @@ -148,7 +141,7 @@ user 0m4.640s sys 0m0.016s ``` -# Output directory +## Output directory You set the thumbnail write parameters with the `-o` option. This is a pattern which the input filename is pasted into to @@ -184,7 +177,7 @@ $ vipsthumbnail fred.jpg ../jim.tif -o mythumbs/tn_%s.jpg Now both input files will have thumbnails written to a subdirectory of their current directory. -# Output format and options +## Output format and options You can use `-o` to specify the thumbnail image format too. For example: @@ -206,7 +199,7 @@ optimizer. Check the image write operations to see all the possible options. For example: -``` +```bash $ vips jpegsave save image to jpeg file usage: @@ -250,7 +243,7 @@ large saving. For example: -``` +```bash $ vipsthumbnail 42-32157534.jpg $ ls -l tn_42-32157534.jpg -rw-r–r– 1 john john 6682 Nov 12 21:27 tn_42-32157534.jpg @@ -258,13 +251,13 @@ $ ls -l tn_42-32157534.jpg `keep=none` almost halves the size of the thumbnail: -``` +```bash $ vipsthumbnail 42-32157534.jpg -o x.jpg[optimize_coding,keep=none] $ ls -l x.jpg -rw-r–r– 1 john john 3600 Nov 12 21:27 x.jpg ``` -# Colour management +## Colour management `vipsthumbnail` will optionally put images through LittleCMS for you. You can use this to move all thumbnails to the same colour space. All web browsers @@ -274,7 +267,7 @@ This can save several kb per thumbnail. For example: -``` +```bash $ vipsthumbnail shark.jpg $ ls -l tn_shark.jpg -rw-r–r– 1 john john 7295 Nov  9 14:33 tn_shark.jpg @@ -283,7 +276,7 @@ $ ls -l tn_shark.jpg Now transform to sRGB and don't attach a profile (you can also use `keep=none`, though that will remove *all* metadata from the image): -``` +```bash $ vipsthumbnail shark.jpg --export-profile srgb -o tn_shark.jpg[profile=none] $ ls -l tn_shark.jpg -rw-r–r– 1 john john 4229 Nov  9 14:33 tn_shark.jpg @@ -303,7 +296,7 @@ space, even though it has no embedded profile. $ vipsthumbnail kgdev.jpg --import-profile /my/profiles/a98.icm ``` -# Final suggestion +## Final suggestion Putting all this together, I suggest this as a sensible set of options: diff --git a/doc/version.xml.in b/doc/version.xml.in deleted file mode 100644 index 5c53e2937e..0000000000 --- a/doc/version.xml.in +++ /dev/null @@ -1 +0,0 @@ -@VIPS_VERSION@ \ No newline at end of file diff --git a/doc/vips.toml.in b/doc/vips.toml.in new file mode 100644 index 0000000000..7e608eff18 --- /dev/null +++ b/doc/vips.toml.in @@ -0,0 +1,79 @@ +[library] +name = "Vips" +version = "@VIPS_VERSION@" +browse_url = "https://github.com/libvips/libvips" +repository_url = "https://github.com/libvips/libvips.git" +website_url = "https://www.libvips.org" +docs_url = "https://www.libvips.org/API/@VIPS_VERSION@/" +authors = "libvips team and contributors" +license = "LGPL-2.1-or-later" +description = "The libvips image processing library" +search_index = true + +# List the dependencies using their GIR namespace +dependencies = ["GObject-2.0"] + + [dependencies."GObject-2.0"] + name = "GObject" + description = "The base type system library" + docs_url = "https://docs.gtk.org/gobject/" + +related = ["GObject-2.0"] + + [related."GObject-2.0"] + name = "GObject" + description = "The base type system library" + docs_url = "https://docs.gtk.org/gobject/" + +[theme] +name = "basic" +show_class_hierarchy = true +show_index_summary = true + +[source-location] +# The base URL for accessing a file in the repository +base_url = "https://github.com/libvips/libvips/blob/master/" + +[extra] +# The same order will be used when generating the index +content_files = [ + "using-the-cli.md", + "using-from-c.md", + "using-from-cplusplus.md", + "developer-checklist.md", + "using-threads.md", + "function-list.md", + "making-image-pyramids.md", + "multipage-and-animated-images.md", + "using-vipsthumbnail.md", + "how-it-works.md", + "how-it-opens-files.md", + "file-format.md", + "extending.md", + "binding.md", + "examples.md", + "cite.md", + + "libvips-arithmetic.md", + "libvips-header.md", +] +content_images = [ + "images/Combine.png", + "images/interconvert.png", + "images/Memtrace.png", + "images/owl.jpg", + "images/Sequence.png", + "images/Sink.png", + "images/tn_owl.jpg", + "images/Vips-smp.png", +] +content_base_url = "https://github.com/libvips/libvips/blob/master/doc/" +urlmap_file = "urlmap.js" + +[check] +ignore_deprecated = true + +# Hide the following types from the docs +[[object]] +name = "Token" +hidden = true diff --git a/libvips/arithmetic/add.c b/libvips/arithmetic/add.c index 64b2a4b250..604e3d385d 100644 --- a/libvips/arithmetic/add.c +++ b/libvips/arithmetic/add.c @@ -188,7 +188,7 @@ vips_add_init(VipsAdd *add) } /** - * vips_add: + * vips_add: (method) * @left: input image * @right: input image * @out: (out): output image diff --git a/libvips/arithmetic/arithmetic.c b/libvips/arithmetic/arithmetic.c index c51c90583c..814397d048 100644 --- a/libvips/arithmetic/arithmetic.c +++ b/libvips/arithmetic/arithmetic.c @@ -55,213 +55,6 @@ #include "parithmetic.h" -/** - * SECTION: arithmetic - * @short_description: pixel arithmetic, trig, log, statistics - * @stability: Stable - * @include: vips/vips.h - * - * These operations perform pixel arithmetic, that is, they perform an - * arithmetic operation, such as addition, on every pixel in an image or a - * pair of images. All (except in a few cases noted below) will work with - * images of any type or any mixture of types, of any size and of any number - * of bands. - * - * For binary operations, if the number of bands differs, one of the images - * must have one band. In this case, an n-band image is formed from the - * one-band image by joining n copies of the one-band image together, and then - * the two n-band images are operated upon. - * - * In the same way, for operations that take an array constant, such as - * vips_remainder_const(), you can mix single-element arrays or single-band - * images freely. - * - * Arithmetic operations try to preserve precision by increasing the number of - * bits in the output image when necessary. Generally, this follows the ANSI C - * conventions for type promotion, so multiplying two - * #VIPS_FORMAT_UCHAR images together, for example, produces a - * #VIPS_FORMAT_USHORT image, and taking the vips_cos() of a - * #VIPS_FORMAT_USHORT image produces #VIPS_FORMAT_FLOAT image. - * - * After processing, use vips_cast() and friends to take then format back down - * again. vips_cast_uchar(), for example, will cast any image down to 8-bit - * unsigned. - * - * Images have an *interpretation*: a meaning for the pixel values. With - * #VIPS_INTERPRETATION_sRGB, for example, the first three bands will be - * interpreted (for example, by a saver like vips_jpegsave()) as R, G and B, - * with values in 0 - 255, and any fourth band will be interpreted as an - * alpha channel. - * - * After arithmetic, you may wish to change the interpretation (for example to - * save as 16-bit PNG). Use vips_copy() to change the interpretation without - * changing pixels. - * - * For binary arithmetic operations, type promotion occurs in two stages. - * First, the two input images are cast up to the smallest common format, - * that is, the type with the smallest range that can represent the full - * range of both inputs. This conversion can be represented as a table: - * - * - * Codestin Search App - * - * - * - * @in2/@in1 - * uchar - * char - * ushort - * short - * uint - * int - * float - * double - * complex - * double complex - * - * - * - * - * uchar - * ushort - * short - * ushort - * short - * uint - * int - * float - * double - * complex - * double complex - * - * - * char - * short - * short - * short - * short - * int - * int - * float - * double - * complex - * double complex - * - * - * ushort - * ushort - * short - * ushort - * short - * uint - * int - * float - * double - * complex - * double complex - * - * - * short - * short - * short - * short - * short - * int - * int - * float - * double - * complex - * double complex - * - * - * uint - * uint - * int - * uint - * int - * uint - * int - * float - * double - * complex - * double complex - * - * - * int - * int - * int - * int - * int - * int - * int - * float - * double - * complex - * double complex - * - * - * float - * float - * float - * float - * float - * float - * float - * float - * double - * complex - * double complex - * - * - * double - * double - * double - * double - * double - * double - * double - * double - * double - * double complex - * double complex - * - * - * complex - * complex - * complex - * complex - * complex - * complex - * complex - * complex - * double complex - * complex - * double complex - * - * - * double complex - * double complex - * double complex - * double complex - * double complex - * double complex - * double complex - * double complex - * double complex - * double complex - * double complex - * - * - * - *
- * - * In the second stage, the operation is performed between the two identical - * types to form the output. The details vary between operations, but - * generally the principle is that the output type should be large enough to - * represent the whole range of possible values, except that int never becomes - * float. - */ - G_DEFINE_ABSTRACT_TYPE(VipsArithmetic, vips_arithmetic, VIPS_TYPE_OPERATION); /* Save a bit of typing. diff --git a/libvips/arithmetic/boolean.c b/libvips/arithmetic/boolean.c index 71315dc09f..166b6fac29 100644 --- a/libvips/arithmetic/boolean.c +++ b/libvips/arithmetic/boolean.c @@ -295,7 +295,7 @@ vips_booleanv(VipsImage *left, VipsImage *right, VipsImage **out, } /** - * vips_boolean: + * vips_boolean: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -339,7 +339,7 @@ vips_boolean(VipsImage *left, VipsImage *right, VipsImage **out, } /** - * vips_andimage: + * vips_andimage: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -365,7 +365,7 @@ vips_andimage(VipsImage *left, VipsImage *right, VipsImage **out, ...) } /** - * vips_orimage: + * vips_orimage: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -391,7 +391,7 @@ vips_orimage(VipsImage *left, VipsImage *right, VipsImage **out, ...) } /** - * vips_eorimage: + * vips_eorimage: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -417,7 +417,7 @@ vips_eorimage(VipsImage *left, VipsImage *right, VipsImage **out, ...) } /** - * vips_lshift: + * vips_lshift: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -443,7 +443,7 @@ vips_lshift(VipsImage *left, VipsImage *right, VipsImage **out, ...) } /** - * vips_rshift: + * vips_rshift: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage diff --git a/libvips/arithmetic/complex.c b/libvips/arithmetic/complex.c index fe62ee04fb..c2480ce7a1 100644 --- a/libvips/arithmetic/complex.c +++ b/libvips/arithmetic/complex.c @@ -556,7 +556,7 @@ vips_complex2v(VipsImage *left, VipsImage *right, VipsImage **out, } /** - * vips_complex2: + * vips_complex2: (method) * @left: input #VipsImage * @right: input #VipsImage * @out: (out): output #VipsImage @@ -585,7 +585,7 @@ vips_complex2(VipsImage *left, VipsImage *right, VipsImage **out, } /** - * vips_cross_phase: + * vips_cross_phase: (method) * @left: input #VipsImage * @right: input #VipsImage * @out: (out): output #VipsImage @@ -990,7 +990,7 @@ vips_complexform_init(VipsComplexform *complexform) } /** - * vips_complexform: + * vips_complexform: (method) * @left: input image * @right: input image * @out: (out): output image diff --git a/libvips/arithmetic/divide.c b/libvips/arithmetic/divide.c index 4ae781ebee..c2231daa7c 100644 --- a/libvips/arithmetic/divide.c +++ b/libvips/arithmetic/divide.c @@ -220,7 +220,7 @@ vips_divide_init(VipsDivide *divide) } /** - * vips_divide: + * vips_divide: (method) * @left: input image * @right: input image * @out: (out): output image diff --git a/libvips/arithmetic/math2.c b/libvips/arithmetic/math2.c index e139a1b371..8b29138779 100644 --- a/libvips/arithmetic/math2.c +++ b/libvips/arithmetic/math2.c @@ -258,7 +258,7 @@ vips_math2v(VipsImage *left, VipsImage *right, VipsImage **out, } /** - * vips_math2: + * vips_math2: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -305,7 +305,7 @@ vips_math2(VipsImage *left, VipsImage *right, VipsImage **out, } /** - * vips_pow: + * vips_pow: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -330,7 +330,7 @@ vips_pow(VipsImage *left, VipsImage *right, VipsImage **out, ...) } /** - * vips_wop: + * vips_wop: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -355,7 +355,7 @@ vips_wop(VipsImage *left, VipsImage *right, VipsImage **out, ...) } /** - * vips_atan2: + * vips_atan2: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage diff --git a/libvips/arithmetic/maxpair.c b/libvips/arithmetic/maxpair.c index 052068457c..26212b9904 100644 --- a/libvips/arithmetic/maxpair.c +++ b/libvips/arithmetic/maxpair.c @@ -161,7 +161,7 @@ vips_maxpair_init(VipsMaxpair *maxpair) } /** - * vips_maxpair: + * vips_maxpair: (method) * @left: input image * @right: input image * @out: (out): output image diff --git a/libvips/arithmetic/minpair.c b/libvips/arithmetic/minpair.c index a274efb159..ae5ff17e03 100644 --- a/libvips/arithmetic/minpair.c +++ b/libvips/arithmetic/minpair.c @@ -161,7 +161,7 @@ vips_minpair_init(VipsMinpair *minpair) } /** - * vips_minpair: + * vips_minpair: (method) * @left: input image * @right: input image * @out: (out): output image diff --git a/libvips/arithmetic/multiply.c b/libvips/arithmetic/multiply.c index 9c35bc1812..4f0fe1967c 100644 --- a/libvips/arithmetic/multiply.c +++ b/libvips/arithmetic/multiply.c @@ -205,7 +205,7 @@ vips_multiply_init(VipsMultiply *multiply) } /** - * vips_multiply: + * vips_multiply: (method) * @left: left-hand image * @right: right-hand image * @out: (out): output image diff --git a/libvips/arithmetic/relational.c b/libvips/arithmetic/relational.c index 4c28c55b64..c7e4f76675 100644 --- a/libvips/arithmetic/relational.c +++ b/libvips/arithmetic/relational.c @@ -265,7 +265,7 @@ vips_relationalv(VipsImage *left, VipsImage *right, VipsImage **out, } /** - * vips_relational: + * vips_relational: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -313,7 +313,7 @@ vips_relational(VipsImage *left, VipsImage *right, VipsImage **out, } /** - * vips_equal: + * vips_equal: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -339,7 +339,7 @@ vips_equal(VipsImage *left, VipsImage *right, VipsImage **out, ...) } /** - * vips_notequal: + * vips_notequal: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -365,7 +365,7 @@ vips_notequal(VipsImage *left, VipsImage *right, VipsImage **out, ...) } /** - * vips_more: + * vips_more: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -391,7 +391,7 @@ vips_more(VipsImage *left, VipsImage *right, VipsImage **out, ...) } /** - * vips_moreeq: + * vips_moreeq: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -417,7 +417,7 @@ vips_moreeq(VipsImage *left, VipsImage *right, VipsImage **out, ...) } /** - * vips_less: + * vips_less: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage @@ -443,7 +443,7 @@ vips_less(VipsImage *left, VipsImage *right, VipsImage **out, ...) } /** - * vips_lesseq: + * vips_lesseq: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage diff --git a/libvips/arithmetic/remainder.c b/libvips/arithmetic/remainder.c index 5d11effdcb..45f91d8f3d 100644 --- a/libvips/arithmetic/remainder.c +++ b/libvips/arithmetic/remainder.c @@ -204,7 +204,7 @@ vips_remainder_init(VipsRemainder *remainder) } /** - * vips_remainder: + * vips_remainder: (method) * @left: left-hand input #VipsImage * @right: right-hand input #VipsImage * @out: (out): output #VipsImage diff --git a/libvips/arithmetic/subtract.c b/libvips/arithmetic/subtract.c index 09e4a944e2..063f7d4468 100644 --- a/libvips/arithmetic/subtract.c +++ b/libvips/arithmetic/subtract.c @@ -184,7 +184,7 @@ vips_subtract_init(VipsSubtract *subtract) } /** - * vips_subtract: + * vips_subtract: (method) * @in1: input image * @in2: input image * @out: (out): output image diff --git a/libvips/colour/dE00.c b/libvips/colour/dE00.c index f5eca5072b..e5a8d5ba4a 100644 --- a/libvips/colour/dE00.c +++ b/libvips/colour/dE00.c @@ -247,7 +247,7 @@ vips_dE00_init(VipsdE00 *dE00) } /** - * vips_dE00: + * vips_dE00: (method) * @left: first input image * @right: second input image * @out: output image diff --git a/libvips/colour/dE76.c b/libvips/colour/dE76.c index 2027e4ce8a..b7c85d305c 100644 --- a/libvips/colour/dE76.c +++ b/libvips/colour/dE76.c @@ -124,7 +124,7 @@ vips_dE76_init(VipsdE76 *dE76) } /** - * vips_dE76: + * vips_dE76: (method) * @left: first input image * @right: second input image * @out: (out): output image diff --git a/libvips/colour/dECMC.c b/libvips/colour/dECMC.c index 5507b9ed1a..5a279bd758 100644 --- a/libvips/colour/dECMC.c +++ b/libvips/colour/dECMC.c @@ -72,7 +72,7 @@ vips_dECMC_init(VipsdECMC *dECMC) } /** - * vips_dECMC: + * vips_dECMC: (method) * @left: first input image * @right: second input image * @out: (out): output image diff --git a/libvips/conversion/bandjoin.c b/libvips/conversion/bandjoin.c index 511740a4c3..8150b038ab 100644 --- a/libvips/conversion/bandjoin.c +++ b/libvips/conversion/bandjoin.c @@ -264,7 +264,7 @@ vips_bandjoin(VipsImage **in, VipsImage **out, int n, ...) } /** - * vips_bandjoin2: + * vips_bandjoin2: (method) * @in1: first input image * @in2: second input image * @out: (out): output image diff --git a/libvips/conversion/embed.c b/libvips/conversion/embed.c index e779455f57..9f10486b77 100644 --- a/libvips/conversion/embed.c +++ b/libvips/conversion/embed.c @@ -822,7 +822,7 @@ vips_gravity_init(VipsGravity *gravity) } /** - * vips_gravity: + * vips_gravity: (method) * @in: input image * @out: output image * @direction: place @in at this direction in @out diff --git a/libvips/conversion/ifthenelse.c b/libvips/conversion/ifthenelse.c index b716330723..1b952dfcd2 100644 --- a/libvips/conversion/ifthenelse.c +++ b/libvips/conversion/ifthenelse.c @@ -557,7 +557,7 @@ vips_ifthenelse_init(VipsIfthenelse *ifthenelse) } /** - * vips_ifthenelse: + * vips_ifthenelse: (method) * @cond: condition #VipsImage * @in1: then #VipsImage * @in2: else #VipsImage diff --git a/libvips/conversion/join.c b/libvips/conversion/join.c index 5d6dd7c767..5a505827ea 100644 --- a/libvips/conversion/join.c +++ b/libvips/conversion/join.c @@ -290,7 +290,7 @@ vips_join_init(VipsJoin *join) } /** - * vips_join: + * vips_join: (method) * @in1: first input image * @in2: second input image * @out: (out): output image diff --git a/libvips/create/gaussnoise.c b/libvips/create/gaussnoise.c index 733a5b5ed1..7a94764462 100644 --- a/libvips/create/gaussnoise.c +++ b/libvips/create/gaussnoise.c @@ -64,6 +64,7 @@ #include #include +#include #include "pcreate.h" diff --git a/libvips/create/perlin.c b/libvips/create/perlin.c index eb7301bd8a..4435d6cb04 100644 --- a/libvips/create/perlin.c +++ b/libvips/create/perlin.c @@ -45,6 +45,7 @@ #include #include +#include #include "pcreate.h" diff --git a/libvips/create/worley.c b/libvips/create/worley.c index 2f9b6a7e99..c0877be78c 100644 --- a/libvips/create/worley.c +++ b/libvips/create/worley.c @@ -48,6 +48,7 @@ #include #include +#include #include "pcreate.h" diff --git a/libvips/deprecated/format.c b/libvips/deprecated/format.c index f67c203c20..191b12f803 100644 --- a/libvips/deprecated/format.c +++ b/libvips/deprecated/format.c @@ -327,7 +327,7 @@ format_for_file_sub(VipsFormatClass *format, } /** - * vips_format_for_file: + * vips_format_for_file: (skip) * @filename: file to find a format for * * Searches for a format you could use to load a file. @@ -378,7 +378,7 @@ format_for_name_sub(VipsFormatClass *format, const char *name) } /** - * vips_format_for_name: + * vips_format_for_name: (skip) * @filename: name to find a format for * * Searches for a format you could use to save a file. diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 34cc1aecce..a064b7989b 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -74,94 +74,97 @@ #include "pforeign.h" /** - * SECTION: foreign - * @short_description: load and save images in a variety of formats - * @stability: Stable - * @see_also: image - * @include: vips/vips.h - * @title: VipsForeign + * VipsForeign: * - * This set of operations load and save images in a variety of formats. + * An abstract base class to load and save images in a variety of formats. * - * # Load and save + * ## Load and save * * You can load and save from and to files, memory areas, and the libvips IO - * abstractions, #VipsSource and #VipsTarget. + * abstractions, [class@Source] and [class@Target]. * - * Use vips_foreign_find_load(), vips_foreign_find_load_buffer() and - * vips_foreign_find_load_source() to find a loader for an object. Use - * vips_foreign_find_save(), vips_foreign_find_save_buffer() and - * vips_foreign_find_save_target() to find a saver for a format. You can then - * run these operations using vips_call() and friends to perform the load or + * Use [func@Foreign.find_load] [func@Foreign.find_load_buffer] and + * [func@Foreign.find_load_source] to find a loader for an object. Use + * [func@Foreign.find_save], [func@Foreign.find_save_buffer] and + * [func@Foreign.find_save_target] to find a saver for a format. You can then + * run these operations using [func@call] and friends to perform the load or * save. * - * vips_image_write_to_file() and vips_image_new_from_file() and friends use + * [method@Image.write_to_file] and [ctor@Image.new_from_file] and friends use * these functions to automate file load and save. * * You can also invoke the operations directly, for example: * - * |[ + * ```c * vips_tiffsave(my_image, "frank.anything", * "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG, * NULL); - * ]| + * ``` * - * # Image metadata + * ## Image metadata * * All loaders attach all image metadata as libvips properties on load. * - * You can change metadata with vips_image_set_int() and friends. + * You can change metadata with [method@Image.set_int] and friends. * - * During save, you can use @keep to specify which metadata to retain, - * defaults to all, see #VipsForeignKeep. Setting @profile will + * During save, you can use `keep` to specify which metadata to retain, + * defaults to all, see [flags@ForeignKeep]. Setting `profile` will * automatically keep the ICC profile. * - * # Many page images + * ## Many page images * * By default, libvips will only load the first page of many page or animated - * images. Use @page and @n to set the start page and the number of pages to - * load. Set @n to -1 to load all pages. + * images. Use `page` and `n` to set the start page and the number of pages to + * load. Set `n` to -1 to load all pages. * * Many page images are loaded as a tall, thin strip of pages. * - * Use vips_image_get_page_height() and vips_image_get_n_pages() to find the - * page height and number of pages of a loaded image. + * Use [method@Image.get_page_height] and [method@Image.get_n_pages] to find + * the page height and number of pages of a loaded image. * - * Use @page_height to set the page height for image save. + * Use `page_height` to set the page height for image save. * - * # Alpha save + * ## Alpha save * * Not all image formats support alpha. If you try to save an image with an * alpha channel to a format that does not support it, the alpha will be - * automatically flattened out. Use @background (default 0) to set the colour + * automatically flattened out. Use `background` (default 0) to set the colour * that alpha should be flattened against. * - * # Adding new formats + * ## Adding new formats * * To add support for a new file format to vips, simply define a new subclass - * of #VipsForeignLoad or #VipsForeignSave. + * of [class@ForeignLoad] or [class@ForeignSave]. * - * If you define a new operation which is a subclass of #VipsForeign, support - * for it automatically appears in all VIPS user-interfaces. It will also be - * transparently supported by vips_image_new_from_file() and friends. + * If you define a new operation which is a subclass of [class@Foreign], + * support for it automatically appears in all libvips user-interfaces. It + * will also be transparently supported by [ctor@Image.new_from_file] and + * friends. + */ + +/** + * VipsForeignLoad: + * + * An abstract base class to load images in a variety of formats. * * ## Writing a new loader * - * Add a new loader to VIPS by subclassing #VipsForeignLoad. Subclasses need to - * implement at least @header(). + * Add a new loader to libvips by subclassing [class@ForeignLoad]. Subclasses + * need to implement at least [vfunc@ForeignLoad.header]. * - * @header() must set at least the header fields of @out. @load(), if defined, - * must load the pixels to @real. + * [vfunc@ForeignLoad.header] must set at least the header fields of `out`. + * [vfunc@ForeignLoad.load], if defined, must load the pixels to `real`. * * The suffix list is used to select a format to save a file in, and to pick a - * loader if you don't define is_a(). + * loader if you don't define [func@Foreign.is_a]. * - * You should also define @nickname and @description in #VipsObject. + * You should also define [property@VipsObject:nickname] and + * [property@VipsObject:description] in [class@Object]. * * As a complete example, here's code for a PNG loader, minus the actual * calls to libpng. * - * |[ + * ```c * typedef struct _VipsForeignLoadPng { * VipsForeignLoad parent_object; * @@ -252,17 +255,23 @@ * vips_foreign_load_png_init(VipsForeignLoadPng *png) * { * } - * ]| + * ``` + */ + +/** + * VipsForeignSave: + * + * An abstract base class to save images in a variety of formats. * * ## Writing a new saver * - * Call your saver in the class' @build() method after chaining up. The - * prepared image should be ready for you to save in @ready. + * Call your saver in the class' [vfunc@Object.build] method after chaining up. + * The prepared image should be ready for you to save in `ready`. * * As a complete example, here's the code for the CSV saver, minus the calls * to the actual save routines. * - * |[ + * ```c * typedef struct _VipsForeignSaveCsv { * VipsForeignSave parent_object; * @@ -332,7 +341,7 @@ * { * csv->separator = g_strdup("\t"); * } - * ]| + * ``` */ /* Use this to link images to the load operation that made them. diff --git a/libvips/freqfilt/phasecor.c b/libvips/freqfilt/phasecor.c index 6671425a80..f84ef35ea6 100644 --- a/libvips/freqfilt/phasecor.c +++ b/libvips/freqfilt/phasecor.c @@ -120,7 +120,7 @@ vips_phasecor_init(VipsPhasecor *phasecor) } /** - * vips_phasecor: + * vips_phasecor: (method) * @in1: first input image * @in2: second input image * @out: (out): output image diff --git a/libvips/include/vips/basic.h b/libvips/include/vips/basic.h index e229f3ddf1..e74deb48df 100644 --- a/libvips/include/vips/basic.h +++ b/libvips/include/vips/basic.h @@ -100,6 +100,8 @@ typedef enum { VIPS_PRECISION_LAST } VipsPrecision; +#ifndef __GI_SCANNER__ + /* Just for testing. */ VIPS_API @@ -107,6 +109,8 @@ char *vips_path_filename7(const char *path); VIPS_API char *vips_path_mode7(const char *path); +#endif /* !__GI_SCANNER__ */ + struct _VipsImage; typedef struct _VipsImage VipsImage; struct _VipsRegion; diff --git a/libvips/include/vips/buf.h b/libvips/include/vips/buf.h index 3951369163..fece94f8dd 100644 --- a/libvips/include/vips/buf.h +++ b/libvips/include/vips/buf.h @@ -39,11 +39,6 @@ extern "C" { #endif /*__cplusplus*/ -/* A string in the process of being written to ... multiple calls to - * vips_buf_append add to it. On overflow append "..." and block further - * writes. - */ - struct _VipsBuf { /* All fields are private. */ diff --git a/libvips/include/vips/connection.h b/libvips/include/vips/connection.h index ef4995b6ea..ea3b21e9bc 100644 --- a/libvips/include/vips/connection.h +++ b/libvips/include/vips/connection.h @@ -58,8 +58,6 @@ extern "C" { (G_TYPE_INSTANCE_GET_CLASS((obj), \ VIPS_TYPE_CONNECTION, VipsConnectionClass)) -/* Communicate with something like a socket or pipe. - */ typedef struct _VipsConnection { VipsObject parent_object; @@ -116,13 +114,6 @@ void vips_pipe_read_limit_set(gint64 limit); (G_TYPE_INSTANCE_GET_CLASS((obj), \ VIPS_TYPE_SOURCE, VipsSourceClass)) -/* Read from something like a socket, file or memory area and present the data - * with a unified seek / read / map interface. - * - * During the header phase, we save data from unseekable sources in a buffer - * so readers can rewind and read again. We don't buffer data during the - * decode stage. - */ struct _VipsSource { VipsConnection parent_object; @@ -199,7 +190,7 @@ typedef struct _VipsSourceClass { * We must return gint64, since ssize_t is often defined as unsigned * on Windows. */ - gint64 (*read)(VipsSource *, void *, size_t); + gint64 (*read)(VipsSource *source, void *buffer, size_t length); /* Seek to a certain position, args exactly as lseek(2). Set errno on * error. @@ -210,7 +201,7 @@ typedef struct _VipsSourceClass { * We have to use int64 rather than off_t, since we must work on * Windows, where off_t can be 32-bits. */ - gint64 (*seek)(VipsSource *, gint64, int); + gint64 (*seek)(VipsSource *source, gint64 offset, int whence); } VipsSourceClass; @@ -226,7 +217,7 @@ VipsSource *vips_source_new_from_blob(VipsBlob *blob); VIPS_API VipsSource *vips_source_new_from_target(VipsTarget *target); VIPS_API -VipsSource *vips_source_new_from_memory(const void *data, size_t size); +VipsSource *vips_source_new_from_memory(const void *data, size_t length); VIPS_API VipsSource *vips_source_new_from_options(const char *options); @@ -237,7 +228,7 @@ int vips_source_unminimise(VipsSource *source); VIPS_API int vips_source_decode(VipsSource *source); VIPS_API -gint64 vips_source_read(VipsSource *source, void *data, size_t length); +gint64 vips_source_read(VipsSource *source, void *buffer, size_t length); VIPS_API gboolean vips_source_is_mappable(VipsSource *source); VIPS_API @@ -273,9 +264,6 @@ gint64 vips_source_length(VipsSource *source); (G_TYPE_INSTANCE_GET_CLASS((obj), \ VIPS_TYPE_SOURCE_CUSTOM, VipsSourceCustomClass)) -/* Subclass of source_custom with signals for handlers. This is supposed to be - * useful for language bindings. - */ typedef struct _VipsSourceCustom { VipsSource parent_object; @@ -288,8 +276,8 @@ typedef struct _VipsSourceCustomClass { * We must use gint64 everywhere since there's no G_TYPE_SIZE. */ - gint64 (*read)(VipsSourceCustom *, void *, gint64); - gint64 (*seek)(VipsSourceCustom *, gint64, int); + gint64 (*read)(VipsSourceCustom *source, void *buffer, gint64 length); + gint64 (*seek)(VipsSourceCustom *source, gint64 offset, int whence); } VipsSourceCustomClass; @@ -355,6 +343,10 @@ GInputStream *vips_g_input_stream_new_from_source(VipsSource *source); (G_TYPE_INSTANCE_GET_CLASS((obj), \ VIPS_TYPE_SOURCE_G_INPUT_STREAM, VipsSourceGInputStreamClass)) +/** + * VipsSourceGInputStream: (copy-func g_object_ref) + * (free-func g_object_unref) + */ typedef struct _VipsSourceGInputStream { VipsSource parent_instance; @@ -396,8 +388,6 @@ VipsSourceGInputStream *vips_source_g_input_stream_new(GInputStream *stream); */ #define VIPS_TARGET_BUFFER_SIZE (8500) -/* Output to something like a socket, pipe or memory area. - */ struct _VipsTarget { VipsConnection parent_object; @@ -448,11 +438,11 @@ typedef struct _VipsTargetClass { * We must return gint64, since ssize_t is often defined as unsigned * on Windows. */ - gint64 (*write)(VipsTarget *, const void *, size_t); + gint64 (*write)(VipsTarget *target, const void *data, size_t length); /* Deprecated in favour of ::end. */ - void (*finish)(VipsTarget *); + void (*finish)(VipsTarget *target); /* libtiff needs to be able to seek and read on targets, * unfortunately. @@ -466,19 +456,19 @@ typedef struct _VipsTargetClass { * We must return gint64, since ssize_t is often defined as unsigned * on Windows. */ - gint64 (*read)(VipsTarget *, void *, size_t); + gint64 (*read)(VipsTarget *target, void *buffer, size_t length); /* Seek output. Args exactly as lseek(2). * * We have to use int64 rather than off_t, since we must work on * Windows, where off_t can be 32-bits. */ - gint64 (*seek)(VipsTarget *, gint64 offset, int whence); + gint64 (*seek)(VipsTarget *target, gint64 offset, int whence); /* Output has been generated, so do any clearing up, * eg. copy the bytes we saved in memory to the target blob. */ - int (*end)(VipsTarget *); + int (*end)(VipsTarget *target); } VipsTargetClass; @@ -492,7 +482,7 @@ VipsTarget *vips_target_new_to_file(const char *filename); VIPS_API VipsTarget *vips_target_new_to_memory(void); VIPS_API -VipsTarget *vips_target_new_temp(VipsTarget *target); +VipsTarget *vips_target_new_temp(VipsTarget *based_on); VIPS_API int vips_target_write(VipsTarget *target, const void *data, size_t length); VIPS_API @@ -537,8 +527,6 @@ int vips_target_write_amp(VipsTarget *target, const char *str); #define VIPS_TARGET_CUSTOM_BUFFER_SIZE (4096) -/* Output to something like a socket, pipe or memory area. - */ typedef struct _VipsTargetCustom { VipsTarget parent_object; @@ -551,11 +539,11 @@ typedef struct _VipsTargetCustomClass { * We must use gint64 everywhere since there's no G_TYPE_SIZE. */ - gint64 (*write)(VipsTargetCustom *, const void *, gint64); - void (*finish)(VipsTargetCustom *); - gint64 (*read)(VipsTargetCustom *, void *, gint64); - gint64 (*seek)(VipsTargetCustom *, gint64, int); - int (*end)(VipsTargetCustom *); + gint64 (*write)(VipsTargetCustom *target, const void *data, gint64 length); + void (*finish)(VipsTargetCustom *target); + gint64 (*read)(VipsTargetCustom *target, void *buffer, gint64 length); + gint64 (*seek)(VipsTargetCustom *target, gint64 offset, int whence); + int (*end)(VipsTargetCustom *target); } VipsTargetCustomClass; diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index 6ea2addd8f..51d8086e0a 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -82,8 +82,6 @@ typedef struct _VipsForeignClass { } VipsForeignClass; -/* Don't put spaces around void here, it breaks gtk-doc. - */ VIPS_API GType vips_foreign_get_type(void); @@ -270,8 +268,6 @@ typedef struct _VipsForeignLoadClass { int (*load)(VipsForeignLoad *load); } VipsForeignLoadClass; -/* Don't put spaces around void here, it breaks gtk-doc. - */ VIPS_API GType vips_foreign_load_get_type(void); @@ -427,8 +423,6 @@ typedef struct _VipsForeignSaveClass { gboolean coding[VIPS_CODING_LAST]; } VipsForeignSaveClass; -/* Don't put spaces around void here, it breaks gtk-doc. - */ VIPS_API GType vips_foreign_save_get_type(void); diff --git a/libvips/include/vips/format.h b/libvips/include/vips/format.h index 9f52a16e06..37aeb729ec 100644 --- a/libvips/include/vips/format.h +++ b/libvips/include/vips/format.h @@ -76,23 +76,23 @@ typedef struct _VipsFormatClass { /* Is a file in this format. */ - gboolean (*is_a)(const char *); + gboolean (*is_a)(const char *filename); /* Read just the header into the VipsImage. */ - int (*header)(const char *, VipsImage *); + int (*header)(const char *filename, VipsImage *image); /* Load the whole image. */ - int (*load)(const char *, VipsImage *); + int (*load)(const char *filename, VipsImage *image); /* Write the VipsImage to the file in this format. */ - int (*save)(VipsImage *, const char *); + int (*save)(VipsImage *image, const char *filename); /* Get the flags for this file in this format. */ - VipsFormatFlags (*get_flags)(const char *); + VipsFormatFlags (*get_flags)(const char *filename); /* Loop over formats in this order, default 0. We need this because * some formats can be read by several loaders (eg. tiff can be read diff --git a/libvips/include/vips/gate.h b/libvips/include/vips/gate.h index 2b53e22b07..57e179ab22 100644 --- a/libvips/include/vips/gate.h +++ b/libvips/include/vips/gate.h @@ -69,20 +69,9 @@ extern "C" { } \ G_STMT_END -extern gboolean vips__thread_profile; - VIPS_API void vips_profile_set(gboolean profile); -void vips__thread_profile_attach(const char *thread_name); -void vips__thread_profile_detach(void); -void vips__thread_profile_stop(void); - -void vips__thread_gate_start(const char *gate_name); -void vips__thread_gate_stop(const char *gate_name); - -void vips__thread_malloc_free(gint64 size); - #endif /*VIPS_GATE_H*/ #ifdef __cplusplus diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index cdfe578cc3..2454275faa 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -367,8 +367,6 @@ typedef struct _VipsImageClass { } VipsImageClass; -/* Don't put spaces around void here, it breaks gtk-doc. - */ VIPS_API GType vips_image_get_type(void); diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 74e08093dd..88f0dbfec3 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -107,6 +107,10 @@ int vips__exif_update(VipsImage *image); void vips_check_init(void); +/* Set from the command-line. + */ +extern gboolean vips__vector_enabled; + void vips__vector_init(void); void vips__meta_init_types(void); @@ -151,6 +155,13 @@ extern gboolean vips__cache_trace; void vips__thread_init(void); void vips__threadpool_init(void); void vips__threadpool_shutdown(void); + +typedef struct _VipsThreadset VipsThreadset; +VipsThreadset *vips_threadset_new(int max_threads); +int vips_threadset_run(VipsThreadset *set, + const char *domain, GFunc func, gpointer data); +void vips_threadset_free(VipsThreadset *set); + VIPS_API void vips__worker_lock(GMutex *mutex); VIPS_API void vips__worker_cond_wait(GCond *cond, GMutex *mutex); @@ -351,6 +362,10 @@ VipsWindow *vips_window_take(VipsWindow *window, int vips__profile_set(VipsImage *image, const char *name); +void vips__thread_profile_attach(const char *thread_name); +void vips__thread_profile_detach(void); +void vips__thread_profile_stop(void); + int vips__lrmosaic(VipsImage *ref, VipsImage *sec, VipsImage *out, int bandno, int xref, int yref, int xsec, int ysec, @@ -370,6 +385,46 @@ int vips__correl(VipsImage *ref, VipsImage *sec, unsigned int vips_operation_hash(VipsOperation *operation); +int vips__open_read(const char *filename); +FILE *vips__fopen(const char *filename, const char *mode); + +char *vips__file_read_name(const char *name, const char *fallback_dir, + size_t *length_out); +int vips__file_write(void *data, size_t size, size_t nmemb, FILE *stream); + +int vips__fgetc(FILE *fp); + +GValue *vips__gvalue_ref_string_new(const char *text); +void vips__gslist_gvalue_free(GSList *list); +GSList *vips__gslist_gvalue_copy(const GSList *list); +GSList *vips__gslist_gvalue_merge(GSList *a, const GSList *b); +char *vips__gslist_gvalue_get(const GSList *list); + +gint64 vips__seek_no_error(int fd, gint64 pos, int whence); + +int vips__ftruncate(int fd, gint64 pos); + +const char *vips__token_must(const char *buffer, VipsToken *token, + char *string, int size); +const char *vips__token_need(const char *buffer, VipsToken need_token, + char *string, int size); +const char *vips__token_segment(const char *p, VipsToken *token, + char *string, int size); +const char *vips__token_segment_need(const char *p, VipsToken need_token, + char *string, int size); +const char *vips__find_rightmost_brackets(const char *p); + +void vips__change_suffix(const char *name, char *out, int mx, + const char *new_suff, const char **olds, int nolds); + +guint32 vips__random(guint32 seed); +guint32 vips__random_add(guint32 seed, int value); + +const char *vips__icc_dir(void); +const char *vips__windows_prefix(void); + +char *vips__get_iso8601(void); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/interpolate.h b/libvips/include/vips/interpolate.h index 18ffa7a34b..6695eea89e 100644 --- a/libvips/include/vips/interpolate.h +++ b/libvips/include/vips/interpolate.h @@ -91,8 +91,6 @@ typedef struct _VipsInterpolateClass { int window_offset; } VipsInterpolateClass; -/* Don't put spaces around void here, it breaks gtk-doc. - */ VIPS_API GType vips_interpolate_get_type(void); VIPS_API diff --git a/libvips/include/vips/memory.h b/libvips/include/vips/memory.h index 4f75cc5a27..93e669340b 100644 --- a/libvips/include/vips/memory.h +++ b/libvips/include/vips/memory.h @@ -71,6 +71,8 @@ extern "C" { #define VIPS_ARRAY(OBJ, N, T) \ ((T *) VIPS_MALLOC(OBJ, (N) * sizeof(T))) +#ifndef __GI_SCANNER__ + G_DEFINE_AUTOPTR_CLEANUP_FUNC(VipsImage, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(VipsObject, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(VipsRegion, g_object_unref) @@ -89,6 +91,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(VipsOperation, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(VipsArrayDouble, VipsArrayDouble_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(VipsArrayImage, VipsArrayImage_unref) +#endif /* !__GI_SCANNER__ */ + VIPS_API void *vips_malloc(VipsObject *object, size_t size); VIPS_API diff --git a/libvips/include/vips/meson.build b/libvips/include/vips/meson.build index 17bf777c79..217a5ea7a9 100644 --- a/libvips/include/vips/meson.build +++ b/libvips/include/vips/meson.build @@ -1,19 +1,9 @@ +# Headers that we install but neither introspect nor document. public_other_headers = files( - 'buf.h', - 'connection.h', - 'dbuf.h', 'debug.h', 'format.h', - 'gate.h', - 'generate.h', 'private.h', - 'sbuf.h', - 'semaphore.h', - 'thread.h', - 'threadpool.h', 'transform.h', - 'util.h', - 'vector.h', ) public_deprecated_headers = files( @@ -33,14 +23,19 @@ endif public_headers = files( 'arithmetic.h', 'basic.h', + 'buf.h', 'colour.h', + 'connection.h', 'conversion.h', 'convolution.h', 'create.h', + 'dbuf.h', 'draw.h', 'error.h', 'foreign.h', 'freqfilt.h', + 'gate.h', + 'generate.h', 'header.h', 'histogram.h', 'image.h', @@ -53,7 +48,13 @@ public_headers = files( 'rect.h', 'region.h', 'resample.h', + 'sbuf.h', + 'semaphore.h', + 'thread.h', + 'threadpool.h', 'type.h', + 'util.h', + 'vector.h', 'vips.h', ) @@ -94,8 +95,8 @@ enumtypes = gnome.mkenums( vips_verbose_config = [] foreach _, section : build_summary foreach key, arr : section - if key.contains('gtk-doc') or \ - key.contains('doxygen') or \ + if key.contains('docs') or \ + key.contains('cpp-docs') or \ key.contains('introspection') or \ key.contains('examples') continue diff --git a/libvips/include/vips/object.h b/libvips/include/vips/object.h index 0c4cbddf04..368f0b2a63 100644 --- a/libvips/include/vips/object.h +++ b/libvips/include/vips/object.h @@ -137,8 +137,7 @@ typedef enum /*< flags >*/ { #define VIPS_ARG_INTERPOLATE(CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET) \ VIPS_ARG_OBJECT(CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, VIPS_TYPE_INTERPOLATE) -#define VIPS_ARG_BOOL(CLASS, NAME, PRIORITY, LONG, DESC, \ - FLAGS, OFFSET, VALUE) \ +#define VIPS_ARG_BOOL(CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, VALUE) \ { \ GParamSpec *pspec; \ \ @@ -151,8 +150,7 @@ typedef enum /*< flags >*/ { pspec, (VipsArgumentFlags) (FLAGS), (PRIORITY), (OFFSET)); \ } -#define VIPS_ARG_DOUBLE(CLASS, NAME, PRIORITY, LONG, DESC, \ - FLAGS, OFFSET, MIN, MAX, VALUE) \ +#define VIPS_ARG_DOUBLE(CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, MIN, MAX, VALUE) \ { \ GParamSpec *pspec; \ \ @@ -165,8 +163,7 @@ typedef enum /*< flags >*/ { pspec, (VipsArgumentFlags) (FLAGS), (PRIORITY), (OFFSET)); \ } -#define VIPS_ARG_BOXED(CLASS, NAME, PRIORITY, LONG, DESC, \ - FLAGS, OFFSET, TYPE) \ +#define VIPS_ARG_BOXED(CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, TYPE) \ { \ GParamSpec *pspec; \ \ @@ -179,8 +176,7 @@ typedef enum /*< flags >*/ { pspec, (VipsArgumentFlags) (FLAGS), (PRIORITY), (OFFSET)); \ } -#define VIPS_ARG_INT(CLASS, NAME, PRIORITY, LONG, DESC, \ - FLAGS, OFFSET, MIN, MAX, VALUE) \ +#define VIPS_ARG_INT(CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, MIN, MAX, VALUE) \ { \ GParamSpec *pspec; \ \ @@ -193,8 +189,7 @@ typedef enum /*< flags >*/ { pspec, (VipsArgumentFlags) (FLAGS), (PRIORITY), (OFFSET)); \ } -#define VIPS_ARG_UINT64(CLASS, NAME, PRIORITY, LONG, DESC, \ - FLAGS, OFFSET, MIN, MAX, VALUE) \ +#define VIPS_ARG_UINT64(CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, MIN, MAX, VALUE) \ { \ GParamSpec *pspec; \ \ @@ -207,8 +202,7 @@ typedef enum /*< flags >*/ { pspec, (VipsArgumentFlags) (FLAGS), (PRIORITY), (OFFSET)); \ } -#define VIPS_ARG_ENUM(CLASS, NAME, PRIORITY, LONG, DESC, \ - FLAGS, OFFSET, TYPE, VALUE) \ +#define VIPS_ARG_ENUM(CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, TYPE, VALUE) \ { \ GParamSpec *pspec; \ \ @@ -221,8 +215,7 @@ typedef enum /*< flags >*/ { pspec, (VipsArgumentFlags) (FLAGS), (PRIORITY), (OFFSET)); \ } -#define VIPS_ARG_FLAGS(CLASS, NAME, PRIORITY, LONG, DESC, \ - FLAGS, OFFSET, TYPE, VALUE) \ +#define VIPS_ARG_FLAGS(CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, TYPE, VALUE) \ { \ GParamSpec *pspec; \ \ @@ -235,8 +228,7 @@ typedef enum /*< flags >*/ { pspec, (VipsArgumentFlags) (FLAGS), (PRIORITY), (OFFSET)); \ } -#define VIPS_ARG_STRING(CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, \ - VALUE) \ +#define VIPS_ARG_STRING(CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, VALUE) \ { \ GParamSpec *pspec; \ \ @@ -318,8 +310,14 @@ typedef GHashTable VipsArgumentTable; VIPS_API int vips_argument_get_id(void); + +#ifndef __GI_SCANNER__ + void vips__object_set_member(VipsObject *object, GParamSpec *pspec, GObject **member, GObject *argument); + +#endif /* !__GI_SCANNER__ */ + typedef void *(*VipsArgumentMapFn)(VipsObject *object, GParamSpec *pspec, VipsArgumentClass *argument_class, VipsArgumentInstance *argument_instance, void *a, void *b); @@ -626,8 +624,6 @@ void vips_object_print_name(VipsObject *object); VIPS_API gboolean vips_object_sanity(VipsObject *object); -/* Don't put spaces around void here, it breaks gtk-doc. - */ VIPS_API GType vips_object_get_type(void); diff --git a/libvips/include/vips/operation.h b/libvips/include/vips/operation.h index 7384a4eede..8e115f0ca6 100644 --- a/libvips/include/vips/operation.h +++ b/libvips/include/vips/operation.h @@ -100,8 +100,6 @@ typedef struct _VipsOperationClass { void (*invalidate)(VipsOperation *operation); } VipsOperationClass; -/* Don't put spaces around void here, it breaks gtk-doc. - */ VIPS_API GType vips_operation_get_type(void); diff --git a/libvips/include/vips/private.h b/libvips/include/vips/private.h index c6f2bc5fa6..19cbf15f42 100644 --- a/libvips/include/vips/private.h +++ b/libvips/include/vips/private.h @@ -40,6 +40,8 @@ extern "C" { #endif /*__cplusplus*/ +#include + #define VIPS_SPARE (8) /* Private to iofuncs: the minimum number of scanlines we add above and below @@ -225,6 +227,54 @@ void VipsArrayDouble_unref(VipsArrayDouble *array); VIPS_API void VipsArrayImage_unref(VipsArrayImage *array); +extern gboolean vips__thread_profile; + +void vips__thread_gate_start(const char *gate_name); +void vips__thread_gate_stop(const char *gate_name); + +void vips__thread_malloc_free(gint64 size); + +FILE *vips__file_open_read(const char *filename, + const char *fallback_dir, gboolean text_mode); +FILE *vips__file_open_write(const char *filename, + gboolean text_mode); + +/* TODO(kleisauke): VIPS_API is required by vipsedit. + */ +VIPS_API +int vips__write(int fd, const void *buf, size_t count); + +/* TODO(kleisauke): VIPS_API is required by test_connections. + */ +VIPS_API +int vips__open(const char *filename, int flags, int mode); + +/* TODO(kleisauke): VIPS_API is required by vipsedit. + */ +VIPS_API +char *vips__file_read(FILE *fp, const char *name, size_t *length_out); + +/* TODO(kleisauke): VIPS_API is required by the magick module. + */ +VIPS_API +gint64 vips__get_bytes(const char *filename, unsigned char buf[], gint64 len); + +/* TODO(kleisauke): VIPS_API is required by vipsedit. + */ +VIPS_API +gint64 vips__seek(int fd, gint64 pos, int whence); + +/* TODO(kleisauke): VIPS_API is required by libvips-cpp and vipsheader. + */ +VIPS_API +void vips__filename_split8(const char *name, + char *filename, char *option_string); + +/* TODO(kleisauke): VIPS_API is required by jpegsave_file_fuzzer. + */ +VIPS_API +char *vips__temp_name(const char *format); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/region.h b/libvips/include/vips/region.h index 7e4c7c1048..d7f06c5746 100644 --- a/libvips/include/vips/region.h +++ b/libvips/include/vips/region.h @@ -128,8 +128,6 @@ typedef struct _VipsRegionClass { } VipsRegionClass; -/* Don't put spaces around void here, it breaks gtk-doc. - */ VIPS_API GType vips_region_get_type(void); diff --git a/libvips/include/vips/thread.h b/libvips/include/vips/thread.h index cb40d66d65..3670c83001 100644 --- a/libvips/include/vips/thread.h +++ b/libvips/include/vips/thread.h @@ -36,10 +36,8 @@ extern "C" { #endif /*__cplusplus*/ -/* Wrapper for g_thread_try_new(). - */ VIPS_API -GThread *vips_g_thread_new(const char *, GThreadFunc, gpointer); +GThread *vips_g_thread_new(const char *domain, GThreadFunc func, gpointer data); VIPS_API gboolean vips_thread_isvips(void); @@ -47,12 +45,6 @@ gboolean vips_thread_isvips(void); VIPS_API int vips_thread_execute(const char *domain, GFunc func, gpointer data); -typedef struct _VipsThreadset VipsThreadset; -VipsThreadset *vips_threadset_new(int max_threads); -int vips_threadset_run(VipsThreadset *set, - const char *domain, GFunc func, gpointer data); -void vips_threadset_free(VipsThreadset *set); - #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/threadpool.h b/libvips/include/vips/threadpool.h index 77230f3128..9f31bb17ed 100644 --- a/libvips/include/vips/threadpool.h +++ b/libvips/include/vips/threadpool.h @@ -51,10 +51,6 @@ extern "C" { #endif /*__cplusplus*/ -/* Per-thread state. Allocate functions can use these members to - * communicate with work functions. - */ - #define VIPS_TYPE_THREAD_STATE (vips_thread_state_get_type()) #define VIPS_THREAD_STATE(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj), \ @@ -112,8 +108,6 @@ typedef struct _VipsThreadStateClass { VIPS_API void *vips_thread_state_set(VipsObject *object, void *a, void *b); -/* Don't put spaces around void here, it breaks gtk-doc. - */ VIPS_API GType vips_thread_state_get_type(void); diff --git a/libvips/include/vips/type.h b/libvips/include/vips/type.h index be74cf6f89..8e5968c7d0 100644 --- a/libvips/include/vips/type.h +++ b/libvips/include/vips/type.h @@ -38,6 +38,8 @@ extern "C" { #endif /*__cplusplus*/ +#ifndef __GI_SCANNER__ + /* A very simple boxed type for testing. Just holds an int. */ typedef struct _VipsThing { @@ -55,6 +57,8 @@ GType vips_thing_get_type(void); VIPS_API VipsThing *vips_thing_new(int i); +#endif /* !__GI_SCANNER__ */ + /* A ref-counted area of memory. Can hold arrays of things as well. */ typedef struct _VipsArea { diff --git a/libvips/include/vips/util.h b/libvips/include/vips/util.h index a91b065c92..82f619bca3 100644 --- a/libvips/include/vips/util.h +++ b/libvips/include/vips/util.h @@ -39,7 +39,6 @@ extern "C" { #endif /*__cplusplus*/ -#include #include /* Some platforms don't have M_PI :-( @@ -285,47 +284,7 @@ int vips_filename_suffix_match(const char *path, const char *suffixes[]); VIPS_API gint64 vips_file_length(int fd); -/* TODO(kleisauke): VIPS_API is required by vipsedit. - */ -VIPS_API -int vips__write(int fd, const void *buf, size_t count); - -/* TODO(kleisauke): VIPS_API is required by test_connections. - */ -VIPS_API -int vips__open(const char *filename, int flags, int mode); -int vips__open_read(const char *filename); -FILE *vips__fopen(const char *filename, const char *mode); - -FILE *vips__file_open_read(const char *filename, - const char *fallback_dir, gboolean text_mode); -FILE *vips__file_open_write(const char *filename, - gboolean text_mode); -/* TODO(kleisauke): VIPS_API is required by vipsedit. - */ -VIPS_API -char *vips__file_read(FILE *fp, const char *name, size_t *length_out); -char *vips__file_read_name(const char *name, const char *fallback_dir, - size_t *length_out); -int vips__file_write(void *data, size_t size, size_t nmemb, FILE *stream); -/* TODO(kleisauke): VIPS_API is required by the magick module. - */ -VIPS_API -gint64 vips__get_bytes(const char *filename, unsigned char buf[], gint64 len); -int vips__fgetc(FILE *fp); -GValue *vips__gvalue_ref_string_new(const char *text); -void vips__gslist_gvalue_free(GSList *list); -GSList *vips__gslist_gvalue_copy(const GSList *list); -GSList *vips__gslist_gvalue_merge(GSList *a, const GSList *b); -char *vips__gslist_gvalue_get(const GSList *list); - -gint64 vips__seek_no_error(int fd, gint64 pos, int whence); -/* TODO(kleisauke): VIPS_API is required by vipsedit. - */ -VIPS_API -gint64 vips__seek(int fd, gint64 pos, int whence); -int vips__ftruncate(int fd, gint64 pos); VIPS_API int vips_existsf(const char *name, ...) G_GNUC_PRINTF(1, 2); @@ -342,7 +301,7 @@ VIPS_API int vips_rename(const char *old_name, const char *new_name); /** - * VipsToken: + * VipsToken: (skip) * @VIPS_TOKEN_LEFT: left bracket * @VIPS_TOKEN_RIGHT: right bracket * @VIPS_TOKEN_STRING: string constant @@ -356,7 +315,6 @@ int vips_rename(const char *old_name, const char *new_name); * * Strings may be in double quotes, and may contain escaped quote characters, * for example string, "string" and "str\"ing". - * */ typedef enum { VIPS_TOKEN_LEFT = 1, @@ -366,49 +324,23 @@ typedef enum { VIPS_TOKEN_COMMA } VipsToken; +#ifndef __GI_SCANNER__ + // we expose this one in the API for testing VIPS_API const char *vips__token_get(const char *buffer, VipsToken *token, char *string, int size); -const char *vips__token_must(const char *buffer, VipsToken *token, - char *string, int size); -const char *vips__token_need(const char *buffer, VipsToken need_token, - char *string, int size); -const char *vips__token_segment(const char *p, VipsToken *token, - char *string, int size); -const char *vips__token_segment_need(const char *p, VipsToken need_token, - char *string, int size); -const char *vips__find_rightmost_brackets(const char *p); -/* TODO(kleisauke): VIPS_API is required by libvips-cpp and vipsheader. - */ -VIPS_API -void vips__filename_split8(const char *name, - char *filename, char *option_string); + +#endif /* !__GI_SCANNER__ */ VIPS_API int vips_ispoweroftwo(int p); VIPS_API int vips_amiMSBfirst(void); -/* TODO(kleisauke): VIPS_API is required by jpegsave_file_fuzzer. - */ -VIPS_API -char *vips__temp_name(const char *format); - -void vips__change_suffix(const char *name, char *out, int mx, - const char *new_suff, const char **olds, int nolds); - VIPS_API char *vips_realpath(const char *path); -guint32 vips__random(guint32 seed); -guint32 vips__random_add(guint32 seed, int value); - -const char *vips__icc_dir(void); -const char *vips__windows_prefix(void); - -char *vips__get_iso8601(void); - VIPS_API int vips_strtod(const char *str, double *out); diff --git a/libvips/include/vips/vector.h b/libvips/include/vips/vector.h index 7dc1ee6864..445ecb2b26 100644 --- a/libvips/include/vips/vector.h +++ b/libvips/include/vips/vector.h @@ -38,10 +38,6 @@ extern "C" { #endif /*__cplusplus*/ -/* Set from the command-line. - */ -extern gboolean vips__vector_enabled; - VIPS_API gboolean vips_vector_isenabled(void); VIPS_API diff --git a/libvips/iofuncs/buf.c b/libvips/iofuncs/buf.c index 3e94907bcf..aac134eb62 100644 --- a/libvips/iofuncs/buf.c +++ b/libvips/iofuncs/buf.c @@ -46,11 +46,7 @@ #include /** - * SECTION: buf - * @short_description: a string you can append to - * @stability: Stable - * @see_also: #vips - * @include: vips/vips.h + * VipsBuf: * * A message buffer you can append stuff to safely and quickly. If the message * gets too long, you get "..." and truncation. Message buffers can be on the @@ -58,7 +54,7 @@ * * For example: * - * |[ + * ```c * char txt[256]; * VipsBuf buf = VIPS_BUF_STATIC(txt); * int i; @@ -70,7 +66,7 @@ * vips_buf_appendg(&buf, array[i]); * } * printf("%s", vips_buf_all(&buf)); - * ]| + * ``` */ /** @@ -167,12 +163,12 @@ vips_buf_set_static(VipsBuf *buf, char *base, int mx) * * For example: * - * |[ + * ```c * char txt[256]; * VipsBuf buf; * * vips_buf_init_static(&buf, txt, 256); - * ]| + * ``` * * Static buffers don't need to be freed when they go out of scope, but their * size must be set at compile-time. diff --git a/libvips/iofuncs/connection.c b/libvips/iofuncs/connection.c index e0a5f75381..ab3f85b945 100644 --- a/libvips/iofuncs/connection.c +++ b/libvips/iofuncs/connection.c @@ -56,29 +56,21 @@ #include /** - * SECTION: connection - * @short_description: a source/sink of bytes, perhaps a network socket - * @stability: Stable - * @see_also: foreign - * @include: vips/vips.h - * @title: VipsConnection + * VipsConnection: * - * A #VipsConnection is a source or sink of bytes for something like jpeg - * loading, see for example vips_jpegload_source(). + * An abstract base class representing a source or sink of bytes. * * It can be connected to a network socket, for example, or perhaps - * a node.js stream, or to an area of memory. + * a Node.js stream, or to an area of memory. This allows it to support + * operations like JPEG loading, see for example [func@jpegload_source]. * - * Subclass to add other input sources. Use #VipsSourceCustom and - * #VipsTargetCustom to make a source or target with action signals for - * ::read, ::write and ::seek. - */ - -/** - * VipsConnection: + * Subclass to add other input sources. Use [class@SourceCustom] and + * [class@TargetCustom] to make a source or target with action signals. + * These classes provide action signals such as: * - * A #VipsConnection is a source or sink of bytes for something like jpeg - * loading. It can be connected to a network socket, for example. + * - [signal@SourceCustom::read] for reading data from a custom source. + * - [signal@SourceCustom::seek] for seeking within a data stream. + * - [signal@TargetCustom::write] for writing data to a custom target. */ G_DEFINE_ABSTRACT_TYPE(VipsConnection, vips_connection, VIPS_TYPE_OBJECT); diff --git a/libvips/iofuncs/generate.c b/libvips/iofuncs/generate.c index a2ef201fa0..3c2d417448 100644 --- a/libvips/iofuncs/generate.c +++ b/libvips/iofuncs/generate.c @@ -546,7 +546,8 @@ vips_start_many(VipsImage *out, void *a, void *b) * * See also: vips_image_generate(), vips_start_many(). * - * Returns: %NULL-terminated array of images. Do not free the result. + * Returns: (transfer none) (nullable): %NULL-terminated array of images. + * Do not free the result. */ VipsImage ** vips_allocate_input_array(VipsImage *out, ...) @@ -655,9 +656,9 @@ write_vips(VipsRegion *region, VipsRect *area, void *a) /** * vips_image_generate: * @image: generate this image - * @start_fn: start sequences with this function - * @generate_fn: generate pixels with this function - * @stop_fn: stop sequences with this function + * @start_fn: (scope async): start sequences with this function + * @generate_fn: (scope async): generate pixels with this function + * @stop_fn: (scope async): stop sequences with this function * @a: user data * @b: user data * diff --git a/libvips/iofuncs/ginputsource.c b/libvips/iofuncs/ginputsource.c index c6862d3a60..71ab781cf1 100644 --- a/libvips/iofuncs/ginputsource.c +++ b/libvips/iofuncs/ginputsource.c @@ -290,7 +290,7 @@ vips_g_input_stream_init(VipsGInputStream *gstream) * Create a new #GInputStream wrapping a #VipsSource. This is useful for * loaders like SVG and PDF which support GInput methods. * - * Returns: a new #GInputStream + * Returns: (transfer full): a new #GInputStream */ GInputStream * vips_g_input_stream_new_from_source(VipsSource *source) diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 3071dd34d9..1155f69ecd 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -86,53 +86,6 @@ #include #include -/** - * SECTION: header - * @short_description: get, set and walk image headers - * @stability: Stable - * @see_also: type - * @include: vips/vips.h - * - * These functions let you get at image header data (including metadata) in a - * uniform way. - * - * Use vips_image_get_typeof() to test for the - * existence and #GType of a header field. - * - * You can attach arbitrary metadata to images. Metadata is copied as images - * are processed, so all images which used this image as input, directly or - * indirectly, will have this same bit of metadata attached to them. Copying - * is implemented with reference-counted pointers, so it is efficient, even for - * large items of data. This does however mean that metadata items need to be - * immutable. Metadata is handy for things like ICC profiles or EXIF data. - * - * Various convenience functions (eg. vips_image_set_int()) let you easily - * attach - * simple types like - * numbers, strings and memory blocks to images. Use vips_image_map() to loop - * over an image's fields, including all metadata. - * - * Items of metadata are identified by strings. Some strings are reserved, for - * example the ICC profile for an image is known by convention as - * "icc-profile-data". - * - * If you save an image in VIPS format, all metadata (with a restriction, see - * below) is automatically saved for you in a block of XML at the end of the - * file. When you load a VIPS image, the metadata is restored. You can use the - * `vipsedit` command-line tool to extract or replace this block of XML. - * - * VIPS metadata is based on %GValue. See the docs for that system if you want - * to do fancy stuff such as defining a new metadata type. - * VIPS defines a new %GValue called `vips_save_string`, a variety of string, - * see vips_value_set_save_string(). - * If your %GValue can be transformed to `vips_save_string`, it will be - * saved and loaded to and from VIPS files for you. - * - * VIPS provides a couple of base classes which implement - * reference-counted areas of memory. If you base your metadata on one of - * these types, it can be copied between images efficiently. - */ - /* Use in various small places where we need a mutex and it's not worth * making a private one. */ @@ -219,7 +172,7 @@ vips_format_sizeof(VipsBandFormat format) * vips_format_sizeof_unsafe: (skip) * @format: format type * - * A fast but dangerous version of vips_format_sizeof(). You must have + * A fast but dangerous version of [func@format_sizeof]. You must have * previously range-checked @format or you'll crash. * * Returns: number of bytes for a band format. @@ -480,12 +433,12 @@ vips_image_get_format_max(VipsBandFormat format) * vips_image_guess_format: * @image: image to guess for * - * Return the #VipsBandFormat for an image, guessing a sane value if + * Return the [enum@BandFormat] for an image, guessing a sane value if * the set value looks crazy. * * For example, for a float image tagged as rgb16, we'd return ushort. * - * Returns: a sensible #VipsBandFormat for the image. + * Returns: a sensible [enum@BandFormat] for the image. */ VipsBandFormat vips_image_guess_format(const VipsImage *image) @@ -565,7 +518,7 @@ vips_image_guess_format(const VipsImage *image) * vips_image_get_coding: * @image: image to get from * - * Returns: the image coding + * Returns: the [enum@Coding] from the image header. */ VipsCoding vips_image_get_coding(const VipsImage *image) @@ -577,10 +530,10 @@ vips_image_get_coding(const VipsImage *image) * vips_image_get_interpretation: * @image: image to get from * - * Return the #VipsInterpretation set in the image header. - * Use vips_image_guess_interpretation() if you want a sanity-checked value. + * Return the [enum@Interpretation] set in the image header. + * Use [method@Image.guess_format] if you want a sanity-checked value. * - * Returns: the #VipsInterpretation from the image header. + * Returns: the [enum@Interpretation] from the image header. */ VipsInterpretation vips_image_get_interpretation(const VipsImage *image) @@ -664,10 +617,10 @@ vips_image_default_interpretation(const VipsImage *image) * vips_image_guess_interpretation: * @image: image to guess for * - * Return the #VipsInterpretation for an image, guessing a sane value if + * Return the [enum@Interpretation] for an image, guessing a sane value if * the set value looks crazy. * - * Returns: a sensible #VipsInterpretation for the image. + * Returns: a sensible [enum@Interpretation] for the image. */ VipsInterpretation vips_image_guess_interpretation(const VipsImage *image) @@ -841,8 +794,8 @@ vips_image_get_yoffset(const VipsImage *image) * vips_image_get_filename: * @image: image to get from * - * Returns: the name of the file the image was loaded from, or NULL if there - * is no filename. + * Returns: the name of the file the image was loaded from, or `NULL` if + * there is no filename. */ const char * vips_image_get_filename(const VipsImage *image) @@ -936,8 +889,8 @@ vips_image_get_page_height(VipsImage *image) * vips_image_get_n_pages: * @image: image to get from * - * Fetch and sanity-check #VIPS_META_N_PAGES. Default to 1 if not present or - * crazy. + * Fetch and sanity-check [const@META_N_PAGES]. Default to 1 if not present + * or crazy. * * This is the number of pages in the image file, not the number of pages that * have been loaded into @image. @@ -962,8 +915,8 @@ vips_image_get_n_pages(VipsImage *image) * vips_image_get_concurrency: * @image: image to get from * - * Fetch and sanity-check #VIPS_CONCURRENCY. Default to 1 if not present or - * crazy. + * Fetch and sanity-check [const@META_CONCURRENCY]. Default to 1 if not + * present or crazy. * * Returns: the suggested concurrency for this image */ @@ -986,8 +939,8 @@ vips_image_get_concurrency(VipsImage *image, int default_concurrency) * vips_image_get_n_subifds: * @image: image to get from * - * Fetch and sanity-check #VIPS_META_N_SUBIFDS. Default to 0 if not present or - * crazy. + * Fetch and sanity-check [const@META_N_SUBIFDS]. Default to 0 if not + * present or crazy. * * Returns: the number of subifds in the image file */ @@ -1009,7 +962,7 @@ vips_image_get_n_subifds(VipsImage *image) * vips_image_get_orientation: * @image: image to get from * - * Fetch and sanity-check #VIPS_META_ORIENTATION. Default to 1 (no rotate, + * Fetch and sanity-check [const@META_ORIENTATION]. Default to 1 (no rotate, * no flip) if not present or crazy. * * Returns: the image orientation. @@ -1033,7 +986,7 @@ vips_image_get_orientation(VipsImage *image) * vips_image_get_orientation_swap: * @image: image to get from * - * Return %TRUE if applying the orientation would swap width and height. + * Return `TRUE` if applying the orientation would swap width and height. * * Returns: if width/height will swap */ @@ -1057,9 +1010,9 @@ vips_image_get_orientation_swap(VipsImage *image) * Since this function modifies @image, it is not threadsafe. Only call it on * images which you are sure have not been shared with another thread. * - * See also: vips_image_wio_input(), vips_image_copy_memory(). + * See also: [method@Image.wio_input] or [method@Image.copy_memory]. * - * Returns: (transfer none): a pointer to pixel data, if possible. + * Returns: (nullable) (transfer none): a pointer to pixel data, if possible. */ const void * vips_image_get_data(VipsImage *image) @@ -1084,12 +1037,11 @@ vips_image_get_data(VipsImage *image) * * A convenience function to set the header fields after creating an image. * Normally you copy the fields from your input images with - * vips_image_pipelinev() and then make - * any adjustments you need, but if you are creating an image from scratch, - * for example vips_black() or vips_jpegload(), you do need to set all the - * fields yourself. + * [method.Image.pipelinev] and then make any adjustments you need, + * but if you are creating an image from scratch, for example [func@black] + * or [func@jpegload], you do need to set all the fields yourself. * - * See also: vips_image_pipelinev(). + * See also: [method.Image.pipelinev]. */ void vips_image_init_fields(VipsImage *image, @@ -1206,28 +1158,28 @@ vips__image_copy_fields_array(VipsImage *out, VipsImage *in[]) } /** - * vips_image_set: + * vips_image_set: (method) * @image: image to set the metadata on * @name: the name to give the metadata - * @value: the %GValue to copy into the image + * @value: the [struct@GObject.Value] to copy into the image * * Set a piece of metadata on @image. Any old metadata with that name is - * destroyed. The %GValue is copied into the image, so you need to unset the + * destroyed. The [struct@GObject.Value] is copied into the image, so you need to unset the * value when you're done with it. * * For example, to set an integer on an image (though you would use the - * convenience function vips_image_set_int() in practice), you would do: + * convenience function [method@Image.set_int] in practice), you would do: * - * |[ + * ```c * GValue value = G_VALUE_INIT; * * g_value_init(&value, G_TYPE_INT); * g_value_set_int(&value, 42); * vips_image_set(image, name, &value); * g_value_unset(&value); - * ]| + * ``` * - * See also: vips_image_get(). + * See also: [method@Image.image_get]. */ void vips_image_set(VipsImage *image, const char *name, GValue *value) @@ -1293,22 +1245,23 @@ vips_set_value_from_pointer(GValue *value, void *data) } /** - * vips_image_get: - * @image: image to get the field from from + * vips_image_get: (method) + * @image: image to get the field from * @name: the name to fetch - * @value_copy: (transfer full) (out caller-allocates): the %GValue is copied into this + * @value_copy: (transfer full) (out caller-allocates): the + * [struct@GObject.Value] is copied into this * * Fill @value_copy with a copy of the header field. @value_copy must be zeroed * but uninitialised. * * This will return -1 and add a message to the error buffer if the field - * does not exist. Use vips_image_get_typeof() to test for the + * does not exist. Use [method@Image.image_get_typeof] to test for the * existence of a field first if you are not certain it will be there. * * For example, to read a double from an image (though of course you would use - * vips_image_get_double() in practice): + * [method@Image.image_get_double] in practice): * - * |[ + * ```c * GValue value = G_VALUE_INIT; * double d; * @@ -1326,9 +1279,9 @@ vips_set_value_from_pointer(GValue *value, void *data) * * d = g_value_get_double(&value); * g_value_unset(&value); - * ]| + * ``` * - * See also: vips_image_get_typeof(), vips_image_get_double(). + * See also: [method@Image.image_get_typeof] or [method@Image.image_get_double]. * * Returns: (skip): 0 on success, -1 otherwise. */ @@ -1383,17 +1336,17 @@ vips_image_get(const VipsImage *image, const char *name, GValue *value_copy) } /** - * vips_image_get_typeof: + * vips_image_get_typeof: (method) * @image: image to test * @name: the name to search for * - * Read the %GType for a header field. Returns zero if there is no - * field of that name. + * Read the [alias@GObject.Type] for a header field. Returns zero if there + * is no field of that name. * - * See also: vips_image_get(). + * See also: [method@Image.image_get]. * - * Returns: the %GType of the field, or zero if there is no - * field of that name. + * Returns: the [alias@GObject.Type] of the field, or zero if there is no + * field of that name. */ GType vips_image_get_typeof(const VipsImage *image, const char *name) @@ -1431,12 +1384,12 @@ vips_image_get_typeof(const VipsImage *image, const char *name) * @image: image to test * @name: the name to search for * - * Find and remove an item of metadata. Return %FALSE if no metadata of that + * Find and remove an item of metadata. Return `FALSE` if no metadata of that * name was found. * - * See also: vips_image_set(), vips_image_get_typeof(). + * See also: [method@Image.image_set] or [method@Image.image_get_typeof]. * - * Returns: %TRUE if an item of metadata of that name was found and removed + * Returns: `TRUE` if an item of metadata of that name was found and removed */ gboolean vips_image_remove(VipsImage *image, const char *name) @@ -1488,18 +1441,19 @@ vips_image_map_fn(VipsMeta *meta, VipsImageMapFn fn, void *a) /** * vips_image_map: * @image: image to map over - * @fn: (scope call): function to call for each header field - * @a: (closure fn): user data for function + * @fn: (scope call) (closure a): function to call for each header field + * @a: user data for @fn * * This function calls @fn for every header field, including every item of * metadata. * - * Like all _map functions, the user function should return %NULL to continue - * iteration, or a non-%NULL pointer to indicate early termination. + * Like all _map functions, the user function should return `NULL` to continue + * iteration, or a non-`NULL` pointer to indicate early termination. * - * See also: vips_image_get_typeof(), vips_image_get(). + * See also: [method@Image.image_get_typeof] or [method@Image.image_get]. * - * Returns: (transfer none): %NULL on success, the failing pointer otherwise. + * Returns: (nullable) (transfer none): `NULL` on success, the failing + * pointer otherwise. */ void * vips_image_map(VipsImage *image, VipsImageMapFn fn, void *a) @@ -1552,14 +1506,14 @@ add_fields(VipsImage *image, const char *field, GValue *value, void *a) * vips_image_get_fields: * @image: image to get fields from * - * Get a %NULL-terminated array listing all the metadata field names on @image. - * Free the return result with g_strfreev(). + * Get a `NULL`-terminated array listing all the metadata field names on @image. + * Free the return result with [func@GLib.strfreev]. * * This is handy for language bindings. From C, it's usually more convenient to - * use vips_image_map(). + * use [method@Image.map]. * - * Returns: (transfer full): metadata fields in image, as a %NULL-terminated - * array. + * Returns: (transfer full): metadata fields in image, as a `NULL`-terminated + * array. */ gchar ** vips_image_get_fields(VipsImage *image) @@ -1587,7 +1541,7 @@ vips_image_get_fields(VipsImage *image) * Attaches @data as a metadata item on @image under the name @name. When * VIPS no longer needs the metadata, it will be freed with @free_fn. * - * See also: vips_image_get_double(), vips_image_set() + * See also: [method@Image.image_get_double] or [method@Image.image_set]. */ void vips_image_set_area(VipsImage *image, const char *name, @@ -1631,11 +1585,11 @@ meta_get_value(const VipsImage *image, * @data: (out): return metadata value * * Gets @data from @image under the name @name. A convenience - * function over vips_image_get(). Use vips_image_get_typeof() to test for - * the existence of a piece of metadata. + * function over [method@Image.image_get]. Use [method@Image.image_get_typeof] to + * test for the existence of a piece of metadata. * - * See also: vips_image_set_area(), vips_image_get(), - * vips_image_get_typeof() + * See also: [method@Image.set_area], [method@Image.image_get] or + * [method@Image.image_get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1660,12 +1614,12 @@ vips_image_get_area(const VipsImage *image, * @name: metadata name * @free_fn: (scope async) (nullable): free function for @data * @data: (array length=length) (element-type guint8) (transfer full): pointer to area of - * memory + * memory * @length: length of memory area * * Attaches @data as a metadata item on @image under the name @name. * - * See also: vips_image_get_blob(), vips_image_set(). + * See also: [method@Image.image_get_blob] or [method@Image.image_set]. */ void vips_image_set_blob(VipsImage *image, const char *name, @@ -1689,7 +1643,7 @@ vips_image_set_blob(VipsImage *image, const char *name, * Attaches @data as a metadata item on @image under the name @name, taking * a copy of the memory area. * - * See also: vips_image_get_blob(), vips_image_set(). + * See also: [method@Image.image_get_blob] or [method@Image.image_set]. */ void vips_image_set_blob_copy(VipsImage *image, @@ -1718,17 +1672,19 @@ vips_image_set_blob_copy(VipsImage *image, } /** - * vips_image_get_blob: + * vips_image_get_blob: (method) * @image: image to get the metadata from * @name: metadata name - * @data: (out) (array length=length) (element-type guint8): pointer to area of memory + * @data: (out) (array length=length) (element-type guint8): pointer to area + * of memory * @length: (out): return the blob length here, optionally * * Gets @data from @image under the name @name, optionally returns its - * length in @length. Use vips_image_get_typeof() to test for the existence + * length in @length. Use [method@Image.image_get_typeof] to test for the existence * of a piece of metadata. * - * See also: vips_image_get(), vips_image_get_typeof(), vips_blob_get(), + * See also: [method@Image.image_get], [method@Image.image_get_typeof] or + * [method@Blob.get]. * * Returns: 0 on success, -1 otherwise. */ @@ -1748,16 +1704,15 @@ vips_image_get_blob(const VipsImage *image, const char *name, } /** - * vips_image_get_int: + * vips_image_get_int: (method) * @image: image to get the header field from * @name: field name * @out: (out): return field value * * Gets @out from @im under the name @name. - * The value will be transformed into - * an int, if possible. + * The value will be transformed into an int, if possible. * - * See also: vips_image_get(), vips_image_get_typeof() + * See also: [method@Image.image_get] or [method@Image.image_get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1781,10 +1736,9 @@ vips_image_get_int(const VipsImage *image, const char *name, int *out) * @i: metadata value * * Attaches @i as a metadata item on @image under the name @name. A - * convenience - * function over vips_image_set(). + * convenience function over [method@Image.image_set]. * - * See also: vips_image_get_int(), vips_image_set() + * See also: [method@Image.image_get_int] or [method@Image.image_set]. */ void vips_image_set_int(VipsImage *image, const char *name, int i) @@ -1798,16 +1752,15 @@ vips_image_set_int(VipsImage *image, const char *name, int i) } /** - * vips_image_get_double: + * vips_image_get_double: (method) * @image: image to get the header field from * @name: field name * @out: (out): return field value * * Gets @out from @im under the name @name. - * The value will be transformed into - * a double, if possible. + * The value will be transformed into a double, if possible. * - * See also: vips_image_get(), vips_image_get_typeof() + * See also: [method@Image.image_get] or [method@Image.image_get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1831,10 +1784,9 @@ vips_image_get_double(const VipsImage *image, const char *name, double *out) * @d: metadata value * * Attaches @d as a metadata item on @image as @name. A - * convenience - * function over vips_image_set(). + * convenience function over [method@Image.image_set]. * - * See also: vips_image_get_double(), vips_image_set() + * See also: [method@Image.image_get_double] or [method@Image.image_set]. */ void vips_image_set_double(VipsImage *image, const char *name, double d) @@ -1854,14 +1806,13 @@ vips_image_set_double(VipsImage *image, const char *name, double d) * @out: (out) (transfer none): return field value * * Gets @out from @im under the name @name. - * The field must be of type - * G_TYPE_STRING, VIPS_TYPE_REF_STRING. + * The field must be of type `G_TYPE_STRING` or `VIPS_TYPE_REF_STRING`. * * Do not free @out. * - * Use vips_image_get_as_string() to fetch any field as a string. + * Use [method@Image.get_as_string] to fetch any field as a string. * - * See also: vips_image_get(), vips_image_get_typeof() + * See also: [method@Image.image_get] or [method@Image.image_get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1906,9 +1857,9 @@ vips_image_get_string(const VipsImage *image, const char *name, * * Attaches @str as a metadata item on @image as @name. * A convenience - * function over vips_image_set() using #VIPS_TYPE_REF_STRING. + * function over [method@Image.image_set] using `VIPS_TYPE_REF_STRING`. * - * See also: vips_image_get_double(), vips_image_set(). + * See also: [method@Image.image_get_double] or [method@Image.image_set]. */ void vips_image_set_string(VipsImage *image, const char *name, const char *str) @@ -1931,10 +1882,11 @@ vips_image_set_string(VipsImage *image, const char *name, const char *str) * This function will read any field, returning it as a printable string. * You need to free the string with g_free() when you are done with it. * - * This will base64-encode BLOBs, for example. Use vips_buf_appendgv() to + * This will base64-encode BLOBs, for example. Use [method@Buf.appendg] to * make a string that's for humans. * - * See also: vips_image_get(), vips_image_get_typeof(), vips_buf_appendgv(). + * See also: [method@Image.image_get], [method@Image.image_get_typeof] or + * [method@Buf.appendg]. * * Returns: 0 on success, -1 otherwise. */ @@ -1992,19 +1944,19 @@ vips_image_print_field(const VipsImage *image, const char *name) } /** - * vips_image_get_image: + * vips_image_get_image: (method) * @image: image to get the metadata from * @name: metadata name * @out: (out) (transfer full): return metadata value * * Gets @out from @im under the name @name. - * The field must be of type - * #VIPS_TYPE_IMAGE. You must unref @out with g_object_unref(). + * The field must be of type `VIPS_TYPE_IMAGE`. + * You must unref @out with g_object_unref(). * - * Use vips_image_get_typeof() to test for the + * Use [method@Image.image_get_typeof] to test for the * existence of a piece of metadata. * - * See also: vips_image_get(), vips_image_set_image() + * See also:[method@Image.image_get] or [method@Image.set_image] * * Returns: 0 on success, -1 otherwise. */ @@ -2029,9 +1981,9 @@ vips_image_get_image(const VipsImage *image, * @im: metadata value * * Attaches @im as a metadata item on @image as @name. - * A convenience function over vips_image_set(). + * A convenience function over [method@Image.image_set]. * - * See also: vips_image_get_image(), vips_image_set(). + * See also: [method@Image.image_get_image] or [method@Image.image_set]. */ void vips_image_set_image(VipsImage *image, const char *name, VipsImage *im) @@ -2052,15 +2004,14 @@ vips_image_set_image(VipsImage *image, const char *name, VipsImage *im) * @n: (out) (optional): return the number of elements here, optionally * * Gets @out from @im under the name @name. - * The field must be of type - * #VIPS_TYPE_ARRAY_INT. + * The field must be of type `VIPS_TYPE_ARRAY_INT`. * * Do not free @out. @out is valid as long as @image is valid. * - * Use vips_image_get_typeof() to test for the + * Use [method@Image.image_get_typeof] to test for the * existence of a piece of metadata. * - * See also: vips_image_get(), vips_image_set_image() + * See also:[method@Image.image_get] or [method@Image.set_image] * * Returns: 0 on success, -1 otherwise. */ @@ -2086,9 +2037,9 @@ vips_image_get_array_int(VipsImage *image, const char *name, * @n: the number of elements * * Attaches @array as a metadata item on @image as @name. - * A convenience function over vips_image_set(). + * A convenience function over [method@Image.image_set]. * - * See also: vips_image_get_image(), vips_image_set(). + * See also: [method@Image.image_get_image] or [method@Image.image_set]. */ void vips_image_set_array_int(VipsImage *image, const char *name, @@ -2110,15 +2061,14 @@ vips_image_set_array_int(VipsImage *image, const char *name, * @n: (out) (optional): return the number of elements here, optionally * * Gets @out from @im under the name @name. - * The field must be of type - * #VIPS_TYPE_ARRAY_INT. + * The field must be of type `VIPS_TYPE_ARRAY_INT`. * * Do not free @out. @out is valid as long as @image is valid. * - * Use vips_image_get_typeof() to test for the + * Use [method@Image.image_get_typeof] to test for the * existence of a piece of metadata. * - * See also: vips_image_get(), vips_image_set_image() + * See also:[method@Image.image_get] or [method@Image.set_image] * * Returns: 0 on success, -1 otherwise. */ @@ -2144,9 +2094,9 @@ vips_image_get_array_double(VipsImage *image, const char *name, * @n: the number of elements * * Attaches @array as a metadata item on @image as @name. - * A convenience function over vips_image_set(). + * A convenience function over [method@Image.image_set]. * - * See also: vips_image_get_image(), vips_image_set(). + * See also: [method@Image.image_get_image] or [method@Image.image_set]. */ void vips_image_set_array_double(VipsImage *image, const char *name, @@ -2163,7 +2113,7 @@ vips_image_set_array_double(VipsImage *image, const char *name, /** * vips_image_history_printf: * @image: add history line to this image - * @format: printf() format string + * @format: `printf()`-style format string * @...: arguments to format string * * Add a line to the image history. The @format and arguments are expanded, the @@ -2172,16 +2122,16 @@ vips_image_set_array_double(VipsImage *image, const char *name, * * For example: * - * |[ + * ```c * vips_image_history_printf(image, "vips invert %s %s", * in->filename, out->filename); - * ]| + * ``` * * Might add the string * - * |[ + * ```bash * "vips invert /home/john/fred.v /home/john/jim.v # Fri Apr 3 23:30:35 2009\n" - * ]| + * ``` * * VIPS operations don't add history lines for you because a single action at * the application level might involve many VIPS operations. History must be @@ -2228,10 +2178,10 @@ vips_image_history_printf(VipsImage *image, const char *fmt, ...) * @argv: (array length=argc) (element-type char*): program arguments * * Formats the name/argv as a single string and calls - * vips_image_history_printf(). A - * convenience function for command-line prorams. + * [method@Image.history_printf]. A convenience function for + * command-line programs. * - * See also: vips_image_get_history(). + * See also: [method@Image.get_history]. * * Returns: 0 on success, -1 on error. */ @@ -2265,10 +2215,10 @@ vips_image_history_args(VipsImage *image, * * VIPS tracks the history of each image, that is, the sequence of operations * that generated that image. Applications built on VIPS need to call - * vips_image_history_printf() for each action they perform, setting the + * [method@Image.history_printf] for each action they perform, setting the * command-line equivalent for the action. * - * See also: vips_image_history_printf(). + * See also: [method@Image.history_printf]. * * Returns: (transfer none): The history of @image as a C string. Do not free! */ diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 3c09627b39..ba3d6b5839 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -72,72 +72,65 @@ #include /** - * SECTION: image - * @short_description: the VIPS image class - * @stability: Stable - * @see_also: header - * VipsRegion - * generate - * VipsOperation - * @include: vips/vips.h + * VipsImage: * - * The image class and associated types and macros. + * The [class@Image] class and associated types and macros. * * Images can be created from formatted files on disc, from C-style arrays on * disc, from formatted areas of memory, or from C-style arrays in memory. See - * vips_image_new_from_file() and friends. - * Creating an image is fast. VIPS reads just enough of + * [ctor@Image.new_from_file] and friends. + * Creating an image is fast. libvips reads just enough of * the image to be able to get the various properties, such as width in * pixels. It delays reading any pixels until they are really needed. * * Once you have an image, you can get properties from it in the usual way. - * You can use projection functions, like vips_image_get_width() or - * g_object_get(), to get %GObject properties. + * You can use projection functions, like [method@Image.get_width] or + * [method@GObject.Object.get], to get [class@GObject.Object] properties. * - * VIPS images are three-dimensional arrays, the dimensions being width, + * `.v` images are three-dimensional arrays, the dimensions being width, * height and bands. Each dimension can be up to 2 ** 31 pixels (or band * elements). An image has a format, meaning the machine number type used - * to represent each value. VIPS supports 10 formats, from 8-bit unsigned - * integer up to 128-bit double complex, see vips_image_get_format(). + * to represent each value. libvips supports 10 formats, from 8-bit unsigned + * integer up to 128-bit double complex, see [method@Image.get_format]. * - * In VIPS, images are uninterpreted arrays, meaning that from the point of - * view of most operations, they are just large collections of numbers. + * In libvips, images are uninterpreted arrays, meaning that from the point + * of view of most operations, they are just large collections of numbers. * There's no difference between an RGBA (RGB with alpha) image and a CMYK * image, for example, they are both just four-band images. It's up to the * user of the library to pass the right sort of image to each operation. * - * To take an example, VIPS has vips_Lab2XYZ(), an operation to transform - * an image from CIE LAB colour space to CIE XYZ space. It assumes the - * first three bands represent pixels in LAB colour space and returns an + * To take an example, libvips has [method@Image.Lab2XYZ], an operation to + * transform an image from CIE LAB colour space to CIE XYZ space. It assumes + * the first three bands represent pixels in LAB colour space and returns an * image where the first three bands are transformed to XYZ and any - * remaining bands are just copied. Pass it a RGB image by mistake and + * remaining bands are just copied. Pass it an RGB image by mistake and * you'll just get nonsense. * - * VIPS has a feature to help (a little) with this: it sets a - * #VipsInterpretation hint for each image (see - * vips_image_get_interpretation()); a hint which says how pixels should - * be interpreted. For example, vips_Lab2XYZ() will set the - * interpretation of the output image to #VIPS_INTERPRETATION_XYZ. A - * few utility operations will also use interpretation as a guide. For - * example, you can give vips_colourspace() an input image and a desired - * colourspace and it will use the input's interpretation hint to apply - * the best sequence of colourspace transforms to get to the desired space. - * - * Use things like vips_invert() to manipulate your images. When you are done, - * you can write images to disc files (with vips_image_write_to_file()), - * to formatted memory buffers (with vips_image_write_to_buffer()) and to - * C-style memory arrays (with vips_image_write_to_memory(). + * libvips has a feature to help (a little) with this: it sets a + * [enum@Interpretation] hint for each image (see + * [method@Image.get_interpretation]); a hint which says how pixels should + * be interpreted. For example, [method@Image.Lab2XYZ] will set the + * interpretation of the output image to [enum@Vips.Interpretation.XYZ]. + * A few utility operations will also use interpretation as a guide. For + * example, you can give [method@Image.colourspace] an input image and a + * desired colourspace and it will use the input's interpretation hint to + * apply the best sequence of colourspace transforms to get to the desired + * space. + * + * Use things like [method@Image.invert] to manipulate your images. When you + * are done, you can write images to disc files (with + * [method@Image.write_to_file]), to formatted memory buffers (with + * [method@Image.write_to_buffer]) and to C-style memory arrays (with + * [method@Image.write_to_memory]). * * You can also write images to other images. Create, for example, a temporary - * disc image with vips_image_new_temp_file(), then write your image to that - * with vips_image_write(). You can create several other types of image and - * write to them, see vips_image_new_memory(), for example. + * disc image with [ctor@Image.new_temp_file], then write your image to that + * with [method@Image.write]. You can create several other types of image and + * write to them, see [ctor@Image.new_memory], for example. * - * See operation for an introduction to - * running operations on images, see header for getting and setting image - * metadata. See object for a discussion of - * the lower levels. + * See [class@Operation] for an introduction to running operations on images, + * see [Image headers](libvips-header.html) for getting and setting image + * metadata. See [class@Object] for a discussion of the lower levels. */ /** @@ -285,14 +278,6 @@ * progress. See #VipsImage::eval. */ -/** - * VipsImage: - * - * An image. These can represent an image on disc, a memory buffer, an image - * in the process of being written to disc or a partially evaluated image - * in memory. - */ - /** * VIPS_IMAGE_SIZEOF_ELEMENT: * @I: a #VipsImage diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 53c3525a1e..fd16886f37 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -58,108 +58,105 @@ #include "vipsmarshal.h" /** - * SECTION: object - * @short_description: the VIPS base object class - * @stability: Stable - * @see_also: operation - * @include: vips/vips.h + * VipsObject: * - * The #VipsObject class and associated types and macros. + * An abstract base class for all objects in libvips. * - * #VipsObject is the base class for all objects in libvips. It has the - * following major features: + * It has the following major features: * - * Functional class creation Vips objects have a very - * regular lifecycle: initialise, build, use, destroy. They behave rather like - * function calls and are free of side-effects. + * - **Functional class creation**: libvips objects have a very regular + * lifecycle: initialise, build, use, destroy. They behave rather like + * function calls and are free of side-effects. * - * Run-time introspection Vips objects can be fully - * introspected at run-time. There is no need for separate source-code - * analysis. + * - **Run-time introspection**: libvips objects can be fully introspected + * at run-time. There is no need for separate source-code analysis. * - * Command-line interface Any vips object can be run from - * the command-line with the `vips` driver program. + * - **Command-line interface**: Any vips object can be run from the + * command-line with the `vips` driver program. * - * ## The #VipsObject lifecycle + * ## The [class@Object] lifecycle * - * #VipsObject s have a strictly defined lifecycle, split broadly as construct - * and then use. In detail, the stages are: + * [class@Object]'s have a strictly defined lifecycle, split broadly as + * construct and then use. In detail, the stages are: * - * 1. g_object_new(). The #VipsObject is created with g_object_new(). Objects - * in this state are blank slates and need to have their various parameters - * set. + * 1. [ctor@GObject.Object.new]. The [class@Object] is created with + * [ctor@GObject.Object.new]. Objects in this state are blank slates and + * need to have their various parameters set. * - * 2. g_object_set(). You loop over the #VipsArgument that the object has - * defined with vips_argument_map(). Arguments have a set of flags attached to - * them for required, optional, input, output, type, and so on. You must set - * all required arguments. + * 2. [method@GObject.Object.set]. You loop over the [struct@Argument] that + * the object has defined with [func@Argument.map]. Arguments have a set of + * flags attached to them for required, optional, input, output, type, and + * so on. You must set all required arguments. * - * 3. vips_object_build(). Call this to construct the object and get it ready - * for use. Building an object happens in four stages, see below. + * 3. [method@Object.build]. Call this to construct the object and get it + * ready for use. Building an object happens in four stages, see below. * - * 4. g_object_get(). The object has now been built. You can read out any - * computed values. + * 4. [method@GObject.Object.get]. The object has now been built. You can + * read out any computed values. * - * 5. g_object_unref(). When you are done with an object, you can unref it. - * See the section on reference counting for an explanation of the convention - * that #VipsObject uses. When the last ref to an object is released, the - * object is closed. Objects close in three stages, see below. + * 5. [method@GObject.Object.unref]. When you are done with an object, you + * can unref it. See the section on reference counting for an explanation + * of the convention that [class@Object] uses. When the last ref to an + * object is released, the object is closed. Objects close in three stages, + * see below. * - * The stages inside vips_object_build() are: + * The stages inside [method@Object.build] are: * - * 1. Chain up through the object's @build class methods. At each stage, - * each class does any initial setup and checking, then chains up to its - * superclass. + * 1. Chain up through the object's `build` class methods. At each stage, + * each class does any initial setup and checking, then chains up to its + * superclass. * - * 2. The innermost @build method inside #VipsObject itself checks that all - * input arguments have been set and then returns. + * 2. The innermost `build` method inside [class@Object] itself checks that + * all input arguments have been set and then returns. * - * 3. All object @build methods now finish executing, from innermost to - * outermost. They know all input arguments have been checked and supplied, so - * now they set all output arguments. + * 3. All object `build` methods now finish executing, from innermost to + * outermost. They know all input arguments have been checked and supplied, + * so now they set all output arguments. * - * 4. vips_object_build() finishes the process by checking that all output - * objects have been set, and then triggering the #VipsObject::postbuild - * signal. #VipsObject::postbuild only runs if the object has constructed - * successfully. + * 4. [method@Object.build] finishes the process by checking that all output + * objects have been set, and then triggering the [signal@Object::postbuild] + * signal. [signal@Object::postbuild] only runs if the object has constructed + * successfully. * - * #VipsOperation has a cache of recent operation objects, see that class for - * an explanation of vips_cache_operation_build(). + * [class@Operation] has a cache of recent operation objects, see that class for + * an explanation of [func@cache_operation_build]. * - * Finally the stages inside close are: + * Finally, the stages inside close are: * - * 1. #VipsObject::preclose. This is emitted at the start of - * the #VipsObject dispose. The object is still functioning. + * 1. [signal@Object::preclose]. This is emitted at the start of the + * [class@Object] dispose. The object is still functioning. * - * 2. #VipsObject::close. This runs just after all #VipsArgument held by - * the object have been released. + * 2. [signal@Object::close]. This runs just after all [struct@Argument] held + * by the object have been released. * - * 3. #VipsObject::postclose. This runs right at the end. The object - * pointer is still valid, but nothing else is. + * 3. [signal@Object::postclose]. This runs right at the end. The object + * pointer is still valid, but nothing else is. * - * ## #VipsArgument + * ## The [class@Object] reference counting convention * - * libvips has a simple mechanism for automating at least some aspects of - * %GObject properties. You add a set of macros to your _class_init() which - * describe the arguments, and set the get and set functions to the vips ones. - * - * See extending for a complete example. + * [class@Object] has a set of conventions to simplify reference counting. * - * ## The #VipsObject reference counting convention + * 1. All input [class@GObject.Object] have a ref added to them, owned by the + * object. When a [class@Object] is unreffed, all of these refs to input + * objects are automatically dropped. * - * #VipsObject has a set of conventions to simplify reference counting. + * 2. All output [class@GObject.Object] hold a ref to the object. When a + * [class@GObject.Object] which is an output of a [class@Object] is + * disposed, it must drop this reference. [class@Object] which are outputs + * of other [class@Object]'s will do this automatically. * - * 1. All input %GObject have a ref added to them, owned by the object. When a - * #VipsObject is unreffed, all of these refs to input objects are - * automatically dropped. - * - * 2. All output %GObject hold a ref to the object. When a %GObject which is an - * output of a #VipsObject is disposed, it must drop this reference. - * #VipsObject which are outputs of other #VipsObject will do this - * automatically. + * See [class@Operation] for an example of [class@Object] reference counting. + */ + +/** + * VipsArgument: * - * See #VipsOperation for an example of #VipsObject reference counting. + * libvips has a simple mechanism for automating at least some aspects of + * [class@GObject.Object] properties. You add a set of macros to your + * `_class_init()` which describe the arguments, and set the get and set + * functions to the libvips ones. * + * See [extending](extending.html) for a complete example. */ /** diff --git a/libvips/iofuncs/operation.c b/libvips/iofuncs/operation.c index dc201c24f8..ad7260db04 100644 --- a/libvips/iofuncs/operation.c +++ b/libvips/iofuncs/operation.c @@ -52,28 +52,23 @@ #include /** - * SECTION: operation - * @short_description: the VIPS operation base object class - * @stability: Stable - * @see_also: object - * @include: vips/vips.h + * VipsOperation: * - * The #VipsOperation class and associated types and macros. + * An abstract base class for all operations in libvips. * - * #VipsOperation is the base class for all operations in libvips. It builds - * on #VipsObject to provide the introspection and command-line interface to - * libvips. + * It builds on [class@VipsObject] to provide the introspection and + * command-line interface to libvips. * * It also maintains a cache of recent operations. See below. * - * vips_call(), vips_call_split() and vips_call_split_option_string() are used - * by vips to implement the C API. They can execute any #VipsOperation, + * [func@call], [func@call_split] and [func@call_split_option_string] are used + * by vips to implement the C API. They can execute any [class@Operation], * passing in a set of required and optional arguments. Normally you would not * use these functions directly: every operation has a tiny wrapper function * which provides type-safety for the required arguments. For example, - * vips_embed() is defined as: + * [method@Image.embed] is defined as: * - * |[ + * ```c * int * vips_embed(VipsImage *in, VipsImage **out, * int x, int y, int width, int height, ...) @@ -87,38 +82,38 @@ * * return result; * } - * ]| + * ``` * - * Use vips_call_argv() to run any vips operation from a command-line style - * argc/argv array. This is the thing used by the vips main program to - * implement the vips command-line interface. + * Use [func@call_argv] to run any libvips operation from a command-line style + * argc/argv array. This is the thing used by the `vips` main program to + * implement the command-line interface. * - * ## #VipsOperation and reference counting + * ## [class@Operation] and reference counting * - * After calling a #VipsOperation you are responsible for unreffing any output - * objects. For example, consider: + * After calling a [class@Operation] you are responsible for unreffing any + * output objects. For example, consider: * - * |[ + * ```c * VipsImage *im = ...; * VipsImage *t1; * * if (vips_invert(im, &t1, NULL)) - * error .. - * ]| + * error .. + * ``` * - * This will invert @im and return a new #VipsImage, @t1. As the caller - * of vips_invert(), you are responsible for @t1 and must unref it when you no - * longer need it. If vips_invert() fails, no @t1 is returned and you don't - * need to do anything. + * This will invert `im` and return a new [class@Image], `t1`. As the caller + * of [method@Image.invert], you are responsible for `t1` and must unref it when + * you no longer need it. If [method@Image.invert] fails, no `t1` is returned and + * you don't need to do anything. * - * If you don't need to use @im for another operation, - * you can unref @im immediately after the call. If @im is needed to calculate - * @t1, vips_invert() will add a ref to @im and automatically drop it when @t1 - * is unreffed. + * If you don't need to use `im` for another operation, you can unref `im` + * immediately after the call. If `im` is needed to calculate `t1`, + * [method@Image.invert] will add a ref to `im` and automatically drop it when + * `t1` is unreffed. * * Consider running two operations, one after the other. You could write: * - * |[ + * ```c * VipsImage *im = ...; * VipsImage *t1, *t2; * @@ -133,12 +128,12 @@ * return -1; * } * g_object_unref(t1); - * ]| + * ``` * * This is correct, but rather long-winded. libvips provides a handy thing to * make a vector of auto-freeing object references. You can write this as: * - * |[ + * ```c * VipsObject *parent = ...; * VipsImage *im = ...; * VipsImage *t = (VipsImage **) vips_object_local_array(parent, 2); @@ -146,23 +141,23 @@ * if (vips_invert(im, &t[0], NULL) || * vips_flip(t[0], &t[1], VIPS_DIRECTION_HORIZONTAL, NULL)) * return -1; - * ]| + * ``` * - * where @parent is some enclosing object which will be unreffed when this - * task is complete. vips_object_local_array() makes an array of #VipsObject - * (or #VipsImage, in this case) where when @parent is freed, all non-NULL - * #VipsObject in the array are also unreffed. + * where `parent` is some enclosing object which will be unreffed when this + * task is complete. [method@Object.local_array] makes an array of + * [class@Object] (or [class@Image], in this case) where when `parent` is + * freed, all non-`NULL` [class@Object] in the array are also unreffed. * - * ## The #VipsOperation cache + * ## The [class@Operation] cache * - * Because all #VipsObject are immutable, they can be cached. The cache is - * very simple to use: instead of calling vips_object_build(), call - * vips_cache_operation_build(). This function calculates a hash from the - * operations's input arguments and looks it up in table of all recent + * Because all [class@Object] are immutable, they can be cached. The cache is + * very simple to use: instead of calling [method@Object.build], call + * [func@cache_operation_build]. This function calculates a hash from the + * operations' input arguments and looks it up in table of all recent * operations. If there's a hit, the new operation is unreffed, the old * operation reffed, and the old operation returned in place of the new one. * - * The cache size is controlled with vips_cache_set_max() and friends. + * The cache size is controlled with [func@cache_set_max] and friends. */ /** diff --git a/libvips/iofuncs/rect.c b/libvips/iofuncs/rect.c index 460236db0e..6e13c991e8 100644 --- a/libvips/iofuncs/rect.c +++ b/libvips/iofuncs/rect.c @@ -44,16 +44,6 @@ #include -/** - * SECTION: rectangle - * @short_description: the VIPS rectangle class - * @stability: Stable - * @see_also: region - * @include: vips/vips.h - * - * The #VipsRect class and associated types and macros. - */ - /** * VipsRect: * @left: left edge of rectangle @@ -61,7 +51,7 @@ * @width: width of rectangle * @height: height of rectangle * - * A #VipsRect is a rectangular area of pixels. This is a struct for + * A [struct@Rect] is a rectangular area of pixels. This is a struct for * performing simple rectangle algebra. */ diff --git a/libvips/iofuncs/region.c b/libvips/iofuncs/region.c index 56d1557c5b..199786fb2b 100644 --- a/libvips/iofuncs/region.c +++ b/libvips/iofuncs/region.c @@ -105,39 +105,23 @@ #include /** - * SECTION: region - * @short_description: small, rectangular parts of images - * @stability: Stable - * @see_also: image, - * generate - * @include: vips/vips.h + * VipsRegion: + * + * A [class@Region] represents a small, rectangular part of an image. * - * A #VipsRegion is a small part of an image. You use regions to - * read pixels out of images without having to have the whole image in memory - * at once. + * You use regions to read pixels out of images without having to have the + * whole image in memory at once. * * A region can be a memory buffer, part of a memory-mapped file, part of some * other image, or part of some other region. * * Regions must be created, used and freed all within the same thread, since - * they can reference private per-thread caches. VIPS sanity-checks region - * ownership in various places, so you are likely to see g_assert() errors if - * you don't follow this rule. - * - * There - * is API to transfer ownership of regions between threads, but hopefully this - * is only needed within VIPS, so we don't expose it. Hopefully. - */ - -/** - * VipsRegion: - * @im: the #VipsImage that this region is defined on - * @valid: the #VipsRect of pixels that this region represents - * - * A small part of a #VipsImage. @valid holds the left/top/width/height of the - * area of pixels that are available from the region. + * they can reference private per-thread caches. libvips sanity-checks region + * ownership in various places, so you are likely to see [func@GLib.assert] + * errors if you don't follow this rule. * - * See also: VIPS_REGION_ADDR(), vips_region_new(), vips_region_prepare(). + * There is API to transfer ownership of regions between threads, but + * (hopefully) this is only needed within libvips, so we don't expose it. */ /** diff --git a/libvips/iofuncs/sbuf.c b/libvips/iofuncs/sbuf.c index 7a7d92664e..a0d3edcdce 100644 --- a/libvips/iofuncs/sbuf.c +++ b/libvips/iofuncs/sbuf.c @@ -56,16 +56,11 @@ #include /** - * SECTION: sbuf - * @short_description: buffered read from a source - * @stability: Stable - * @see_also: foreign - * @include: vips/vips.h - * @title: VipsSbuf - * - * #VipsSbuf wraps up a #VipsSource and provides a set of calls for - * text-oriented buffered reading. You can fetch lines of text, skip - * whitespace, and so on. + * VipsSbuf: + * + * A [class@Sbuf] provides a buffered reading interface for a [class@Source]. + * + * You can fetch lines of text, skip whitespace, and so on. * * It is useful for implementing things like CSV readers, for example. */ diff --git a/libvips/iofuncs/sink.c b/libvips/iofuncs/sink.c index bf146b23cc..67f1a8eab0 100644 --- a/libvips/iofuncs/sink.c +++ b/libvips/iofuncs/sink.c @@ -446,9 +446,9 @@ vips_sink_base_progress(void *a) * @im: scan over this image * @tile_width: tile width * @tile_height: tile height - * @start_fn: start sequences with this function - * @generate_fn: generate pixels with this function - * @stop_fn: stop sequences with this function + * @start_fn: (scope async): start sequences with this function + * @generate_fn: (scope async): generate pixels with this function + * @stop_fn: (scope async): stop sequences with this function * @a: user data * @b: user data * @@ -513,9 +513,9 @@ vips_sink_tile(VipsImage *im, /** * vips_sink: (method) * @im: scan over this image - * @start_fn: start sequences with this function - * @generate_fn: generate pixels with this function - * @stop_fn: stop sequences with this function + * @start_fn: (scope async): start sequences with this function + * @generate_fn: (scope async): generate pixels with this function + * @stop_fn: (scope async): stop sequences with this function * @a: user data * @b: user data * diff --git a/libvips/iofuncs/sinkdisc.c b/libvips/iofuncs/sinkdisc.c index e48d14daf4..fbf743fe1b 100644 --- a/libvips/iofuncs/sinkdisc.c +++ b/libvips/iofuncs/sinkdisc.c @@ -484,8 +484,8 @@ write_free(Write *write) /** * vips_sink_disc: (method) * @im: image to process - * @write_fn: (scope call): called for every batch of pixels - * @a: (closure write_fn): client data + * @write_fn: (scope call) (closure a): called for every batch of pixels + * @a: client data * * vips_sink_disc() loops over @im, top-to-bottom, generating it in sections. * As each section is produced, @write_fn is called. diff --git a/libvips/iofuncs/sinkscreen.c b/libvips/iofuncs/sinkscreen.c index f8873ab2f6..d05123edb2 100644 --- a/libvips/iofuncs/sinkscreen.c +++ b/libvips/iofuncs/sinkscreen.c @@ -1132,8 +1132,8 @@ vips__sink_screen_once(void *data) * @tile_height: tile height * @max_tiles: maximum tiles to cache * @priority: rendering priority - * @notify_fn: (scope call) (nullable): pixels are ready notification callback - * @a: (closure notify_fn) (nullable): client data for callback + * @notify_fn: (scope call) (closure a) (nullable): pixels are ready notification callback + * @a: (nullable): client data for callback * * This operation renders @in in the background, making pixels available * on @out as they are calculated. The @notify_fn callback is run every diff --git a/libvips/iofuncs/source.c b/libvips/iofuncs/source.c index d68fd225f7..56839984b4 100644 --- a/libvips/iofuncs/source.c +++ b/libvips/iofuncs/source.c @@ -74,6 +74,46 @@ #include #include +/** + * VipsSource: + * + * A [class@Source] provides a unified interface for reading, seeking, and + * mapping data, regardless of the underlying source type. + * + * This source can originate from something like a socket, file or memory + * area. + * + * During the header phase, we save data from unseekable sources in a buffer + * so readers can rewind and read again. We don't buffer data during the + * decode stage. + */ + +/** + * VipsSourceCustom: + * + * Subclass of [class@Source] with action signals for handlers. + * + * This is supposed to be useful for language bindings. + */ + +/** + * VipsTarget: + * + * A [class@Target] provides a unified interface for writing data to various + * output destinations. + * + * This target could be a socket, file, memory area, or any other destination + * that accepts byte data. + */ + +/** + * VipsTargetCustom: + * + * Subclass of [class@Target] with action signals for handlers. + * + * This is supposed to be useful for language bindings. + */ + #define MODE_READ CLOEXEC(BINARYIZE(O_RDONLY)) /* -1 on a pipe isn't actually unbounded. Have a limit to prevent @@ -411,9 +451,9 @@ vips_source_new_from_descriptor(int descriptor) /** * vips_source_new_from_file: - * @descriptor: read from this filename + * @filename: read from this filename * - * Create an source attached to a file. + * Create a source attached to a file. * * If this descriptor does not support mmap and the source is * used with a loader that can only work from memory, then the data will be @@ -1030,10 +1070,10 @@ vips_source_is_file(VipsSource *source) /** * vips_source_map: * @source: source to operate on - * @length_out: return the file length here, or NULL + * @length: return the file length here, or NULL * * Map the source entirely into memory and return a pointer to the - * start. If @length_out is non-NULL, the source size is written to it. + * start. If @length is non-NULL, the source size is written to it. * * This operation can take a long time. Use vips_source_is_mappable() to * check if a source can be mapped efficiently. @@ -1043,7 +1083,7 @@ vips_source_is_file(VipsSource *source) * Returns: a pointer to the start of the file contents, or NULL on error. */ const void * -vips_source_map(VipsSource *source, size_t *length_out) +vips_source_map(VipsSource *source, size_t *length) { VIPS_DEBUG_MSG("vips_source_map:\n"); @@ -1074,8 +1114,8 @@ vips_source_map(VipsSource *source, size_t *length_out) vips_source_pipe_read_to_position(source, -1)) return NULL; - if (length_out) - *length_out = source->length; + if (length) + *length = source->length; SANITY(source); diff --git a/libvips/iofuncs/sourceginput.c b/libvips/iofuncs/sourceginput.c index 12cbe5beb8..ee2aa6cd59 100644 --- a/libvips/iofuncs/sourceginput.c +++ b/libvips/iofuncs/sourceginput.c @@ -242,7 +242,7 @@ vips_source_g_input_stream_init(VipsSourceGInputStream *source) * * Create a #VipsSourceGInputStream which wraps @stream. * - * Returns: the new source. + * Returns: (transfer full): the new source. */ VipsSourceGInputStream * vips_source_g_input_stream_new(GInputStream *stream) diff --git a/libvips/iofuncs/target.c b/libvips/iofuncs/target.c index 66145fbc4a..a6709adc93 100644 --- a/libvips/iofuncs/target.c +++ b/libvips/iofuncs/target.c @@ -316,13 +316,13 @@ vips_target_init(VipsTarget *target) } /** - * vips_target_new_to_descriptor: + * vips_target_new_to_descriptor: (constructor) * @descriptor: write to this file descriptor * * Create a target attached to a file descriptor. * @descriptor is kept open until the target is finalized. * - * See also: vips_target_new_to_file(). + * See also: [ctor@Target.new_to_file]. * * Returns: a new target. */ @@ -347,7 +347,7 @@ vips_target_new_to_descriptor(int descriptor) } /** - * vips_target_new_to_file: + * vips_target_new_to_file: (constructor) * @filename: write to this file * * Create a target attached to a file. @@ -375,12 +375,12 @@ vips_target_new_to_file(const char *filename) } /** - * vips_target_new_to_memory: + * vips_target_new_to_memory: (constructor) * * Create a target which will write to a memory area. Read from @blob to get * memory. * - * See also: vips_target_new_to_file(). + * See also: [ctor@Target.new_to_file]. * * Returns: a new target. */ @@ -404,13 +404,13 @@ vips_target_new_to_memory(void) } /** - * vips_target_new_temp: + * vips_target_new_temp: (constructor) * @based_on: base the temporary target on this target * * Create a temporary target -- either a temporary file on disc, or an area in * memory, depending on what sort of target @based_on is. * - * See also: vips_target_new_to_file(). + * See also: [ctor@Target.new_to_file]. * * Returns: a new target. */ @@ -503,15 +503,15 @@ vips_target_flush(VipsTarget *target) /** * vips_target_write: * @target: target to operate on - * @buffer: bytes to write - * @length: length of @buffer in bytes + * @data: data to write + * @length: length of @data in bytes * - * Write @length bytes from @buffer to the output. + * Write @length bytes from @data to the output. * * Returns: 0 on success, -1 on error. */ int -vips_target_write(VipsTarget *target, const void *buffer, size_t length) +vips_target_write(VipsTarget *target, const void *data, size_t length) { VIPS_DEBUG_MSG("vips_target_write: %zd bytes\n", length); @@ -522,12 +522,12 @@ vips_target_write(VipsTarget *target, const void *buffer, size_t length) if (length > VIPS_TARGET_BUFFER_SIZE - target->write_point) { /* Still too large? Do an unbuffered write. */ - if (vips_target_write_unbuffered(target, buffer, length)) + if (vips_target_write_unbuffered(target, data, length)) return -1; } else { memcpy(target->output_buffer + target->write_point, - buffer, length); + data, length); target->write_point += length; } @@ -544,7 +544,7 @@ vips_target_write(VipsTarget *target, const void *buffer, size_t length) * Return the number of bytes actually read. If all bytes have been read from * the file, return 0. * - * Arguments exactly as read(2). + * Arguments exactly as [`read()`](man:read(2)). * * Reading from a target sounds weird, but libtiff needs this for * multi-page writes. This method will fail for targets like pipes. @@ -567,43 +567,41 @@ vips_target_read(VipsTarget *target, void *buffer, size_t length) /** * vips_target_seek: * @target: target to operate on - * @position: position to seek to + * @offset: offset to seek to * @whence: seek relative to beginning, offset, or end * - * Seek the target. This behaves exactly as lseek(2). + * Seek the target. This behaves exactly as [`lseek()`](man:lseek(2)). * * Seeking a target sounds weird, but libtiff needs this. This method will * fail for targets like pipes. * - * Returns: the new seek position, -1 on error. + * Returns: the new offset, -1 on error. */ gint64 -vips_target_seek(VipsTarget *target, gint64 position, int whence) +vips_target_seek(VipsTarget *target, gint64 offset, int whence) { VipsTargetClass *class = VIPS_TARGET_GET_CLASS(target); - gint64 new_position; + gint64 new_offset; - VIPS_DEBUG_MSG("vips_target_seek: pos = %" G_GINT64_FORMAT - ", whence = %d\n", - position, whence); + VIPS_DEBUG_MSG( + "vips_target_seek: offset = %" G_GINT64_FORMAT ", whence = %d\n", + offset, whence); if (vips_target_flush(target)) return -1; - new_position = class->seek(target, position, whence); + new_offset = class->seek(target, offset, whence); - VIPS_DEBUG_MSG("vips_target_seek: new_position = %" G_GINT64_FORMAT "\n", - new_position); + VIPS_DEBUG_MSG("vips_target_seek: new_offset = %" G_GINT64_FORMAT "\n", + new_offset); - return new_position; + return new_offset; } /** * vips_target_end: * @target: target to operate on - * @buffer: bytes to write - * @length: length of @buffer in bytes * * Call this at the end of write to make the target do any cleaning up. You * can call it many times. @@ -652,16 +650,16 @@ vips_target_end(VipsTarget *target) * @target: target to operate on * @length: return number of bytes of data * - * Memory targets only (see vips_target_new_to_memory()). Steal all data - * written to the target so far, and call vips_target_end(). + * Memory targets only (see [ctor@Target.new_to_memory]). Steal all data + * written to the target so far, and call [method@Target.end]. * - * You must free the returned pointer with g_free(). + * You must free the returned pointer with [func@GLib.free]. * - * The data is NOT automatically null-terminated. vips_target_putc() a '\0' - * before calling this to get a null-terminated string. + * The data is NOT automatically null-terminated. Use [method@Target.putc] with + * a '\0' before calling this to get a null-terminated string. * - * You can't call this after vips_target_end(), since that moves the data to a - * blob, and we can't steal from that in case the pointer has been be shared. + * You can't call this after [method@Target.end], since that moves the data to a + * blob, and we can't steal from that in case the pointer has been shared. * * You can't call this function more than once. * @@ -698,7 +696,7 @@ vips_target_steal(VipsTarget *target, size_t *length) * vips_target_steal_text: * @target: target to operate on * - * As vips_target_steal_text(), but return a null-terminated string. + * As [method@Target.steal], but return a null-terminated string. * * Returns: (transfer full): target contents as a null-terminated string. */ @@ -715,7 +713,7 @@ vips_target_steal_text(VipsTarget *target) * @target: target to operate on * @ch: character to write * - * Write a single character @ch to @target. See the macro VIPS_TARGET_PUTC() + * Write a single character @ch to @target. See the macro [func@TARGET_PUTC] * for a faster way to do this. * * Returns: 0 on success, -1 on error. @@ -753,7 +751,7 @@ vips_target_writes(VipsTarget *target, const char *str) /** * vips_target_writef: * @target: target to operate on - * @fmt: printf()-style format string + * @fmt: `printf()`-style format string * @...: arguments to format string * * Format the string and write to @target. diff --git a/libvips/iofuncs/thread.c b/libvips/iofuncs/thread.c index 585bb3a4c7..a15ba85b9f 100644 --- a/libvips/iofuncs/thread.c +++ b/libvips/iofuncs/thread.c @@ -114,6 +114,16 @@ vips_thread_run(gpointer data) return result; } +/** + * vips_g_thread_new: + * @domain: (nullable): an (optional) name for the new thread + * @func: (scope async) (closure data): a function to execute in the new thread + * @data: (nullable): an argument to supply to the new thread + * + * Wrapper for g_thread_try_new(). + * + * Returns: (transfer full): the new #GThread, or %NULL if an error occurred + */ GThread * vips_g_thread_new(const char *domain, GThreadFunc func, gpointer data) { diff --git a/libvips/iofuncs/threadpool.c b/libvips/iofuncs/threadpool.c index 59a18e8dfb..a84ca93112 100644 --- a/libvips/iofuncs/threadpool.c +++ b/libvips/iofuncs/threadpool.c @@ -78,17 +78,14 @@ #endif /*G_OS_WIN32*/ /** - * SECTION: threadpool - * @short_description: pools of worker threads - * @stability: Stable - * @see_also: generate - * @include: vips/vips.h - * @title: VipsThreadpool + * VipsThreadState: * - * vips_threadpool_run() loops a set of threads over an image. Threads take it - * in turns to allocate units of work (a unit might be a tile in an image), - * then run in parallel to process those units. An optional progress function - * can be used to give feedback. + * A [class@VipsThreadState] represents a per-thread state. + * + * [callback@ThreadpoolAllocateFn] functions can use these members to + * communicate with [callback@ThreadpoolWorkFn] functions. + * + * See also: [func@threadpool_run]. */ /* Set to stall threads for debugging. @@ -138,9 +135,9 @@ vips__threadpool_shutdown(void) /** * vips_thread_execute: - * @name: a name for the thread - * @func: a function to execute in the libvips threadset - * @data: an argument to supply to @func + * @domain: a name for the thread (useful for debugging) + * @func: (scope async) (closure data): a function to execute in the libvips threadset + * @data: (nullable): an argument to supply to @func * * A newly created or reused thread will execute @func with the * argument @data. @@ -562,17 +559,12 @@ vips_threadpool_new(VipsImage *im) * VipsThreadpoolAllocateFn: * @state: per-thread state * @a: client data - * @b: client data - * @c: client data * @stop: set this to signal end of computation * * This function is called to allocate a new work unit for the thread. It is * always single-threaded, so it can modify per-pool state (such as a * counter). * - * @a, @b, @c are the values supplied to the call to - * vips_threadpool_run(). - * * It should set @stop to %TRUE to indicate that no work could be allocated * because the job is done. * @@ -585,16 +577,11 @@ vips_threadpool_new(VipsImage *im) * VipsThreadpoolWorkFn: * @state: per-thread state * @a: client data - * @b: client data - * @c: client data * * This function is called to process a work unit. Many copies of this can run * at once, so it should not write to the per-pool state. It can write to * per-thread state. * - * @a, @b, @c are the values supplied to the call to - * vips_threadpool_run(). - * * See also: vips_threadpool_run(). * * Returns: 0 on success, or -1 on error @@ -603,8 +590,6 @@ vips_threadpool_new(VipsImage *im) /** * VipsThreadpoolProgressFn: * @a: client data - * @b: client data - * @c: client data * * This function is called by the main thread once for every work unit * processed. It can be used to give the user progress feedback. @@ -617,10 +602,10 @@ vips_threadpool_new(VipsImage *im) /** * vips_threadpool_run: * @im: image to loop over - * @start: allocate per-thread state - * @allocate: allocate a work unit - * @work: process a work unit - * @progress: give progress feedback about a work unit, or %NULL + * @start: (scope async): allocate per-thread state + * @allocate: (scope async): allocate a work unit + * @work: (scope async): process a work unit + * @progress: (scope async): give progress feedback about a work unit, or %NULL * @a: client data * * This function runs a set of threads over an image. Each thread first calls diff --git a/libvips/iofuncs/threadset.c b/libvips/iofuncs/threadset.c index 7cbe31a270..e242d50c63 100644 --- a/libvips/iofuncs/threadset.c +++ b/libvips/iofuncs/threadset.c @@ -246,7 +246,7 @@ vips_threadset_add_thread(VipsThreadset *set) } /** - * vips_threadset_new: + * vips_threadset_new: (free-func vips_threadset_free) (skip) * @max_threads: maximum number of system threads * * Create a new threadset. @@ -285,8 +285,8 @@ vips_threadset_new(int max_threads) * vips_threadset_run: * @set: the threadset to run the task in * @domain: the name of the task (useful for debugging) - * @func: the task to execute - * @data: the task's data + * @func: (scope async) (closure data): the task to execute + * @data: (nullable): the task's data * * Execute a task in a thread. If there are no idle threads and the maximum * thread limit specified by @max_threads has not been reached, a new thread diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index 624e221d4b..41e2db5b57 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -68,7 +68,14 @@ #define MODE_READ CLOEXEC(BINARYIZE(O_RDONLY)) -/* Test two lists for eqality. +/** + * vips_slist_equal: + * @l1: (element-type guint8): a #GSList + * @l2: (element-type guint8): another #GSList + * + * Test two lists for equality. + * + * Returns: `TRUE` if @l1 is equal to @l2. `FALSE` otherwise. */ gboolean vips_slist_equal(GSList *l1, GSList *l2) @@ -87,7 +94,17 @@ vips_slist_equal(GSList *l1, GSList *l2) return TRUE; } -/* Map over an slist. _copy() the list in case the callback changes it. +/** + * vips_slist_map2: + * @list: (element-type guint8): a #GSList + * @fn: (scope call): function to apply to each list element + * @a: user data + * @b: user data + * + * Map over a slist. _copy() the list in case the callback changes it. + * + * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first + * non-%NULL value from @fn. */ void * vips_slist_map2(GSList *list, VipsSListMap2Fn fn, void *a, void *b) @@ -105,7 +122,17 @@ vips_slist_map2(GSList *list, VipsSListMap2Fn fn, void *a, void *b) return result; } -/* Map backwards. We _reverse() rather than recurse and unwind to save stack. +/** + * vips_slist_map2_rev: + * @list: (element-type guint8): a #GSList + * @fn: (scope call): function to apply to each list element + * @a: user data + * @b: user data + * + * Map backwards. We _reverse() rather than recurse and unwind to save stack. + * + * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first + * non-%NULL value from @fn. */ void * vips_slist_map2_rev(GSList *list, VipsSListMap2Fn fn, void *a, void *b) @@ -124,6 +151,20 @@ vips_slist_map2_rev(GSList *list, VipsSListMap2Fn fn, void *a, void *b) return result; } +/** + * vips_slist_map4: + * @list: (element-type guint8): a #GSList + * @fn: (scope call): function to apply to each list element + * @a: user data + * @b: user data + * @c: user data + * @d: user data + * + * Map over a slist. _copy() the list in case the callback changes it. + * + * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first + * non-%NULL value from @fn. + */ void * vips_slist_map4(GSList *list, VipsSListMap4Fn fn, void *a, void *b, void *c, void *d) @@ -142,6 +183,19 @@ vips_slist_map4(GSList *list, return result; } +/** + * vips_slist_fold2: + * @list: (element-type guint8): a #GSList + * @start: initial value for the accumulator + * @fn: (scope call): function to apply to each list element + * @a: user data + * @b: user data + * + * Fold over a slist, applying @fn to each element. + * + * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first + * non-%NULL value from @fn. + */ void * vips_slist_fold2(GSList *list, void *start, VipsSListFold2Fn fn, void *a, void *b) @@ -159,7 +213,17 @@ vips_slist_fold2(GSList *list, void *start, return c; } -/* Remove all occurrences of an item from a list. +/** + * vips_slist_filter: + * @list: (element-type guint8): a #GSList + * @fn: (scope call): function to call for each element. + * @a: user data + * @b: user data + * + * Remove all occurrences of an item from a list. + * Returns the new head of the list. + * + * Returns: (element-type guint8) (transfer full): new head of @list */ GSList * vips_slist_filter(GSList *list, VipsSListMap2Fn fn, void *a, void *b) @@ -198,7 +262,11 @@ vips_slist_free_all_cb(void *thing, void *dummy) g_free(thing); } -/* Free a g_slist of things which need g_free()ing. +/** + * vips_slist_free_all: + * @list: (element-type guint8): a #GSList + * + * Free a g_slist of things which need g_free()ing. */ void vips_slist_free_all(GSList *list) @@ -229,7 +297,17 @@ vips_hash_table_predicate(const char *key, void *value, Pair *pair) return (pair->result = pair->fn(value, pair->a, pair->b)) != NULL; } -/* Like slist map, but for a hash table. +/** + * vips_hash_table_map: + * @hash: a #GHashTable + * @fn: (scope call): function to apply to each hash value + * @a: user data + * @b: user data + * + * Like slist map, but for a hash table. + * + * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first + * non-%NULL value from @fn. */ void * vips_hash_table_map(GHashTable *hash, VipsSListMap2Fn fn, void *a, void *b) @@ -850,7 +928,11 @@ vips__gvalue_ref_string_new(const char *text) return value; } -/* Free a GSList of GValue. +/** + * vips__gslist_gvalue_free: + * @list: (element-type GValue): a #GSList of GValue + * + * Free a GSList of GValue. */ void vips__gslist_gvalue_free(GSList *list) @@ -859,7 +941,13 @@ vips__gslist_gvalue_free(GSList *list) g_slist_free(list); } -/* Copy a GSList of GValue. +/** + * vips__gslist_gvalue_copy: + * @list: (element-type GValue): a #GSList of GValue + * + * Copy a GSList of GValue. + * + * Returns: (element-type GValue) (transfer full): a copy of @list */ GSList * vips__gslist_gvalue_copy(const GSList *list) @@ -878,9 +966,15 @@ vips__gslist_gvalue_copy(const GSList *list) return copy; } -/* Merge two GSList of GValue ... append to a all elements in b which are not - * in a. Return the new value of a. Works for any vips refcounted type - * (string, blob, etc.). +/** + * vips__gslist_gvalue_merge: + * @a: (element-type GValue): a #GSList of GValue + * @b: (element-type GValue): a #GSList of GValue + * + * Merge two GSList of GValue ... append to a all elements in b which are not + * in a. Works for any vips refcounted type (string, blob, etc.). + * + * Returns: (element-type GValue) (transfer full): the new value of @a */ GSList * vips__gslist_gvalue_merge(GSList *a, const GSList *b) @@ -919,8 +1013,16 @@ vips__gslist_gvalue_merge(GSList *a, const GSList *b) return a; } -/* Make a char * from GSList of GValue. Each GValue should be a ref_string. - * free the result. Empty list -> "", not NULL. Join strings with '\n'. +/** + * vips__gslist_gvalue_get: + * @list: (element-type GValue): a #GSList of GValue + * + * Make a char * from GSList of GValue. Each GValue should be a ref_string. + * + * If @list is empty, the return value will be `NULL`. + * + * Returns: (transfer full) (nullable): a newly-allocated string containing + * all of the list elements joined together, with '\n' between them. */ char * vips__gslist_gvalue_get(const GSList *list) diff --git a/libvips/meson.build b/libvips/meson.build index f89a93f252..ff55c98781 100644 --- a/libvips/meson.build +++ b/libvips/meson.build @@ -45,13 +45,14 @@ if enable_introspection vips_gir = gnome.generate_gir( libvips_lib, namespace: 'Vips', - nsversion: '8.0', + nsversion: '@0@.0'.format(version_major), identifier_prefix: 'Vips', symbol_prefix: 'vips', + export_packages: 'vips', header: 'vips/vips.h', sources: libvips_sources, dependencies: libvips_deps, - includes: 'GObject-2.0', + includes: ['GObject-2.0', 'Gio-2.0'], install: true ) diff --git a/libvips/mosaicing/match.c b/libvips/mosaicing/match.c index dd5ca6d735..783e343c20 100644 --- a/libvips/mosaicing/match.c +++ b/libvips/mosaicing/match.c @@ -303,7 +303,7 @@ vips_match_init(VipsMatch *match) } /** - * vips_match: + * vips_match: (method) * @ref: reference image * @sec: secondary image * @out: (out): output image diff --git a/libvips/mosaicing/merge.c b/libvips/mosaicing/merge.c index e6d151cd46..5d0cd43a71 100644 --- a/libvips/mosaicing/merge.c +++ b/libvips/mosaicing/merge.c @@ -172,7 +172,7 @@ vips_merge_init(VipsMerge *merge) } /** - * vips_merge: + * vips_merge: (method) * @ref: reference image * @sec: secondary image * @out: (out): output image diff --git a/libvips/mosaicing/mosaic.c b/libvips/mosaicing/mosaic.c index 6101046f85..bb04a05cf0 100644 --- a/libvips/mosaicing/mosaic.c +++ b/libvips/mosaicing/mosaic.c @@ -309,7 +309,7 @@ vips_mosaic_init(VipsMosaic *mosaic) } /** - * vips_mosaic: + * vips_mosaic: (method) * @ref: reference image * @sec: secondary image * @out: (out): output image diff --git a/libvips/mosaicing/mosaic1.c b/libvips/mosaicing/mosaic1.c index dcfc28adeb..357ee65da5 100644 --- a/libvips/mosaicing/mosaic1.c +++ b/libvips/mosaicing/mosaic1.c @@ -626,7 +626,7 @@ vips_mosaic1_init(VipsMosaic1 *mosaic1) } /** - * vips_mosaic1: + * vips_mosaic1: (method) * @ref: reference image * @sec: secondary image * @out: output image diff --git a/libvips/resample/interpolate.c b/libvips/resample/interpolate.c index 13e3575e47..7d3c86d70b 100644 --- a/libvips/resample/interpolate.c +++ b/libvips/resample/interpolate.c @@ -63,13 +63,15 @@ #include /** - * SECTION: interpolator - * @short_description: various interpolators: nearest, bilinear, and - * some non-linear - * @stability: Stable - * @include: vips/vips.h + * VipsInterpolate: * - * A number of image interpolators. + * An abstract base class for the various interpolation functions. + * + * Use `vips --list classes` to see all the interpolators available. + * + * An interpolator consists of a function to perform the interpolation, plus + * some extra data fields which tells libvips how to call the function and + * what data it needs. */ G_DEFINE_ABSTRACT_TYPE(VipsInterpolate, vips_interpolate, VIPS_TYPE_OBJECT); @@ -83,12 +85,12 @@ G_DEFINE_ABSTRACT_TYPE(VipsInterpolate, vips_interpolate, VIPS_TYPE_OBJECT); * @y: interpolate value at this position * * An interpolation function. It should read source pixels from @in with - * VIPS_REGION_ADDR(), it can look left and up from (x, y) by @window_offset + * [func@REGION_ADDR], it can look left and up from (x, y) by @window_offset * pixels and it can access pixels in a window of size @window_size. * * The interpolated value should be written to the pixel pointed to by @out. * - * See also: #VipsInterpolateClass. + * See also: [struct@VipsInterpolateClass]. */ /** @@ -99,32 +101,26 @@ G_DEFINE_ABSTRACT_TYPE(VipsInterpolate, vips_interpolate, VIPS_TYPE_OBJECT); * @get_window_offset: return the window offset for this method * @window_offset: or just set this for a constant window offset * - * The abstract base class for the various VIPS interpolation functions. - * Use "vips --list classes" to see all the interpolators available. - * - * An interpolator consists of a function to perform the interpolation, plus - * some extra data fields which tell vips how to call the function and what - * data it needs. - * * @window_size is the size of the window that the interpolator needs. For * example, a bicubic interpolator needs to see a window of 4x4 pixels to be * able to interpolate a value. * * You can either have a function in @get_window_size which returns the window - * that a specific interpolator needs, or you can leave @get_window_size %NULL + * that a specific interpolator needs, or you can leave @get_window_size `NULL` * and set a constant value in @window_size. * * @window_offset is how much to offset the window up and left of (x, y). For - * example, a bicubic interpolator will want a @window_offset of 1. + * example, a bicubic interpolator will want an @window_offset of 1. * * You can either have a function in @get_window_offset which returns the * offset that a specific interpolator needs, or you can leave - * @get_window_offset %NULL and set a constant value in @window_offset. + * @get_window_offset `NULL` and set a constant value in @window_offset. * - * You also need to set @nickname and @description in #VipsObject. + * You also need to set [property@VipsObject:nickname] and + * [property@VipsObject:description] in [class@Object]. * - * See also: #VipsInterpolateMethod, #VipsObject, - * vips_interpolate_bilinear_static(). + * See also: [callback@InterpolateMethod], [class@Object] or + * [func@Interpolate.bilinear_static]. */ #ifdef DEBUG @@ -209,7 +205,7 @@ vips_interpolate_init(VipsInterpolate *interpolate) * @y: interpolate value at this position * * Look up the @interpolate method in the class and call it. Use - * vips_interpolate_get_method() to get a direct pointer to the function and + * [method@Interpolate.get_method] to get a direct pointer to the function and * avoid the lookup overhead. * * You need to set @in and @out up correctly. @@ -230,7 +226,7 @@ vips_interpolate(VipsInterpolate *interpolate, * @interpolate: interpolator to use * * Look up the @interpolate method in the class and return it. Use this - * instead of vips_interpolate() to cache method dispatch. + * instead of [func@interpolate] to cache method dispatch. * * Returns: a pointer to the interpolation function */ @@ -283,14 +279,14 @@ vips_interpolate_get_window_offset(VipsInterpolate *interpolate) /** * VIPS_TRANSFORM_SHIFT: * - * Many of the vips interpolators use fixed-point arithmetic for coordinate + * Many of the libvips interpolators use fixed-point arithmetic for coordinate * calculation. This is how many bits of precision they use. */ /** * VIPS_TRANSFORM_SCALE: * - * #VIPS_TRANSFORM_SHIFT as a multiplicative constant. + * [const@TRANSFORM_SHIFT] as a multiplicative constant. */ /** @@ -303,7 +299,7 @@ vips_interpolate_get_window_offset(VipsInterpolate *interpolate) /** * VIPS_INTERPOLATE_SCALE: * - * #VIPS_INTERPOLATE_SHIFT as a multiplicative constant. + * [const@INTERPOLATE_SHIFT] as a multiplicative constant. */ /* VipsInterpolateNearest class @@ -619,7 +615,7 @@ vips_interpolate_bilinear_static(void) return interpolate; } -/* Called on startup: register the base vips interpolators. +/* Called on startup: register the base libvips interpolators. */ void vips__interpolate_init(void) @@ -643,11 +639,11 @@ vips__interpolate_init(void) * @nickname: nickname for interpolator * * Look up an interpolator from a nickname and make one. You need to free the - * result with g_object_unref() when you're done with it. + * result with [method@GObject.Object.unref] when you're done with it. * - * See also: vips_type_find(). + * See also: [func@type_find]. * - * Returns: an interpolator, or %NULL on error. + * Returns: an interpolator, or `NULL` on error. */ VipsInterpolate * vips_interpolate_new(const char *nickname) diff --git a/libvips/resample/reduce.c b/libvips/resample/reduce.c index 94fb8088b6..b1c5f773ec 100644 --- a/libvips/resample/reduce.c +++ b/libvips/resample/reduce.c @@ -72,70 +72,6 @@ * The resampling kernels vips supports. See vips_reduce(), for example. */ -/* gtk-doc does not see comments in C++ files, so we have these docs here. - */ - -/** - * vips_reducev: (method) - * @in: input image - * @out: (out): output image - * @vshrink: vertical reduce - * @...: %NULL-terminated list of optional named arguments - * - * Optional arguments: - * - * * @kernel: #VipsKernel to use to interpolate (default: lanczos3) - * * @gap: reducing gap to use (default: 0.0) - * - * Reduce @in vertically by a float factor. The pixels in @out are - * interpolated with a 1D mask generated by @kernel. - * - * Set @gap to speed up reducing by having vips_shrinkv() to shrink - * with a box filter first. The bigger @gap, the closer the result - * to the fair resampling. The smaller @gap, the faster resizing. - * The default value is 0.0 (no optimization). - * - * This is a very low-level operation: see vips_resize() for a more - * convenient way to resize images. - * - * This operation does not change xres or yres. The image resolution needs to - * be updated by the application. - * - * See also: vips_shrink(), vips_resize(), vips_affine(). - * - * Returns: 0 on success, -1 on error - */ - -/** - * vips_reduceh: (method) - * @in: input image - * @out: (out): output image - * @hshrink: horizontal reduce - * @...: %NULL-terminated list of optional named arguments - * - * Optional arguments: - * - * * @kernel: #VipsKernel to use to interpolate (default: lanczos3) - * * @gap: reducing gap to use (default: 0.0) - * - * Reduce @in horizontally by a float factor. The pixels in @out are - * interpolated with a 1D mask generated by @kernel. - * - * Set @gap to speed up reducing by having vips_shrinkh() to shrink - * with a box filter first. The bigger @gap, the closer the result - * to the fair resampling. The smaller @gap, the faster resizing. - * The default value is 0.0 (no optimization). - * - * This is a very low-level operation: see vips_resize() for a more - * convenient way to resize images. - * - * This operation does not change xres or yres. The image resolution needs to - * be updated by the application. - * - * See also: vips_shrink(), vips_resize(), vips_affine(). - * - * Returns: 0 on success, -1 on error - */ typedef struct _VipsReduce { VipsResample parent_instance; diff --git a/libvips/resample/reduceh.cpp b/libvips/resample/reduceh.cpp index d82521d6a8..7933f9f6e0 100644 --- a/libvips/resample/reduceh.cpp +++ b/libvips/resample/reduceh.cpp @@ -629,9 +629,36 @@ vips_reduceh_init(VipsReduceh *reduceh) reduceh->kernel = VIPS_KERNEL_LANCZOS3; } -/* See reduce.c for the doc comment. +/** + * vips_reduceh: (method) + * @in: input image + * @out: (out): output image + * @hshrink: horizontal reduce + * @...: %NULL-terminated list of optional named arguments + * + * Optional arguments: + * + * * @kernel: #VipsKernel to use to interpolate (default: lanczos3) + * * @gap: reducing gap to use (default: 0.0) + * + * Reduce @in horizontally by a float factor. The pixels in @out are + * interpolated with a 1D mask generated by @kernel. + * + * Set @gap to speed up reducing by having vips_shrinkh() to shrink + * with a box filter first. The bigger @gap, the closer the result + * to the fair resampling. The smaller @gap, the faster resizing. + * The default value is 0.0 (no optimization). + * + * This is a very low-level operation: see vips_resize() for a more + * convenient way to resize images. + * + * This operation does not change xres or yres. The image resolution needs to + * be updated by the application. + * + * See also: vips_shrink(), vips_resize(), vips_affine(). + * + * Returns: 0 on success, -1 on error */ - int vips_reduceh(VipsImage *in, VipsImage **out, double hshrink, ...) { diff --git a/libvips/resample/reducev.cpp b/libvips/resample/reducev.cpp index 4d68dd51bc..7bead22733 100644 --- a/libvips/resample/reducev.cpp +++ b/libvips/resample/reducev.cpp @@ -1113,9 +1113,36 @@ vips_reducev_init(VipsReducev *reducev) reducev->kernel = VIPS_KERNEL_LANCZOS3; } -/* See reduce.c for the doc comment. +/** + * vips_reducev: (method) + * @in: input image + * @out: (out): output image + * @vshrink: vertical reduce + * @...: %NULL-terminated list of optional named arguments + * + * Optional arguments: + * + * * @kernel: #VipsKernel to use to interpolate (default: lanczos3) + * * @gap: reducing gap to use (default: 0.0) + * + * Reduce @in vertically by a float factor. The pixels in @out are + * interpolated with a 1D mask generated by @kernel. + * + * Set @gap to speed up reducing by having vips_shrinkv() to shrink + * with a box filter first. The bigger @gap, the closer the result + * to the fair resampling. The smaller @gap, the faster resizing. + * The default value is 0.0 (no optimization). + * + * This is a very low-level operation: see vips_resize() for a more + * convenient way to resize images. + * + * This operation does not change xres or yres. The image resolution needs to + * be updated by the application. + * + * See also: vips_shrink(), vips_resize(), vips_affine(). + * + * Returns: 0 on success, -1 on error */ - int vips_reducev(VipsImage *in, VipsImage **out, double vshrink, ...) { diff --git a/meson.build b/meson.build index b4603ddb5c..92a2690bc6 100644 --- a/meson.build +++ b/meson.build @@ -659,11 +659,11 @@ build_summary = { {'enable debug': [get_option('debug')], 'enable deprecated': [get_option('deprecated')], 'enable modules': [modules_enabled], - 'enable gtk-doc': [get_option('gtk_doc')], - 'enable doxygen': [get_option('doxygen')], + 'enable docs': [get_option('docs')], + 'enable C++ docs': [get_option('cpp-docs')], 'enable introspection': [enable_introspection], 'enable examples': [get_option('examples')], - 'enable cplusplus': [get_option('cplusplus')], + 'enable C++ binding': [get_option('cplusplus')], 'enable RAD load/save': [get_option('radiance')], 'enable Analyze7 load': [get_option('analyze')], 'enable PPM load/save': [get_option('ppm')], @@ -727,8 +727,8 @@ foreach section_title, section: build_features endforeach subdir('libvips') -if get_option('gtk_doc') - subdir('doc') +if get_option('docs') + subdir('doc') endif if get_option('examples') subdir('examples') diff --git a/meson_options.txt b/meson_options.txt index 76ba6f7ced..175a46c5e6 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -15,15 +15,15 @@ option('cplusplus', value: true, description: 'Build C++ API') -option('doxygen', +option('cpp-docs', type: 'boolean', value: false, - description: 'Build C++ documentation') + description: 'Build C++ documentation (requires doxygen)') -option('gtk_doc', +option('docs', type: 'boolean', value: false, - description: 'Build GTK-doc documentation') + description: 'Build API reference and tools documentation (requires gi-docgen)') option('modules', type: 'feature', From 499ccb20cac55d53006ab3e8486d8c1379a34227 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 31 Mar 2025 12:04:23 +0100 Subject: [PATCH 098/174] Add CITATION.cff (#4440) * Add CITATION.cff * doc: update citation information --------- Co-authored-by: Kleis Auke Wolthuizen --- CITATION.cff | 25 +++++++++++++++++++++++++ doc/cite.md | 7 ++++++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 CITATION.cff diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000000..8871e27d43 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,25 @@ +cff-version: 1.2.0 +message: If you use this software, please cite it as below. +title: libvips +authors: + - family-names: libvips team +url: https://libvips.org +preferred-citation: + type: conference-paper + title: The libvips image processing library + authors: + - family-names: Cupitt + given-names: John + - family-names: Martinez + given-names: Kirk + - family-names: Fuller + given-names: Lovell + - family-names: Wolthuizen + given-names: Kleis Auke + collection-title: Electronic Imaging 2025 + collection-type: proceedings + month: 2 + year: 2025 + publisher: + name: Society for Imaging Science and Technology + url: "https://www.southampton.ac.uk/~km2/papers/2025/vips-ist-preprint.pdf" diff --git a/doc/cite.md b/doc/cite.md index 6006a7d104..2759aa6132 100644 --- a/doc/cite.md +++ b/doc/cite.md @@ -1,6 +1,11 @@ Title: References to cite for libvips -# libvips References +# libvips References + +Cupitt, J., Martinez, K., Fuller, L. and Wolthuizen, K. A. (2025) +[The libvips image processing library]( +https://www.southampton.ac.uk/~km2/papers/2025/vips-ist-preprint.pdf). In Proceedings of Electronic +Imaging 2025, Burlingame. Martinez, K. and Cupitt, J. (2005) [VIPS -- a highly tuned image processing software architecture]( From 1cc60482b15f9ca76817607e7b846cfe89f66672 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 31 Mar 2025 14:18:57 +0200 Subject: [PATCH 099/174] doc: mark gi-docgen test as xfail (#4442) --- doc/meson.build | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/meson.build b/doc/meson.build index e0f1aad115..cceda24121 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -69,5 +69,8 @@ test('doc-check-vips', vips_gir[0], ], depends: vips_gir[0], - suite: ['docs', 'failing'], + # FIXME: Remove once we have documented all public-facing symbols, + # parameters and return values. + should_fail: true, + suite: ['docs'], ) From aab0cd33686860523ca133929245ea7c1a6efb31 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 31 Mar 2025 14:34:53 +0200 Subject: [PATCH 100/174] Add C declaration for fitsload_source (#4441) --- doc/function-list.md | 12 ++++++------ doc/gen-function-list.py | 6 +++--- doc/rename.sed | 6 +++--- libvips/include/vips/foreign.h | 3 +++ 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/doc/function-list.md b/doc/function-list.md index 34f49f94de..fefdf3e7e7 100644 --- a/doc/function-list.md +++ b/doc/function-list.md @@ -25,10 +25,10 @@ libvips has a set of C wrapper functions for calling operators, in this case [method@Image.gamma]: ```c - VipsImage *fred = ...; - VipsImage *jim; +VipsImage *fred = ...; +VipsImage *jim; - if (vips_gamma(fred, &jim, NULL)) +if (vips_gamma(fred, &jim, NULL)) ...error; ``` @@ -128,8 +128,8 @@ API docs each function links to for more details. | `fastcor` | Fast correlation | [method@Image.fastcor] | | `fill_nearest` | Fill image zeros with nearest non-zero pixel | [method@Image.fill_nearest] | | `find_trim` | Search an image for non-edge areas | [method@Image.find_trim] | -| `fitsload` | Load a fits image | [method@Image.fitsload] | -| `fitsload_source` | Load fits from a source | [method@Image.fitsload_source] | +| `fitsload` | Load a fits image | [func@fitsload] | +| `fitsload_source` | Load fits from a source | [func@fitsload_source] | | `fitssave` | Save image to fits file | [method@Image.fitssave] | | `flatten` | Flatten alpha out of an image | [method@Image.flatten] | | `flip` | Flip an image | [method@Image.flip] | @@ -194,7 +194,7 @@ API docs each function links to for more details. | `jpegsave_buffer` | Save image to jpeg buffer | [method@Image.jpegsave_buffer] | | `jpegsave_mime` | Save image to jpeg mime | [method@Image.jpegsave_mime] | | `jpegsave_target` | Save image to jpeg target | [method@Image.jpegsave_target] | -| `jxlload` | Load jpeg-xl image | [method@Image.jxlload] | +| `jxlload` | Load jpeg-xl image | [func@jxlload] | | `jxlload_buffer` | Load jpeg-xl image | [func@jxlload_buffer] | | `jxlload_source` | Load jpeg-xl image | [func@jxlload_source] | | `jxlsave` | Save image in jpeg-xl format | [method@Image.jxlsave] | diff --git a/doc/gen-function-list.py b/doc/gen-function-list.py index 5755af59c4..46fb55f8f4 100755 --- a/doc/gen-function-list.py +++ b/doc/gen-function-list.py @@ -138,10 +138,10 @@ def add_nickname(gtype, a, b): case [method@Image.gamma]: ```c - VipsImage *fred = ...; - VipsImage *jim; +VipsImage *fred = ...; +VipsImage *jim; - if (vips_gamma(fred, &jim, NULL)) +if (vips_gamma(fred, &jim, NULL)) ...error; ``` diff --git a/doc/rename.sed b/doc/rename.sed index 9ed1afb95e..3a1c10de9b 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -114,8 +114,8 @@ s/vips_\(falsecolour\)()/[method@Image.\1]/g s/vips_\(fastcor\)()/[method@Image.\1]/g s/vips_\(fill_nearest\)()/[method@Image.\1]/g s/vips_\(find_trim\)()/[method@Image.\1]/g -s/vips_\(fitsload\)()/[method@Image.\1]/g -s/vips_\(fitsload_source\)()/[method@Image.\1]/g +s/vips_\(fitsload\)()/[func@\1]/g +s/vips_\(fitsload_source\)()/[func@\1]/g s/vips_\(fitssave\)()/[method@Image.\1]/g s/vips_\(flatten\)()/[method@Image.\1]/g s/vips_\(flip\)()/[method@Image.\1]/g @@ -166,7 +166,7 @@ s/vips_\(jpegsave_buffer\)()/[method@Image.\1]/g s/vips_\(jpegsave\)()/[method@Image.\1]/g s/vips_\(jpegsave_mime\)()/[method@Image.\1]/g s/vips_\(jpegsave_target\)()/[method@Image.\1]/g -s/vips_\(jxlload\)()/[method@Image.\1]/g +s/vips_\(jxlload\)()/[func@\1]/g s/vips_\(jxlsave_buffer\)()/[method@Image.\1]/g s/vips_\(jxlsave\)()/[method@Image.\1]/g s/vips_\(jxlsave_target\)()/[method@Image.\1]/g diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index 51d8086e0a..8242861cdc 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -628,6 +628,9 @@ VIPS_API int vips_fitsload(const char *filename, VipsImage **out, ...) G_GNUC_NULL_TERMINATED; VIPS_API +int vips_fitsload_source(VipsSource *source, VipsImage **out, ...) + G_GNUC_NULL_TERMINATED; +VIPS_API int vips_fitssave(VipsImage *in, const char *filename, ...) G_GNUC_NULL_TERMINATED; From 83d4b6cf700ebc492624eb7eb339244e63954d5d Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 31 Mar 2025 19:02:21 +0200 Subject: [PATCH 101/174] doc: make the load functions part of the image ctors (#4444) --- doc/fixup-load-as-ctor.py | 48 ++++++++++++++++ doc/function-list.md | 108 +++++++++++++++++------------------ doc/meson.build | 10 +++- doc/rename.sed | 6 +- libvips/iofuncs/connection.c | 2 +- libvips/iofuncs/header.c | 2 +- 6 files changed, 116 insertions(+), 60 deletions(-) create mode 100755 doc/fixup-load-as-ctor.py diff --git a/doc/fixup-load-as-ctor.py b/doc/fixup-load-as-ctor.py new file mode 100755 index 0000000000..3a18b9d4f1 --- /dev/null +++ b/doc/fixup-load-as-ctor.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 + +import argparse +import xml.etree.ElementTree as ET +from pathlib import Path + + +def register_all_namespaces(filename): + namespaces = dict([node for _, node in ET.iterparse(filename, events=['start-ns'])]) + for ns in namespaces: + ET.register_namespace(ns, namespaces[ns]) + + +def fixup_load_as_ctor(args): + tree = ET.parse(args.in_path) + root = tree.getroot() + + register_all_namespaces(args.in_path) + namespace = { + 'goi': 'http://www.gtk.org/introspection/core/1.0' + } + + namespace_node = root.find('goi:namespace', namespace) + image_node = namespace_node.find('goi:class[@name="Image"]', namespace) + + # Ensure every *load* function is changed to an Image ctor + for node in namespace_node.findall('goi:function', namespace): + name = node.get('name') + if 'load' in name: + namespace_node.remove(node) + + node.tag = 'constructor' + image_node.append(node) + + tree.write(args.out_path, encoding='utf-8', xml_declaration=True) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('in_path', help='input file', type=Path) + parser.add_argument('out_path', help='output file', type=Path) + + args = parser.parse_args() + fixup_load_as_ctor(args) + + +if __name__ == "__main__": + main() diff --git a/doc/function-list.md b/doc/function-list.md index fefdf3e7e7..db9e0a7757 100644 --- a/doc/function-list.md +++ b/doc/function-list.md @@ -65,7 +65,7 @@ API docs each function links to for more details. | `add` | Add two images | [method@Image.add] | | `addalpha` | Append an alpha channel | [method@Image.addalpha] | | `affine` | Affine transform of an image | [method@Image.affine] | -| `analyzeload` | Load an analyze6 image | [func@analyzeload] | +| `analyzeload` | Load an analyze6 image | [ctor@Image.analyzeload] | | `arrayjoin` | Join an array of images | [func@arrayjoin] | | `autorot` | Autorotate image by exif tag | [method@Image.autorot] | | `avg` | Find image average | [method@Image.avg] | @@ -101,8 +101,8 @@ API docs each function links to for more details. | `convsep` | Separable convolution operation | [method@Image.convsep] | | `copy` | Copy an image | [method@Image.copy] | | `countlines` | Count lines in an image | [method@Image.countlines] | -| `csvload` | Load csv | [func@csvload] | -| `csvload_source` | Load csv | [func@csvload_source] | +| `csvload` | Load csv | [ctor@Image.csvload] | +| `csvload_source` | Load csv | [ctor@Image.csvload_source] | | `csvsave` | Save image to csv | [method@Image.csvsave] | | `csvsave_target` | Save image to csv | [method@Image.csvsave_target] | | `dE00` | Calculate de00 | [method@Image.dE00] | @@ -128,8 +128,8 @@ API docs each function links to for more details. | `fastcor` | Fast correlation | [method@Image.fastcor] | | `fill_nearest` | Fill image zeros with nearest non-zero pixel | [method@Image.fill_nearest] | | `find_trim` | Search an image for non-edge areas | [method@Image.find_trim] | -| `fitsload` | Load a fits image | [func@fitsload] | -| `fitsload_source` | Load fits from a source | [func@fitsload_source] | +| `fitsload` | Load a fits image | [ctor@Image.fitsload] | +| `fitsload_source` | Load fits from a source | [ctor@Image.fitsload_source] | | `fitssave` | Save image to fits file | [method@Image.fitssave] | | `flatten` | Flatten alpha out of an image | [method@Image.flatten] | | `flip` | Flip an image | [method@Image.flip] | @@ -142,9 +142,9 @@ API docs each function links to for more details. | `gaussmat` | Make a gaussian image | [func@gaussmat] | | `gaussnoise` | Make a gaussnoise image | [func@gaussnoise] | | `getpoint` | Read a point from an image | [method@Image.getpoint] | -| `gifload` | Load gif with libnsgif | [func@gifload] | -| `gifload_buffer` | Load gif with libnsgif | [func@gifload_buffer] | -| `gifload_source` | Load gif from source | [func@gifload_source] | +| `gifload` | Load gif with libnsgif | [ctor@Image.gifload] | +| `gifload_buffer` | Load gif with libnsgif | [ctor@Image.gifload_buffer] | +| `gifload_source` | Load gif from source | [ctor@Image.gifload_source] | | `gifsave` | Save as gif | [method@Image.gifsave] | | `gifsave_buffer` | Save as gif | [method@Image.gifsave_buffer] | | `gifsave_target` | Save as gif | [method@Image.gifsave_target] | @@ -152,9 +152,9 @@ API docs each function links to for more details. | `gravity` | Place an image within a larger image with a certain gravity | [method@Image.gravity] | | `grey` | Make a grey ramp image | [func@grey] | | `grid` | Grid an image | [method@Image.grid] | -| `heifload` | Load a heif image | [func@heifload] | -| `heifload_buffer` | Load a heif image | [func@heifload_buffer] | -| `heifload_source` | Load a heif image | [func@heifload_source] | +| `heifload` | Load a heif image | [ctor@Image.heifload] | +| `heifload_buffer` | Load a heif image | [ctor@Image.heifload_buffer] | +| `heifload_source` | Load a heif image | [ctor@Image.heifload_source] | | `heifsave` | Save image in heif format | [method@Image.heifsave] | | `heifsave_buffer` | Save image in heif format | [method@Image.heifsave_buffer] | | `heifsave_target` | Save image in heif format | [method@Image.heifsave_target] | @@ -181,22 +181,22 @@ API docs each function links to for more details. | `invertlut` | Build an inverted look-up table | [method@Image.invertlut] | | `invfft` | Inverse fft | [method@Image.invfft] | | `join` | Join a pair of images | [method@Image.join] | -| `jp2kload` | Load jpeg2000 image | [func@jp2kload] | -| `jp2kload_buffer` | Load jpeg2000 image | [func@jp2kload_buffer] | -| `jp2kload_source` | Load jpeg2000 image | [func@jp2kload_source] | +| `jp2kload` | Load jpeg2000 image | [ctor@Image.jp2kload] | +| `jp2kload_buffer` | Load jpeg2000 image | [ctor@Image.jp2kload_buffer] | +| `jp2kload_source` | Load jpeg2000 image | [ctor@Image.jp2kload_source] | | `jp2ksave` | Save image in jpeg2000 format | [method@Image.jp2ksave] | | `jp2ksave_buffer` | Save image in jpeg2000 format | [method@Image.jp2ksave_buffer] | | `jp2ksave_target` | Save image in jpeg2000 format | [method@Image.jp2ksave_target] | -| `jpegload` | Load jpeg from file | [func@jpegload] | -| `jpegload_buffer` | Load jpeg from buffer | [func@jpegload_buffer] | -| `jpegload_source` | Load image from jpeg source | [func@jpegload_source] | +| `jpegload` | Load jpeg from file | [ctor@Image.jpegload] | +| `jpegload_buffer` | Load jpeg from buffer | [ctor@Image.jpegload_buffer] | +| `jpegload_source` | Load image from jpeg source | [ctor@Image.jpegload_source] | | `jpegsave` | Save image to jpeg file | [method@Image.jpegsave] | | `jpegsave_buffer` | Save image to jpeg buffer | [method@Image.jpegsave_buffer] | | `jpegsave_mime` | Save image to jpeg mime | [method@Image.jpegsave_mime] | | `jpegsave_target` | Save image to jpeg target | [method@Image.jpegsave_target] | -| `jxlload` | Load jpeg-xl image | [func@jxlload] | -| `jxlload_buffer` | Load jpeg-xl image | [func@jxlload_buffer] | -| `jxlload_source` | Load jpeg-xl image | [func@jxlload_source] | +| `jxlload` | Load jpeg-xl image | [ctor@Image.jxlload] | +| `jxlload_buffer` | Load jpeg-xl image | [ctor@Image.jxlload_buffer] | +| `jxlload_source` | Load jpeg-xl image | [ctor@Image.jxlload_source] | | `jxlsave` | Save image in jpeg-xl format | [method@Image.jxlsave] | | `jxlsave_buffer` | Save image in jpeg-xl format | [method@Image.jxlsave_buffer] | | `jxlsave_target` | Save image in jpeg-xl format | [method@Image.jxlsave_target] | @@ -204,8 +204,8 @@ API docs each function links to for more details. | `linear` | Calculate (a * in + b) | [method@Image.linear], [method@Image.linear1] | | `linecache` | Cache an image as a set of lines | [method@Image.linecache] | | `logmat` | Make a laplacian of gaussian image | [func@logmat] | -| `magickload` | Load file with imagemagick | [func@magickload] | -| `magickload_buffer` | Load buffer with imagemagick | [func@magickload_buffer] | +| `magickload` | Load file with imagemagick | [ctor@Image.magickload] | +| `magickload_buffer` | Load buffer with imagemagick | [ctor@Image.magickload_buffer] | | `magicksave` | Save file with imagemagick | [method@Image.magicksave] | | `magicksave_buffer` | Save image to magick buffer | [method@Image.magicksave_buffer] | | `mapim` | Resample with a map image | [method@Image.mapim] | @@ -224,10 +224,10 @@ API docs each function links to for more details. | `math` | Apply a math operation to an image | [method@Image.math], [method@Image.sin], [method@Image.cos], [method@Image.tan], [method@Image.asin], [method@Image.acos], [method@Image.atan], [method@Image.sinh], [method@Image.cosh], [method@Image.tanh], [method@Image.asinh], [method@Image.acosh], [method@Image.atanh], [method@Image.exp], [method@Image.exp10], [method@Image.log], [method@Image.log10] | | `math2` | Binary math operations | [method@Image.math2], [method@Image.pow], [method@Image.wop], [method@Image.atan2] | | `math2_const` | Binary math operations with a constant | [method@Image.math2_const], [method@Image.andimage_const], [method@Image.orimage_const], [method@Image.eorimage_const], [method@Image.lshift_const], [method@Image.rshift_const], [method@Image.math2_const1], [method@Image.andimage_const1], [method@Image.orimage_const1], [method@Image.eorimage_const1], [method@Image.lshift_const1], [method@Image.rshift_const1] | -| `matload` | Load mat from file | [func@matload] | +| `matload` | Load mat from file | [ctor@Image.matload] | | `matrixinvert` | Invert a matrix | [method@Image.matrixinvert] | -| `matrixload` | Load matrix | [func@matrixload] | -| `matrixload_source` | Load matrix | [func@matrixload_source] | +| `matrixload` | Load matrix | [ctor@Image.matrixload] | +| `matrixload_source` | Load matrix | [ctor@Image.matrixload_source] | | `matrixmultiply` | Multiply two matrices | [method@Image.matrixmultiply] | | `matrixprint` | Print matrix | [method@Image.matrixprint] | | `matrixsave` | Save image to matrix | [method@Image.matrixsave] | @@ -243,43 +243,43 @@ API docs each function links to for more details. | `mosaic1` | First-order mosaic of two images | [method@Image.mosaic1] | | `msb` | Pick most-significant byte from an image | [method@Image.msb] | | `multiply` | Multiply two images | [method@Image.multiply] | -| `niftiload` | Load nifti volume | [func@niftiload] | -| `niftiload_source` | Load nifti volumes | [func@niftiload_source] | +| `niftiload` | Load nifti volume | [ctor@Image.niftiload] | +| `niftiload_source` | Load nifti volumes | [ctor@Image.niftiload_source] | | `niftisave` | Save image to nifti file | [method@Image.niftisave] | -| `openexrload` | Load an openexr image | [func@openexrload] | -| `openslideload` | Load file with openslide | [func@openslideload] | -| `openslideload_source` | Load source with openslide | [func@openslideload_source] | -| `pdfload` | Load pdf from file | [func@pdfload] | -| `pdfload_buffer` | Load pdf from buffer | [func@pdfload_buffer] | -| `pdfload_source` | Load pdf from source | [func@pdfload_source] | +| `openexrload` | Load an openexr image | [ctor@Image.openexrload] | +| `openslideload` | Load file with openslide | [ctor@Image.openslideload] | +| `openslideload_source` | Load source with openslide | [ctor@Image.openslideload_source] | +| `pdfload` | Load pdf from file | [ctor@Image.pdfload] | +| `pdfload_buffer` | Load pdf from buffer | [ctor@Image.pdfload_buffer] | +| `pdfload_source` | Load pdf from source | [ctor@Image.pdfload_source] | | `percent` | Find threshold for percent of pixels | [method@Image.percent] | | `perlin` | Make a perlin noise image | [func@perlin] | | `phasecor` | Calculate phase correlation | [method@Image.phasecor] | -| `pngload` | Load png from file | [func@pngload] | -| `pngload_buffer` | Load png from buffer | [func@pngload_buffer] | -| `pngload_source` | Load png from source | [func@pngload_source] | +| `pngload` | Load png from file | [ctor@Image.pngload] | +| `pngload_buffer` | Load png from buffer | [ctor@Image.pngload_buffer] | +| `pngload_source` | Load png from source | [ctor@Image.pngload_source] | | `pngsave` | Save image to file as png | [method@Image.pngsave] | | `pngsave_buffer` | Save image to buffer as png | [method@Image.pngsave_buffer] | | `pngsave_target` | Save image to target as png | [method@Image.pngsave_target] | -| `ppmload` | Load ppm from file | [func@ppmload] | -| `ppmload_source` | Load ppm base class | [func@ppmload_source] | +| `ppmload` | Load ppm from file | [ctor@Image.ppmload] | +| `ppmload_source` | Load ppm base class | [ctor@Image.ppmload_source] | | `ppmsave` | Save image to ppm file | [method@Image.ppmsave] | | `ppmsave_target` | Save to ppm | [method@Image.ppmsave_target] | | `premultiply` | Premultiply image alpha | [method@Image.premultiply] | | `prewitt` | Prewitt edge detector | [method@Image.prewitt] | | `profile` | Find image profiles | [method@Image.profile] | -| `profile_load` | Load named icc profile | [func@profile_load] | +| `profile_load` | Load named icc profile | [ctor@Image.profile_load] | | `project` | Find image projections | [method@Image.project] | | `quadratic` | Resample an image with a quadratic transform | [method@Image.quadratic] | | `rad2float` | Unpack radiance coding to float rgb | [method@Image.rad2float] | -| `radload` | Load a radiance image from a file | [func@radload] | -| `radload_buffer` | Load rad from buffer | [func@radload_buffer] | -| `radload_source` | Load rad from source | [func@radload_source] | +| `radload` | Load a radiance image from a file | [ctor@Image.radload] | +| `radload_buffer` | Load rad from buffer | [ctor@Image.radload_buffer] | +| `radload_source` | Load rad from source | [ctor@Image.radload_source] | | `radsave` | Save image to radiance file | [method@Image.radsave] | | `radsave_buffer` | Save image to radiance buffer | [method@Image.radsave_buffer] | | `radsave_target` | Save image to radiance target | [method@Image.radsave_target] | | `rank` | Rank filter | [method@Image.rank], [method@Image.median] | -| `rawload` | Load raw data from a file | [func@rawload] | +| `rawload` | Load raw data from a file | [ctor@Image.rawload] | | `rawsave` | Save image to raw file | [method@Image.rawsave] | | `rawsave_buffer` | Write raw image to buffer | [method@Image.rawsave_buffer] | | `rawsave_target` | Write raw image to target | [method@Image.rawsave_target] | @@ -322,9 +322,9 @@ API docs each function links to for more details. | `subsample` | Subsample an image | [method@Image.subsample] | | `subtract` | Subtract two images | [method@Image.subtract] | | `sum` | Sum an array of images | [func@sum] | -| `svgload` | Load svg with rsvg | [func@svgload] | -| `svgload_buffer` | Load svg with rsvg | [func@svgload_buffer] | -| `svgload_source` | Load svg from source | [func@svgload_source] | +| `svgload` | Load svg with rsvg | [ctor@Image.svgload] | +| `svgload_buffer` | Load svg with rsvg | [ctor@Image.svgload_buffer] | +| `svgload_source` | Load svg from source | [ctor@Image.svgload_source] | | `switch` | Find the index of the first non-zero pixel in tests | [func@switch] | | `system` | Run an external command | [func@system] | | `text` | Make a text image | [func@text] | @@ -332,9 +332,9 @@ API docs each function links to for more details. | `thumbnail_buffer` | Generate thumbnail from buffer | [func@thumbnail_buffer] | | `thumbnail_image` | Generate thumbnail from image | [method@Image.thumbnail_image] | | `thumbnail_source` | Generate thumbnail from source | [func@thumbnail_source] | -| `tiffload` | Load tiff from file | [func@tiffload] | -| `tiffload_buffer` | Load tiff from buffer | [func@tiffload_buffer] | -| `tiffload_source` | Load tiff from source | [func@tiffload_source] | +| `tiffload` | Load tiff from file | [ctor@Image.tiffload] | +| `tiffload_buffer` | Load tiff from buffer | [ctor@Image.tiffload_buffer] | +| `tiffload_source` | Load tiff from source | [ctor@Image.tiffload_source] | | `tiffsave` | Save image to tiff file | [method@Image.tiffsave] | | `tiffsave_buffer` | Save image to tiff buffer | [method@Image.tiffsave_buffer] | | `tiffsave_target` | Save image to tiff target | [method@Image.tiffsave_target] | @@ -342,13 +342,13 @@ API docs each function links to for more details. | `tonelut` | Build a look-up table | [func@tonelut] | | `transpose3d` | Transpose3d an image | [method@Image.transpose3d] | | `unpremultiply` | Unpremultiply image alpha | [method@Image.unpremultiply] | -| `vipsload` | Load vips from file | [func@vipsload] | -| `vipsload_source` | Load vips from source | [func@vipsload_source] | +| `vipsload` | Load vips from file | [ctor@Image.vipsload] | +| `vipsload_source` | Load vips from source | [ctor@Image.vipsload_source] | | `vipssave` | Save image to file in vips format | [method@Image.vipssave] | | `vipssave_target` | Save image to target in vips format | [method@Image.vipssave_target] | -| `webpload` | Load webp from file | [func@webpload] | -| `webpload_buffer` | Load webp from buffer | [func@webpload_buffer] | -| `webpload_source` | Load webp from source | [func@webpload_source] | +| `webpload` | Load webp from file | [ctor@Image.webpload] | +| `webpload_buffer` | Load webp from buffer | [ctor@Image.webpload_buffer] | +| `webpload_source` | Load webp from source | [ctor@Image.webpload_source] | | `webpsave` | Save as webp | [method@Image.webpsave] | | `webpsave_buffer` | Save as webp | [method@Image.webpsave_buffer] | | `webpsave_mime` | Save image to webp mime | [method@Image.webpsave_mime] | diff --git a/doc/meson.build b/doc/meson.build index cceda24121..421982533e 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -39,8 +39,16 @@ vips_toml = configure_file( install_dir: docs_dir / 'vips', ) +fixup_load_as_ctor = find_program('fixup-load-as-ctor.py') + +vips_gir_doc = custom_target( + input: vips_gir[0], + output: 'Vips-@0@.0-doc.gir'.format(version_major), + command: [fixup_load_as_ctor, '@INPUT@', '@OUTPUT@'], +) + custom_target('libvips-doc', - input: [vips_toml, vips_gir[0]], + input: [vips_toml, vips_gir_doc], output: 'vips', command: [ gidocgen, diff --git a/doc/rename.sed b/doc/rename.sed index 3a1c10de9b..13343c5a84 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -114,8 +114,8 @@ s/vips_\(falsecolour\)()/[method@Image.\1]/g s/vips_\(fastcor\)()/[method@Image.\1]/g s/vips_\(fill_nearest\)()/[method@Image.\1]/g s/vips_\(find_trim\)()/[method@Image.\1]/g -s/vips_\(fitsload\)()/[func@\1]/g -s/vips_\(fitsload_source\)()/[func@\1]/g +s/vips_\(fitsload\)()/[ctor@Image.\1]/g +s/vips_\(fitsload_source\)()/[ctor@Image.\1]/g s/vips_\(fitssave\)()/[method@Image.\1]/g s/vips_\(flatten\)()/[method@Image.\1]/g s/vips_\(flip\)()/[method@Image.\1]/g @@ -166,7 +166,7 @@ s/vips_\(jpegsave_buffer\)()/[method@Image.\1]/g s/vips_\(jpegsave\)()/[method@Image.\1]/g s/vips_\(jpegsave_mime\)()/[method@Image.\1]/g s/vips_\(jpegsave_target\)()/[method@Image.\1]/g -s/vips_\(jxlload\)()/[func@\1]/g +s/vips_\(jxlload\)()/[ctor@Image.\1]/g s/vips_\(jxlsave_buffer\)()/[method@Image.\1]/g s/vips_\(jxlsave\)()/[method@Image.\1]/g s/vips_\(jxlsave_target\)()/[method@Image.\1]/g diff --git a/libvips/iofuncs/connection.c b/libvips/iofuncs/connection.c index ab3f85b945..2c3e43c1d3 100644 --- a/libvips/iofuncs/connection.c +++ b/libvips/iofuncs/connection.c @@ -62,7 +62,7 @@ * * It can be connected to a network socket, for example, or perhaps * a Node.js stream, or to an area of memory. This allows it to support - * operations like JPEG loading, see for example [func@jpegload_source]. + * operations like JPEG loading, see for example [ctor@Image.jpegload_source]. * * Subclass to add other input sources. Use [class@SourceCustom] and * [class@TargetCustom] to make a source or target with action signals. diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 1155f69ecd..345ce9408d 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -1039,7 +1039,7 @@ vips_image_get_data(VipsImage *image) * Normally you copy the fields from your input images with * [method.Image.pipelinev] and then make any adjustments you need, * but if you are creating an image from scratch, for example [func@black] - * or [func@jpegload], you do need to set all the fields yourself. + * or [ctor@Image.jpegload], you do need to set all the fields yourself. * * See also: [method.Image.pipelinev]. */ From 4b71888be5cca546a7847606430d808de1d16bd5 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 1 Apr 2025 11:15:37 +0200 Subject: [PATCH 102/174] doc: improve GIR fixup script (#4445) - Convert remaining functions to image constructors. - Make functions with multiple image inputs part of the image class. Follow up to: #4444. --- doc/developer-checklist.md | 24 ++++++---- doc/fixup-gir-for-doc.py | 96 ++++++++++++++++++++++++++++++++++++++ doc/fixup-load-as-ctor.py | 48 ------------------- doc/function-list.md | 72 ++++++++++++++-------------- doc/libvips-arithmetic.md | 2 +- doc/meson.build | 4 +- doc/using-the-cli.md | 2 +- doc/using-vipsthumbnail.md | 4 +- libvips/iofuncs/header.c | 5 +- 9 files changed, 155 insertions(+), 102 deletions(-) create mode 100755 doc/fixup-gir-for-doc.py delete mode 100755 doc/fixup-load-as-ctor.py diff --git a/doc/developer-checklist.md b/doc/developer-checklist.md index d385d2ce0d..ab2a80dd97 100644 --- a/doc/developer-checklist.md +++ b/doc/developer-checklist.md @@ -5,11 +5,12 @@ Title: Checklist for libvips users libvips is a slightly unusual library and you may need to take some of its stranger features into account when you design software that uses it. -## If you can, use [func@thumbnail], not [method@Image.resize] +## If you can, use [ctor@Image.thumbnail], not [method@Image.resize] -The [func@thumbnail] operation combines load and resize into one step. This -lets it take advantage of format library features, such as shrink on load, -and can lead to a large improvement in speed and a large drop in memory use. +The [ctor@Image.thumbnail] operation combines load and resize into one step. +This lets it take advantage of format library features, such as shrink on +load, and can lead to a large improvement in speed and a large drop in memory +use. For example, with this JPEG image: @@ -40,16 +41,18 @@ $ /usr/bin/time -f %M:%e vips > /dev/null 31232:0.02 ``` -31 MB and 0.02s, so [func@thumbnail] is really 2.5x less memory and 4x faster. +31 MB and 0.02s, so [ctor@Image.thumbnail] is really 2.5x less memory and +4x faster. You can see much larger improvements with other formats, and quality will -often be better as well, since [func@thumbnail] will automatically premultiply -and can render vector images directly at the correct size. +often be better as well, since [ctor@Image.thumbnail] will automatically +premultiply and can render vector images directly at the correct size. ## Don't use [method@Image.thumbnail_image] It's just there for emergencies. It can't do any of the rendering tricks, -so it's no faster than [method@Image.resize]. Use [func@thumbnail] if you can. +so it's not faster than [method@Image.resize]. Use [ctor@Image.thumbnail] if +you can. ## Use sequential mode if you can @@ -85,8 +88,9 @@ This can raise memory use, of course. ## Adjust the order of operations in pipelines -If you can, put large resizes right at the start (see [func@thumbnail] above), -then area filters (sharpen, for example), and finally any point operations. +If you can, put large resizes right at the start (see [ctor@Image.thumbnail] +above), then area filters (sharpen, for example), and finally any point +operations. ## Only enable the load libraries you need diff --git a/doc/fixup-gir-for-doc.py b/doc/fixup-gir-for-doc.py new file mode 100755 index 0000000000..25214f42a4 --- /dev/null +++ b/doc/fixup-gir-for-doc.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 + +import argparse +import xml.etree.ElementTree as ET +from pathlib import Path + + +def register_all_namespaces(filename): + namespaces = dict([node for _, node in ET.iterparse(filename, events=['start-ns'])]) + for ns in namespaces: + ET.register_namespace(ns, namespaces[ns]) + + +def fixup_gir_for_doc(args): + tree = ET.parse(args.in_path) + root = tree.getroot() + + register_all_namespaces(args.in_path) + namespace = { + 'goi': 'http://www.gtk.org/introspection/core/1.0' + } + + namespace_node = root.find('goi:namespace', namespace) + image_node = namespace_node.find('goi:class[@name="Image"]', namespace) + + # A list of functions that needs to be converted to an Image constructor. + # Note that all functions containing "load" are already converted. + image_ctors = [ + 'black', + 'eye', + 'fractsurf', + 'gaussmat', + 'gaussnoise', + 'grey', + 'identity', + 'logmat', + 'mask_butterworth', + 'mask_butterworth_band', + 'mask_butterworth_ring', + 'mask_fractal', + 'mask_gaussian', + 'mask_gaussian_band', + 'mask_gaussian_ring', + 'mask_ideal', + 'mask_ideal_band', + 'mask_ideal_ring', + 'perlin', + 'sdf', + 'sines', + 'system', + 'text', + 'thumbnail', + 'thumbnail_buffer', + 'thumbnail_source', + 'tonelut', + 'worley', + 'xyz', + 'zone', + ] + + # Functions that take multiple images as input argument ... make them + # part of the Image class. + image_funcs = [ + 'arrayjoin', + 'bandjoin', + 'bandrank', + 'composite', + 'sum', + 'switch', + ] + + for node in namespace_node.findall('goi:function', namespace): + name = node.get('name') + if 'load' in name or name in image_ctors: + namespace_node.remove(node) + + node.tag = 'constructor' + image_node.append(node) + elif name in image_funcs: + namespace_node.remove(node) + image_node.append(node) + + tree.write(args.out_path, encoding='utf-8', xml_declaration=True) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('in_path', help='input file', type=Path) + parser.add_argument('out_path', help='output file', type=Path) + + args = parser.parse_args() + fixup_gir_for_doc(args) + + +if __name__ == '__main__': + main() diff --git a/doc/fixup-load-as-ctor.py b/doc/fixup-load-as-ctor.py deleted file mode 100755 index 3a18b9d4f1..0000000000 --- a/doc/fixup-load-as-ctor.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import xml.etree.ElementTree as ET -from pathlib import Path - - -def register_all_namespaces(filename): - namespaces = dict([node for _, node in ET.iterparse(filename, events=['start-ns'])]) - for ns in namespaces: - ET.register_namespace(ns, namespaces[ns]) - - -def fixup_load_as_ctor(args): - tree = ET.parse(args.in_path) - root = tree.getroot() - - register_all_namespaces(args.in_path) - namespace = { - 'goi': 'http://www.gtk.org/introspection/core/1.0' - } - - namespace_node = root.find('goi:namespace', namespace) - image_node = namespace_node.find('goi:class[@name="Image"]', namespace) - - # Ensure every *load* function is changed to an Image ctor - for node in namespace_node.findall('goi:function', namespace): - name = node.get('name') - if 'load' in name: - namespace_node.remove(node) - - node.tag = 'constructor' - image_node.append(node) - - tree.write(args.out_path, encoding='utf-8', xml_declaration=True) - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument('in_path', help='input file', type=Path) - parser.add_argument('out_path', help='output file', type=Path) - - args = parser.parse_args() - fixup_load_as_ctor(args) - - -if __name__ == "__main__": - main() diff --git a/doc/function-list.md b/doc/function-list.md index db9e0a7757..ee86f40b5e 100644 --- a/doc/function-list.md +++ b/doc/function-list.md @@ -66,17 +66,17 @@ API docs each function links to for more details. | `addalpha` | Append an alpha channel | [method@Image.addalpha] | | `affine` | Affine transform of an image | [method@Image.affine] | | `analyzeload` | Load an analyze6 image | [ctor@Image.analyzeload] | -| `arrayjoin` | Join an array of images | [func@arrayjoin] | +| `arrayjoin` | Join an array of images | [func@Image.arrayjoin] | | `autorot` | Autorotate image by exif tag | [method@Image.autorot] | | `avg` | Find image average | [method@Image.avg] | | `bandbool` | Boolean operation across image bands | [method@Image.bandbool], [method@Image.bandand], [method@Image.bandor], [method@Image.bandeor], [method@Image.bandmean] | | `bandfold` | Fold up x axis into bands | [method@Image.bandfold] | -| `bandjoin` | Bandwise join a set of images | [func@bandjoin], [method@Image.bandjoin2] | +| `bandjoin` | Bandwise join a set of images | [func@Image.bandjoin], [method@Image.bandjoin2] | | `bandjoin_const` | Append a constant band to an image | [method@Image.bandjoin_const], [method@Image.bandjoin_const1] | | `bandmean` | Band-wise average | [method@Image.bandmean] | -| `bandrank` | Band-wise rank of a set of images | [func@bandrank] | +| `bandrank` | Band-wise rank of a set of images | [func@Image.bandrank] | | `bandunfold` | Unfold image bands into x axis | [method@Image.bandunfold] | -| `black` | Make a black image | [func@black] | +| `black` | Make a black image | [ctor@Image.black] | | `boolean` | Boolean operation on two images | [method@Image.boolean], [method@Image.andimage], [method@Image.orimage], [method@Image.eorimage], [method@Image.lshift], [method@Image.rshift] | | `boolean_const` | Boolean operations against a constant | [method@Image.boolean_const], [method@Image.andimage_const], [method@Image.orimage_const], [method@Image.eorimage_const], [method@Image.lshift_const], [method@Image.rshift_const], [method@Image.boolean_const1], [method@Image.andimage_const1], [method@Image.orimage_const1], [method@Image.eorimage_const1], [method@Image.lshift_const1], [method@Image.rshift_const1] | | `buildlut` | Build a look-up table | [method@Image.buildlut] | @@ -91,7 +91,7 @@ API docs each function links to for more details. | `complex2` | Complex binary operations on two images | [method@Image.complex2], [method@Image.cross_phase] | | `complexform` | Form a complex image from two real images | [method@Image.complexform] | | `complexget` | Get a component from a complex image | [method@Image.complexget], [method@Image.real], [method@Image.imag] | -| `composite` | Blend an array of images with an array of blend modes | [func@composite] | +| `composite` | Blend an array of images with an array of blend modes | [func@Image.composite] | | `composite2` | Blend a pair of images with a blend mode | [method@Image.composite2] | | `conv` | Convolution operation | [method@Image.conv] | | `conva` | Approximate integer convolution | [method@Image.conva] | @@ -123,7 +123,7 @@ API docs each function links to for more details. | `embed` | Embed an image in a larger image | [method@Image.embed] | | `extract_area` | Extract an area from an image | [method@Image.extract_area], [method@Image.crop] | | `extract_band` | Extract band from an image | [method@Image.extract_band] | -| `eye` | Make an image showing the eye's spatial response | [func@eye] | +| `eye` | Make an image showing the eye's spatial response | [ctor@Image.eye] | | `falsecolour` | False-color an image | [method@Image.falsecolour] | | `fastcor` | Fast correlation | [method@Image.fastcor] | | `fill_nearest` | Fill image zeros with nearest non-zero pixel | [method@Image.fill_nearest] | @@ -134,13 +134,13 @@ API docs each function links to for more details. | `flatten` | Flatten alpha out of an image | [method@Image.flatten] | | `flip` | Flip an image | [method@Image.flip] | | `float2rad` | Transform float rgb to radiance coding | [method@Image.float2rad] | -| `fractsurf` | Make a fractal surface | [func@fractsurf] | +| `fractsurf` | Make a fractal surface | [ctor@Image.fractsurf] | | `freqmult` | Frequency-domain filtering | [method@Image.freqmult] | | `fwfft` | Forward fft | [method@Image.fwfft] | | `gamma` | Gamma an image | [method@Image.gamma] | | `gaussblur` | Gaussian blur | [method@Image.gaussblur] | -| `gaussmat` | Make a gaussian image | [func@gaussmat] | -| `gaussnoise` | Make a gaussnoise image | [func@gaussnoise] | +| `gaussmat` | Make a gaussian image | [ctor@Image.gaussmat] | +| `gaussnoise` | Make a gaussnoise image | [ctor@Image.gaussnoise] | | `getpoint` | Read a point from an image | [method@Image.getpoint] | | `gifload` | Load gif with libnsgif | [ctor@Image.gifload] | | `gifload_buffer` | Load gif with libnsgif | [ctor@Image.gifload_buffer] | @@ -150,7 +150,7 @@ API docs each function links to for more details. | `gifsave_target` | Save as gif | [method@Image.gifsave_target] | | `globalbalance` | Global balance an image mosaic | [method@Image.globalbalance] | | `gravity` | Place an image within a larger image with a certain gravity | [method@Image.gravity] | -| `grey` | Make a grey ramp image | [func@grey] | +| `grey` | Make a grey ramp image | [ctor@Image.grey] | | `grid` | Grid an image | [method@Image.grid] | | `heifload` | Load a heif image | [ctor@Image.heifload] | | `heifload_buffer` | Load a heif image | [ctor@Image.heifload_buffer] | @@ -174,7 +174,7 @@ API docs each function links to for more details. | `icc_export` | Output to device with icc profile | [method@Image.icc_export] | | `icc_import` | Import from device with icc profile | [method@Image.icc_import] | | `icc_transform` | Transform between devices with icc profiles | [method@Image.icc_transform] | -| `identity` | Make a 1d image where pixel values are indexes | [func@identity] | +| `identity` | Make a 1d image where pixel values are indexes | [ctor@Image.identity] | | `ifthenelse` | Ifthenelse an image | [method@Image.ifthenelse] | | `insert` | Insert image @sub into @main at @x, @y | [method@Image.insert] | | `invert` | Invert an image | [method@Image.invert] | @@ -203,23 +203,23 @@ API docs each function links to for more details. | `labelregions` | Label regions in an image | [method@Image.labelregions] | | `linear` | Calculate (a * in + b) | [method@Image.linear], [method@Image.linear1] | | `linecache` | Cache an image as a set of lines | [method@Image.linecache] | -| `logmat` | Make a laplacian of gaussian image | [func@logmat] | +| `logmat` | Make a laplacian of gaussian image | [ctor@Image.logmat] | | `magickload` | Load file with imagemagick | [ctor@Image.magickload] | | `magickload_buffer` | Load buffer with imagemagick | [ctor@Image.magickload_buffer] | | `magicksave` | Save file with imagemagick | [method@Image.magicksave] | | `magicksave_buffer` | Save image to magick buffer | [method@Image.magicksave_buffer] | | `mapim` | Resample with a map image | [method@Image.mapim] | | `maplut` | Map an image though a lut | [method@Image.maplut] | -| `mask_butterworth` | Make a butterworth filter | [func@mask_butterworth] | -| `mask_butterworth_band` | Make a butterworth_band filter | [func@mask_butterworth_band] | -| `mask_butterworth_ring` | Make a butterworth ring filter | [func@mask_butterworth_ring] | -| `mask_fractal` | Make fractal filter | [func@mask_fractal] | -| `mask_gaussian` | Make a gaussian filter | [func@mask_gaussian] | -| `mask_gaussian_band` | Make a gaussian filter | [func@mask_gaussian_band] | -| `mask_gaussian_ring` | Make a gaussian ring filter | [func@mask_gaussian_ring] | -| `mask_ideal` | Make an ideal filter | [func@mask_ideal] | -| `mask_ideal_band` | Make an ideal band filter | [func@mask_ideal_band] | -| `mask_ideal_ring` | Make an ideal ring filter | [func@mask_ideal_ring] | +| `mask_butterworth` | Make a butterworth filter | [ctor@Image.mask_butterworth] | +| `mask_butterworth_band` | Make a butterworth_band filter | [ctor@Image.mask_butterworth_band] | +| `mask_butterworth_ring` | Make a butterworth ring filter | [ctor@Image.mask_butterworth_ring] | +| `mask_fractal` | Make fractal filter | [ctor@Image.mask_fractal] | +| `mask_gaussian` | Make a gaussian filter | [ctor@Image.mask_gaussian] | +| `mask_gaussian_band` | Make a gaussian filter | [ctor@Image.mask_gaussian_band] | +| `mask_gaussian_ring` | Make a gaussian ring filter | [ctor@Image.mask_gaussian_ring] | +| `mask_ideal` | Make an ideal filter | [ctor@Image.mask_ideal] | +| `mask_ideal_band` | Make an ideal band filter | [ctor@Image.mask_ideal_band] | +| `mask_ideal_ring` | Make an ideal ring filter | [ctor@Image.mask_ideal_ring] | | `match` | First-order match of two images | [method@Image.match] | | `math` | Apply a math operation to an image | [method@Image.math], [method@Image.sin], [method@Image.cos], [method@Image.tan], [method@Image.asin], [method@Image.acos], [method@Image.atan], [method@Image.sinh], [method@Image.cosh], [method@Image.tanh], [method@Image.asinh], [method@Image.acosh], [method@Image.atanh], [method@Image.exp], [method@Image.exp10], [method@Image.log], [method@Image.log10] | | `math2` | Binary math operations | [method@Image.math2], [method@Image.pow], [method@Image.wop], [method@Image.atan2] | @@ -253,7 +253,7 @@ API docs each function links to for more details. | `pdfload_buffer` | Load pdf from buffer | [ctor@Image.pdfload_buffer] | | `pdfload_source` | Load pdf from source | [ctor@Image.pdfload_source] | | `percent` | Find threshold for percent of pixels | [method@Image.percent] | -| `perlin` | Make a perlin noise image | [func@perlin] | +| `perlin` | Make a perlin noise image | [ctor@Image.perlin] | | `phasecor` | Calculate phase correlation | [method@Image.phasecor] | | `pngload` | Load png from file | [ctor@Image.pngload] | | `pngload_buffer` | Load png from buffer | [ctor@Image.pngload_buffer] | @@ -304,7 +304,7 @@ API docs each function links to for more details. | `scRGB2sRGB` | Convert an scrgb image to srgb | [method@Image.scRGB2sRGB] | | `scale` | Scale an image to uchar | [method@Image.scale] | | `scharr` | Scharr edge detector | [method@Image.scharr] | -| `sdf` | Create an sdf image | [func@sdf] | +| `sdf` | Create an sdf image | [ctor@Image.sdf] | | `sequential` | Check sequential access | [method@Image.sequential] | | `sharpen` | Unsharp masking for print | [method@Image.sharpen] | | `shrink` | Shrink an image | [method@Image.shrink] | @@ -312,7 +312,7 @@ API docs each function links to for more details. | `shrinkv` | Shrink an image vertically | [method@Image.shrinkv] | | `sign` | Unit vector of pixel | [method@Image.sign] | | `similarity` | Similarity transform of an image | [method@Image.similarity] | -| `sines` | Make a 2d sine wave | [func@sines] | +| `sines` | Make a 2d sine wave | [ctor@Image.sines] | | `smartcrop` | Extract an area from an image | [method@Image.smartcrop] | | `sobel` | Sobel edge detector | [method@Image.sobel] | | `spcor` | Spatial correlation | [method@Image.spcor] | @@ -321,17 +321,17 @@ API docs each function links to for more details. | `stdif` | Statistical difference | [method@Image.stdif] | | `subsample` | Subsample an image | [method@Image.subsample] | | `subtract` | Subtract two images | [method@Image.subtract] | -| `sum` | Sum an array of images | [func@sum] | +| `sum` | Sum an array of images | [func@Image.sum] | | `svgload` | Load svg with rsvg | [ctor@Image.svgload] | | `svgload_buffer` | Load svg with rsvg | [ctor@Image.svgload_buffer] | | `svgload_source` | Load svg from source | [ctor@Image.svgload_source] | -| `switch` | Find the index of the first non-zero pixel in tests | [func@switch] | -| `system` | Run an external command | [func@system] | -| `text` | Make a text image | [func@text] | -| `thumbnail` | Generate thumbnail from file | [func@thumbnail] | -| `thumbnail_buffer` | Generate thumbnail from buffer | [func@thumbnail_buffer] | +| `switch` | Find the index of the first non-zero pixel in tests | [func@Image.switch] | +| `system` | Run an external command | [ctor@Image.system] | +| `text` | Make a text image | [ctor@Image.text] | +| `thumbnail` | Generate thumbnail from file | [ctor@Image.thumbnail] | +| `thumbnail_buffer` | Generate thumbnail from buffer | [ctor@Image.thumbnail_buffer] | | `thumbnail_image` | Generate thumbnail from image | [method@Image.thumbnail_image] | -| `thumbnail_source` | Generate thumbnail from source | [func@thumbnail_source] | +| `thumbnail_source` | Generate thumbnail from source | [ctor@Image.thumbnail_source] | | `tiffload` | Load tiff from file | [ctor@Image.tiffload] | | `tiffload_buffer` | Load tiff from buffer | [ctor@Image.tiffload_buffer] | | `tiffload_source` | Load tiff from source | [ctor@Image.tiffload_source] | @@ -339,7 +339,7 @@ API docs each function links to for more details. | `tiffsave_buffer` | Save image to tiff buffer | [method@Image.tiffsave_buffer] | | `tiffsave_target` | Save image to tiff target | [method@Image.tiffsave_target] | | `tilecache` | Cache an image as a set of tiles | [method@Image.tilecache] | -| `tonelut` | Build a look-up table | [func@tonelut] | +| `tonelut` | Build a look-up table | [ctor@Image.tonelut] | | `transpose3d` | Transpose3d an image | [method@Image.transpose3d] | | `unpremultiply` | Unpremultiply image alpha | [method@Image.unpremultiply] | | `vipsload` | Load vips from file | [ctor@Image.vipsload] | @@ -353,8 +353,8 @@ API docs each function links to for more details. | `webpsave_buffer` | Save as webp | [method@Image.webpsave_buffer] | | `webpsave_mime` | Save image to webp mime | [method@Image.webpsave_mime] | | `webpsave_target` | Save as webp | [method@Image.webpsave_target] | -| `worley` | Make a worley noise image | [func@worley] | +| `worley` | Make a worley noise image | [ctor@Image.worley] | | `wrap` | Wrap image origin | [method@Image.wrap] | -| `xyz` | Make an image where pixel values are coordinates | [func@xyz] | -| `zone` | Make a zone plate | [func@zone] | +| `xyz` | Make an image where pixel values are coordinates | [ctor@Image.xyz] | +| `zone` | Make a zone plate | [ctor@Image.zone] | | `zoom` | Zoom an image | [method@Image.zoom] | diff --git a/doc/libvips-arithmetic.md b/doc/libvips-arithmetic.md index eea196f9ab..0034489f9a 100644 --- a/doc/libvips-arithmetic.md +++ b/doc/libvips-arithmetic.md @@ -68,7 +68,7 @@ float. ## Arithmetic functions * [method@Image.add] -* [func@sum] +* [func@Image.sum] * [method@Image.subtract] * [method@Image.multiply] * [method@Image.divide] diff --git a/doc/meson.build b/doc/meson.build index 421982533e..fda1c26c9d 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -39,12 +39,12 @@ vips_toml = configure_file( install_dir: docs_dir / 'vips', ) -fixup_load_as_ctor = find_program('fixup-load-as-ctor.py') +fixup_gir_for_doc = find_program('fixup-gir-for-doc.py') vips_gir_doc = custom_target( input: vips_gir[0], output: 'Vips-@0@.0-doc.gir'.format(version_major), - command: [fixup_load_as_ctor, '@INPUT@', '@OUTPUT@'], + command: [fixup_gir_for_doc, '@INPUT@', '@OUTPUT@'], ) custom_target('libvips-doc', diff --git a/doc/using-the-cli.md b/doc/using-the-cli.md index 71c50a679d..ae845a2b57 100644 --- a/doc/using-the-cli.md +++ b/doc/using-the-cli.md @@ -97,7 +97,7 @@ $ vips affine k2.jpg x.jpg "2 0 0 1" ``` You may need the quotes to stop your shell breaking the argument at -the spaces. [func@bandjoin] needs an array of input images to +the spaces. [func@Image.bandjoin] needs an array of input images to join, run it like this: ```bash diff --git a/doc/using-vipsthumbnail.md b/doc/using-vipsthumbnail.md index 97b8e61f77..e624dc1a6d 100644 --- a/doc/using-vipsthumbnail.md +++ b/doc/using-vipsthumbnail.md @@ -5,8 +5,8 @@ Title: Using vipsthumbnail libvips ships with a handy command-line image thumbnailer, `vipsthumbnail`. This page introduces it, with some examples. -The thumbnailing functionality is implemented by [func@thumbnail] and -[func@thumbnail_buffer] (which thumbnails an image held as a string), +The thumbnailing functionality is implemented by [ctor@Image.thumbnail] and +[ctor@Image.thumbnail_buffer] (which thumbnails an image held as a string), see the docs for details. You can use these functions from any language with a libvips binding. For example, from PHP you could write: diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 345ce9408d..b95c2fb61d 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -1038,8 +1038,9 @@ vips_image_get_data(VipsImage *image) * A convenience function to set the header fields after creating an image. * Normally you copy the fields from your input images with * [method.Image.pipelinev] and then make any adjustments you need, - * but if you are creating an image from scratch, for example [func@black] - * or [ctor@Image.jpegload], you do need to set all the fields yourself. + * but if you are creating an image from scratch, for example + * [ctor@Image.black] or [ctor@Image.jpegload], you do need to set all the + * fields yourself. * * See also: [method.Image.pipelinev]. */ From 13272a107765de3b6e75332399c48716692967d8 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 1 Apr 2025 14:30:43 +0200 Subject: [PATCH 103/174] doc: ensure `vips_profile_load()` is a blob ctor (#4447) --- doc/fixup-gir-for-doc.py | 8 +++++++- doc/function-list.md | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/fixup-gir-for-doc.py b/doc/fixup-gir-for-doc.py index 25214f42a4..414b6ff54d 100755 --- a/doc/fixup-gir-for-doc.py +++ b/doc/fixup-gir-for-doc.py @@ -22,6 +22,7 @@ def fixup_gir_for_doc(args): namespace_node = root.find('goi:namespace', namespace) image_node = namespace_node.find('goi:class[@name="Image"]', namespace) + blob_node = namespace_node.find('goi:record[@name="Blob"]', namespace) # A list of functions that needs to be converted to an Image constructor. # Note that all functions containing "load" are already converted. @@ -71,7 +72,12 @@ def fixup_gir_for_doc(args): for node in namespace_node.findall('goi:function', namespace): name = node.get('name') - if 'load' in name or name in image_ctors: + if name == 'profile_load': + namespace_node.remove(node) + + node.tag = 'constructor' + blob_node.append(node) + elif 'load' in name or name in image_ctors: namespace_node.remove(node) node.tag = 'constructor' diff --git a/doc/function-list.md b/doc/function-list.md index ee86f40b5e..2fd29146da 100644 --- a/doc/function-list.md +++ b/doc/function-list.md @@ -268,7 +268,7 @@ API docs each function links to for more details. | `premultiply` | Premultiply image alpha | [method@Image.premultiply] | | `prewitt` | Prewitt edge detector | [method@Image.prewitt] | | `profile` | Find image profiles | [method@Image.profile] | -| `profile_load` | Load named icc profile | [ctor@Image.profile_load] | +| `profile_load` | Load named icc profile | [ctor@Blob.profile_load] | | `project` | Find image projections | [method@Image.project] | | `quadratic` | Resample an image with a quadratic transform | [method@Image.quadratic] | | `rad2float` | Unpack radiance coding to float rgb | [method@Image.rad2float] | From 1f17e6447965b02a1ed37587b920146d373abc0b Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 1 Apr 2025 14:36:15 +0200 Subject: [PATCH 104/174] Remove stray colour declarations (#4446) --- libvips/include/vips/colour.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libvips/include/vips/colour.h b/libvips/include/vips/colour.h index 4433f85cfc..5848249b83 100644 --- a/libvips/include/vips/colour.h +++ b/libvips/include/vips/colour.h @@ -149,12 +149,6 @@ VIPS_API int vips_Lab2LCh(VipsImage *in, VipsImage **out, ...) G_GNUC_NULL_TERMINATED; VIPS_API -int vips_Yxy2Lab(VipsImage *in, VipsImage **out, ...) - G_GNUC_NULL_TERMINATED; -VIPS_API -int vips_CMC2XYZ(VipsImage *in, VipsImage **out, ...) - G_GNUC_NULL_TERMINATED; -VIPS_API int vips_Lab2XYZ(VipsImage *in, VipsImage **out, ...) G_GNUC_NULL_TERMINATED; VIPS_API From 195dd690480f8b657ae0f7ac2f72906683308117 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 1 Apr 2025 22:35:07 +0100 Subject: [PATCH 105/174] revise docs in iofuncs for gi-docgen (#4443) * mostly do image.c * fix some macros * do region.c * do buf.c * do a couple more * fix up some enums and flags * add VipsPrecision * more optional arg * do error and dbuf and fix the build again * do gate, generate, ginputsource * header, sourceginput, system, ginputsource * init * memory, object * operation * rect, region * reorder, sbuf * sink, sink_memory * sinkscreen, source * sourcecustom, target, targetcustom * thread, threadpool * threadset * type.c * util * vector, window, vips * tidy up * spelling --- doc/rename.sed | 98 +++++++- doc/rename.sh | 2 +- doc/urlmap.js | 1 + libvips/convolution/canny.c | 12 +- libvips/iofuncs/buf.c | 26 +- libvips/iofuncs/cache.c | 57 +++-- libvips/iofuncs/dbuf.c | 8 +- libvips/iofuncs/error.c | 145 +++++++---- libvips/iofuncs/gate.c | 2 +- libvips/iofuncs/generate.c | 49 ++-- libvips/iofuncs/ginputsource.c | 10 +- libvips/iofuncs/header.c | 76 ++++-- libvips/iofuncs/image.c | 435 ++++++++++++++++++--------------- libvips/iofuncs/init.c | 99 ++++---- libvips/iofuncs/memory.c | 88 ++++--- libvips/iofuncs/object.c | 60 ++--- libvips/iofuncs/operation.c | 46 ++-- libvips/iofuncs/rect.c | 2 +- libvips/iofuncs/region.c | 137 ++++++----- libvips/iofuncs/reorder.c | 24 +- libvips/iofuncs/sbuf.c | 16 +- libvips/iofuncs/sink.c | 12 +- libvips/iofuncs/sinkmemory.c | 6 +- libvips/iofuncs/sinkscreen.c | 17 +- libvips/iofuncs/source.c | 33 +-- libvips/iofuncs/sourcecustom.c | 4 +- libvips/iofuncs/sourceginput.c | 5 +- libvips/iofuncs/system.c | 39 ++- libvips/iofuncs/target.c | 9 +- libvips/iofuncs/targetcustom.c | 4 +- libvips/iofuncs/thread.c | 25 +- libvips/iofuncs/threadpool.c | 31 ++- libvips/iofuncs/threadset.c | 7 +- libvips/iofuncs/type.c | 228 +++++++++-------- libvips/iofuncs/util.c | 6 +- libvips/iofuncs/vector.cpp | 2 +- libvips/iofuncs/vips.c | 8 +- 37 files changed, 1063 insertions(+), 766 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index 13343c5a84..ff2c6341cf 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -1,15 +1,59 @@ -s/vips_\([^(]*\)_new()/[ctor@\u\1.new]/g -s/vips_image_\(new_[^(]*\)()/[ctor@Image.\1]/g +s/See also: \([^.]\)/::: seealso\n * \1/g + +s/#VipsImage::\(width\)/[property@Image:\1]/g +s/#VipsImage::\(height\)/[property@Image:\1]/g +s/#VipsImage::\(format\)/[property@Image:\1]/g +s/#VipsImage::\(interpretation\)/[property@Image:\1]/g + +s/#VipsImage::\([^ ,.]*\)/[signal@Image::\1]/g +s/#VipsObject::\([^ ,.]*\)/[signal@Object::\1]/g + +s/vips_foreign_\([^(]*\)()/[func@Foreign.\1]/g + +s/VIPS_INIT()/[func@INIT]/g +s/VIPS_IMAGE_\([^(]*\)()/[func@IMAGE_\1]/g +s/VIPS_REGION\([^(]*\)()/[func@REGION\1]/g +s/VIPS_MATRIX\([^(]*\)()/[func@MATRIX]/g +s/VIPS_BUF_\([^(]*\)()/[func@BUF_\1]/g +s/VIPS_SBUF_\([^(]*\)()/[func@SBUF_\1]/g + +s/vips_image_\(pipeline_array\)()/[func@Image.\1]/g + +s/vips_operation_\([^(]*\)()/[method@Operation.\1]/g +s/vips_connnection_\([^(]*\)()/[method@Connection.\1]/g +s/vips_source_custom\([^(]*\)()/[method@SourceCustom.\1]/g +s/vips_source_\([^(]*\)()/[method@Source.\1]/g +s/vips_target_custom_\([^(]*\)()/[method@TargetCustom.\1]/g +s/vips_target_\([^(]*\)()/[method@Target.\1]/g s/vips_object_\([^(]*\)()/[method@Object.\1]/g -s/vips_image_\(generate\)()/[func@image_generate]/g +s/vips_\([^_]*\)_new()/[ctor@\u\1.new]/g +s/vips_image_\(new_[^(]*\)()/[ctor@Image.\1]/g +s/vips_image_\(generate\)()/[method@Image.generate]/g s/vips_image_\([^(]*\)()/[method@Image.\1]/g s/vips_region_\([^(]*\)()/[method@Region.\1]/g +s/vips_buf_\([^(]*\)()/[method@Buf.\1]/g +s/vips_sbuf_\([^(]*\)()/[method@Sbuf.\1]/g +s/vips_dbuf_\([^(]*\)()/[method@Dbuf.\1]/g +s/vips_\(reorder_[^(]*\)()/[method@Image.\1]/g + +s/vips_area_\(new\)()/[ctor@Area.\1]/g +s/vips_area_\(new_[^(]*\)()/[ctor@Area.\1]/g +s/vips_area_\([^(]*\)()/[method@Area.\1]/g + +s/vips_array_double_\(new[^(]*\)()/[ctor@ArrayDouble.\1]/g +s/vips_array_double_\([^(]*\)()/[method@ArrayDouble.\1]/g + +s/vips_array_int_\(new[^(]*\)()/[ctor@ArrayInt.\1]/g +s/vips_array_int_\([^(]*\)()/[method@ArrayInt.\1]/g + +s/vips_array_image_\(new[^(]*\)()/[ctor@ArrayImage.\1]/g +s/vips_array_image_empty()/[ctor@ArrayImage.empty]/g +s/vips_array_image_\([^(]*\)()/[method@ArrayImage.\1]/g s/vips_\(abs\)()/[method@Image.\1]/g s/vips_\(acosh\)()/[method@Image.\1]/g s/vips_\(acos\)()/[method@Image.\1]/g s/vips_\(addalpha\)()/[method@Image.\1]/g -s/vips_\(addlpha\)()/[method@Image.\1]/g s/vips_\(add\)()/[method@Image.\1]/g s/vips_\(affine\)()/[method@Image.\1]/g s/vips_\(andimage_const1\)()/[method@Image.\1]/g @@ -32,6 +76,7 @@ s/vips_\(bandjoin_const\)()/[method@Image.\1]/g s/vips_\(bandmean\)()/[method@Image.\1]/g s/vips_\(bandor\)()/[method@Image.\1]/g s/vips_\(bandunfold\)()/[method@Image.\1]/g +s/vips_\(black\)()/[ctor@Image.\1]/g s/vips_\(boolean_const1\)()/[method@Image.\1]/g s/vips_\(boolean_const\)()/[method@Image.\1]/g s/vips_\(boolean\)()/[method@Image.\1]/g @@ -126,6 +171,7 @@ s/vips_\(fwfft\)()/[method@Image.\1]/g s/vips_\(gamma\)()/[method@Image.\1]/g s/vips_\(gaussblur\)()/[method@Image.\1]/g s/vips_\(getpoint\)()/[method@Image.\1]/g +s/vips_\(get_tile_size\)()/[method@Image.\1]/g s/vips_\(gifsave_buffer\)()/[method@Image.\1]/g s/vips_\(gifsave\)()/[method@Image.\1]/g s/vips_\(gifsave_target\)()/[method@Image.\1]/g @@ -294,6 +340,9 @@ s/vips_\(shrinkv\)()/[method@Image.\1]/g s/vips_\(sign\)()/[method@Image.\1]/g s/vips_\(similarity\)()/[method@Image.\1]/g s/vips_\(sinh\)()/[method@Image.\1]/g +s/vips_\(sink\)()/[method@Image.\1]/g +s/vips_\(sink_disc\)()/[method@Image.\1]/g +s/vips_\(sink_screen\)()/[method@Image.\1]/g s/vips_\(sin\)()/[method@Image.\1]/g s/vips_\(smartcrop\)()/[method@Image.\1]/g s/vips_\(sobel\)()/[method@Image.\1]/g @@ -331,17 +380,58 @@ s/vips_\(zoom\)()/[method@Image.\1]/g s/vips_\([^(]*\)()/[func@\1]/g +s/#Vips\(Access\)/[enum@\1]/g s/#Vips\(BandFormat\)/[enum@\1]/g s/#Vips\(Interpretation\)/[enum@\1]/g s/#Vips\(Coding\)/[enum@\1]/g s/#Vips\(DemandStyle\)/[enum@\1]/g +s/#Vips\(Precision\)/[enum@\1]/g +s/#Vips\(ArgumentFlags\)/[flags@\1]/g + s/#Vips\(Rect\)/[struct@\1]/g +s/#Vips\(Progress\)/[struct@\1]/g + s/#Vips\(Image\)/[class@\1]/g +s/#Vips\(Foreign\)/[class@\1]/g s/#Vips\(Region\)/[class@\1]/g s/#Vips\(Object\)/[class@\1]/g s/#Vips\(Operation\)/[class@\1]/g s/#Vips\(ForeignLoad\)/[class@\1]/g +s/#Vips\(Connection\)/[class@\1]/g +s/#Vips\(SourceCustom\)/[class@\1]/g +s/#Vips\(Source\)/[class@\1]/g +s/#Vips\(TargetCustom\)/[class@\1]/g +s/#Vips\(Target\)/[class@\1]/g +s/#Vips\(ThreadState\)/[class@\1]/g +s/#Vips\(Buf\)/[class@\1]/g +s/#Vips\(Sbuf\)/[class@\1]/g +s/#Vips\(Dbuf\)/[class@\1]/g +s/#Vips\(Blob\)/[struct@\1]/g +s/#Vips\(Area\)/[struct@\1]/g +s/#Vips\(ArrayInt\)/[struct@\1]/g +s/#Vips\(ArrayDouble\)/[struct@\1]/g +s/#Vips\(ArrayImage\)/[struct@\1]/g +s/#Vips\(RefString\)/[struct@\1]/g +s/#Vips\(ThreadpoolAllocateFn\)/[callback@\1]/g +s/#Vips\(ThreadpoolWorkFn\)/[callback@\1]/g +s/#Vips\(ThreadpoolProgressFn\)/[callback@\1]/g +s/#VIPS_OPERATION_\([^ ,.]*\)/[flags@Vips.OperationFlags.\1]/g +s/#VIPS_FORMAT_\([^ ,.]*\)/[enum@Vips.BandFormat.\1]/g +s/#VIPS_PRECISION_\([^ ,.]*\)/[enum@Vips.Precision.\1]/g +s/#VIPS_DEMAND_STYLE_\([^ ,.]*\)/[enum@Vips.DemandStyle.\1]/g +s/#VIPS_INTERPRETATION_\([^ ,.]*\)/[enum@Vips.Interpretation.\1]/g +s/#VIPS_ACCESS_\([^ ,.]*\)/[enum@Vips.Access.\1]/g +s/#VIPS_CODING_\([^ ,.]*\)/[enum@Vips.Coding.\1]/g + +s/g_thread_\([^(]*new\)()/[ctor@GLib.Thread.\1]/g +s/g_object_\(new\)()/[ctor@GObject.Object.\1]/g s/g_object_\([^(]*\)()/[method@GObject.Object.\1]/g s/%GValue/[struct@GObject.Value]/g s/%GObject/[class@GObject.Object]/g +s/%GThread/[struct@GLib.Thread]/g +s/%GInputStream/[class@Gio.InputStream]/g +s/%GInput/[class@Gio.Input]/g +s/%GSList/[struct@GLib.SList]/g + +s/g_\([^(]*\)()/[func@GLib.\1]/g diff --git a/doc/rename.sh b/doc/rename.sh index eb32fffb09..01013c9adc 100755 --- a/doc/rename.sh +++ b/doc/rename.sh @@ -1,5 +1,5 @@ #!/bin/bash -for filename in "$@"; do +for filename in "$@"; do sed -i -f rename.sed $filename done diff --git a/doc/urlmap.js b/doc/urlmap.js index 11d27febcf..69c33a9199 100644 --- a/doc/urlmap.js +++ b/doc/urlmap.js @@ -1,6 +1,7 @@ // A map between namespaces and base URLs for their online documentation baseURLs = [ ['GLib', 'https://docs.gtk.org/glib/'], + ['Gio', 'https://docs.gtk.org/gio/'], ['GObject', 'https://docs.gtk.org/gobject/'], ['GModule', 'https://docs.gtk.org/gmodule/'], ] diff --git a/libvips/convolution/canny.c b/libvips/convolution/canny.c index 9571f16f8e..7b08e787bd 100644 --- a/libvips/convolution/canny.c +++ b/libvips/convolution/canny.c @@ -478,10 +478,9 @@ vips_canny_init(VipsCanny *canny) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @sigma: %gdouble, sigma for gaussian blur - * * @precision: #VipsPrecision, calculation accuracy + * ::: note "Optional arguments" + * * @sigma: %gdouble, sigma for gaussian blur + * * @precision: [enum@Precision], calculation accuracy * * Find edges by Canny's method: The maximum of the derivative of the gradient * in the direction of the gradient. Output is float, except for uchar input, @@ -492,13 +491,14 @@ vips_canny_init(VipsCanny *canny) * usually a good value. * * Use @precision to set the precision of edge detection. For uchar images, - * setting this to #VIPS_PRECISION_INTEGER will make edge detection much + * setting this to [enum@Vips.Precision.INTEGER] will make edge detection much * faster, but sacrifice some sensitivity. * * You will probably need to process the output further to eliminate weak * edges. * - * See also: vips_sobel(). + * ::: seealso + * vips_sobel(). * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/iofuncs/buf.c b/libvips/iofuncs/buf.c index aac134eb62..bd2f8a60ba 100644 --- a/libvips/iofuncs/buf.c +++ b/libvips/iofuncs/buf.c @@ -60,8 +60,8 @@ * int i; * * vips_buf_appends(&buf, "Numbers are: "); - * for (i = 0; i < array_length; i++) { - * if (i > 0) + * for (i = 0; i < array_length; i++) { + * if (i > 0) * vips_buf_appends(&buf, ", "); * vips_buf_appendg(&buf, array[i]); * } @@ -75,10 +75,10 @@ * * Initialize a heap buffer. For example: * - * |[ + * ```c * char txt[256]; * VipsBuf buf = VIPS_BUF_STATIC(txt); - * ]| + * ``` */ /** @@ -158,7 +158,7 @@ vips_buf_set_static(VipsBuf *buf, char *base, int mx) * @base: the start of the memory area to use for storage * @mx: the size of the storage area * - * Initialise and attach to a static memory area. VIPS_BUF_STATIC() is usually + * Initialise and attach to a static memory area. [func@BUF_STATIC] is usually * more convenient. * * For example: @@ -220,13 +220,13 @@ vips_buf_set_dynamic(VipsBuf *buf, int mx) * Initialise and attach to a heap memory area. * The memory area needs to be at least 4 bytes long. * - * |[ + * ```c * VipsBuf buf; * - * vips_buf_init_synamic(&buf, 256); - * ]| + * vips_buf_init_dynamic(&buf, 256); + * ``` * - * Dynamic buffers must be freed with vips_buf_destroy(), but their size can + * Dynamic buffers must be freed with [method@Buf.destroy], but their size can * be set at runtime. */ void @@ -243,7 +243,7 @@ vips_buf_init_dynamic(VipsBuf *buf, int mx) * @sz: the size of the string to append * * Append at most @sz chars from @str to @buf. @sz < 0 means unlimited. This - * is the low-level append operation: functions like vips_buf_appendf() build + * is the low-level append operation: functions like [method@Buf.appendf] build * on top of this. * * Returns: %FALSE on overflow, %TRUE otherwise. @@ -275,7 +275,7 @@ vips_buf_appendns(VipsBuf *buf, const char *str, int sz) cpy = VIPS_MIN(n, avail); - /* Can't use g_strlcpy() here, we don't want to drop the end of the + /* Can't use [func@GLib.strlcpy] here, we don't want to drop the end of the * string. * * gcc10.3 (I think?) issues a false-positive warning about this. @@ -415,7 +415,7 @@ vips_buf_vappendf(VipsBuf *buf, const char *fmt, va_list ap) // -3 to leave space for "..." // not -4, since the terminating \0 will already be on the string written - // by g_vsnprintf() + // by [func@GLib.vsnprintf] avail = buf->mx - buf->i - 3; p = buf->base + buf->i; (void) g_vsnprintf(p, avail, fmt, ap); @@ -500,7 +500,7 @@ vips_buf_appendd(VipsBuf *buf, int d) * Format and append a #GValue as a printable thing. We display text line "3144 * bytes of binary data" for BLOBs like icc-profile-data. * - * Use vips_image_get_as_string() to make a text representation of a field. + * Use [method@Image.get_as_string] to make a text representation of a field. * That will base64-encode blobs, for example. * * Returns: %FALSE on overflow, %TRUE otherwise. diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index ceacbe6c36..39145399db 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -42,7 +42,7 @@ what about delayed writes ... do we ever write in close? we shouldn't, should do in evalend or written or somesuch - use g_param_values_cmp() instead of value_equal()? + use [func@GLib.param_values_cmp] instead of value_equal()? */ @@ -775,7 +775,7 @@ vips_cache_get_first(void) * vips_cache_drop_all: * * Drop the whole operation cache, handy for leak tracking. Also called - * automatically on vips_shutdown(). + * automatically on [func@shutdown]. */ void vips_cache_drop_all(void) @@ -793,7 +793,7 @@ vips_cache_drop_all(void) vips_cache_print_nolock(); /* We can't modify the hash in the callback from - * g_hash_table_foreach() and friends. Repeatedly drop the + * [func@GLib.hash_table_foreach] and friends. Repeatedly drop the * first item instead. */ while ((operation = vips_cache_get_first())) @@ -867,15 +867,16 @@ vips_cache_trim(void) * * If we miss, build and add @operation. * - * Operators that have been tagged as invalid by the `invalidate` signal are + * Operators that have been tagged as invalid by [signal@Image::invalidate] are * removed from cache. * - * Operators with the #VIPS_OPERATION_BLOCKED flag are never executed. + * Operators with the [flags@Vips.OperationFlags.BLOCKED] flag are never + * executed. * - * Operators with the #VIPS_OPERATION_REVALIDATE flag are always executed and - * any old cache value is replaced. + * Operators with the [flags@Vips.OperationFlags.REVALIDATE] flag are always + * executed and any old cache value is replaced. * - * Operators with the #VIPS_OPERATION_NOCACHE flag are never cached. + * Operators with the [flags@Vips.OperationFlags.NOCACHE] flag are never cached. * * Returns: 0 on success, or -1 on error. */ @@ -974,7 +975,7 @@ vips_cache_operation_buildp(VipsOperation **operation) VIPS_UNREF(operation_before); - /* Retrieve the flags again, as vips_foreign_load_build() may + /* Retrieve the flags again, as [func@Foreign.load_build] may * set load->nocache. */ flags = vips_operation_get_flags(*operation); @@ -1012,11 +1013,11 @@ vips_cache_operation_buildp(VipsOperation **operation) * vips_cache_operation_build: * @operation: (transfer none): operation to lookup * - * A binding-friendly version of vips_cache_operation_buildp(). + * A binding-friendly version of [func@cache_operation_buildp]. * * After calling this, @operation has the same ref count as when it went in, - * and the result must be freed with vips_object_unref_outputs() and - * g_object_unref(). + * and the result must be freed with [method@Object.unref_outputs] and + * [method@GObject.Object.unref]. * * Returns: (transfer full): The built operation. */ @@ -1056,13 +1057,14 @@ vips_cache_set_max(int max) * @max_mem: maximum amount of tracked memory we use * * Set the maximum amount of tracked memory we allow before we start dropping - * cached operations. See vips_tracked_get_mem(). + * cached operations. See [func@tracked_get_mem]. * * libvips only tracks memory it allocates, it can't track memory allocated by - * external libraries. If you use an operation like vips_magickload(), most of - * the memory it uses won't be included. + * external libraries. If you use an operation like [ctor@Image.magickload], + * most of the memory it uses won't be included. * - * See also: vips_tracked_get_mem(). + * ::: seealso + * [func@tracked_get_mem]. */ void vips_cache_set_max_mem(size_t max_mem) @@ -1111,9 +1113,10 @@ vips_cache_get_size(void) * vips_cache_get_max_mem: * * Get the maximum amount of tracked memory we allow before we start dropping - * cached operations. See vips_tracked_get_mem(). + * cached operations. See [func@tracked_get_mem]. * - * See also: vips_tracked_get_mem(). + * ::: seealso + * [func@tracked_get_mem]. * * Returns: the maximum amount of tracked memory we allow */ @@ -1127,13 +1130,14 @@ vips_cache_get_max_mem(void) * vips_cache_get_max_files: * * Get the maximum number of tracked files we allow before we start dropping - * cached operations. See vips_tracked_get_files(). + * cached operations. See [func@tracked_get_files]. * * libvips only tracks file descriptors it allocates, it can't track ones * allocated by external libraries. If you use an operation like - * vips_magickload(), most of the descriptors it uses won't be included. + * [ctor@Image.magickload], most of the descriptors it uses won't be included. * - * See also: vips_tracked_get_files(). + * ::: seealso + * [func@tracked_get_files]. * * Returns: the maximum number of tracked files we allow */ @@ -1148,9 +1152,10 @@ vips_cache_get_max_files(void) * @max_files: max open files we allow * * Set the maximum number of tracked files we allow before we start dropping - * cached operations. See vips_tracked_get_files(). + * cached operations. See [func@tracked_get_files]. * - * See also: vips_tracked_get_files(). + * ::: seealso + * [func@tracked_get_files]. */ void vips_cache_set_max_files(int max_files) @@ -1165,7 +1170,8 @@ vips_cache_set_max_files(int max_files) * * Handy for debugging. Print the operation cache to stdout just before exit. * - * See also: vips_cache_set_trace(). + * ::: seealso + * [func@cache_set_trace]. */ void vips_cache_set_dump(gboolean dump) @@ -1182,7 +1188,8 @@ vips_cache_set_dump(gboolean dump) * You can set the environment variable `VIPS_TRACE` to turn this option on, or * use the command-line flag `--vips-cache-trace`. * - * See also: vips_cache_set_dump(). + * ::: seealso + * [func@cache_set_dump]. */ void vips_cache_set_trace(gboolean trace) diff --git a/libvips/iofuncs/dbuf.c b/libvips/iofuncs/dbuf.c index 672061b4ab..635c82c201 100644 --- a/libvips/iofuncs/dbuf.c +++ b/libvips/iofuncs/dbuf.c @@ -48,7 +48,7 @@ * Initialize @dbuf. You can also just init to zero, eg. * `VipsDbuf buf = {0};`. * - * Destroy with vips_dbuf_destroy(). + * Destroy with [method@Dbuf.destroy]. */ void vips_dbuf_init(VipsDbuf *dbuf) @@ -133,11 +133,11 @@ vips_dbuf_read(VipsDbuf *dbuf, unsigned char *data, size_t size) * @size: (allow-none): optionally return length in bytes here * * Return a pointer to an area you can write to, return length of area in - * @size. Use vips_dbuf_allocate() before this call to set a minimum amount of + * @size. Use [method@Dbuf.allocate] before this call to set a minimum amount of * space to have available. * * The write point moves to just beyond the returned block. Use - * vips_dbuf_seek() to move it back again. + * [method@Dbuf.seek] to move it back again. * * Returns: (transfer none): start of write area. */ @@ -399,7 +399,7 @@ vips_dbuf_null_terminate(VipsDbuf *dbuf) * @size: (allow-none): optionally return length in bytes here * * Destroy a buffer, but rather than freeing memory, a pointer is returned. - * This must be freed with g_free(). + * This must be freed with [func@GLib.free]. * * A `\0` is appended, but not included in the character count. This is so the * pointer can be safely treated as a C string. diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index 2feb859e53..c2725ac9e9 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -88,11 +88,11 @@ * user. If a function you call detects an error, just propagate it and don't * add another message. * - * |[ + * ```c * VipsImage *im; * * if (!(im = vips_image_new_from_file(filename, NULL))) - * // vips_image_new_from_file() will set a message, we don't need to + * // [ctor@Image.new_from_file] will set a message, we don't need to * return -1; * * if (vips_image_get_width(im) < 100) { @@ -100,17 +100,17 @@ * vips_error("myprogram", "%s", _("width too small")); * return -1; * } - * ]| + * ``` * * The domain argument most of these functions take is not localised and is * supposed to indicate the component which failed. * - * libvips uses g_warning() and g_info() to send warning and information + * libvips uses [func@GLib.warning] and [func@GLib.info] to send warning and information * messages to the user. You can use the usual glib mechanisms to display or * divert these messages. For example, info messages are hidden by default, but * you can see them with: * - * |[ + * ```c * $ G_MESSAGES_DEBUG=VIPS vipsthumbnail k2.jpg * VIPS-INFO: thumbnailing k2.jpg * VIPS-INFO: selected loader is VipsForeignLoadJpegFile @@ -123,7 +123,7 @@ * VIPS-INFO: residual reduceh by 0.5 * VIPS-INFO: 13 point mask * VIPS-INFO: thumbnailing k2.jpg as ./tn_k2.jpg - * ]| + * ``` * */ @@ -137,7 +137,7 @@ static int vips_error_freeze_count = 0; /** * vips_error_freeze: * - * Stop errors being logged. Use vips_error_thaw() to unfreeze. You can + * Stop errors being logged. Use [func@error_thaw] to unfreeze. You can * nest freeze/thaw pairs. */ void @@ -169,7 +169,8 @@ vips_error_thaw(void) * Get a pointer to the start of the error buffer as a C string. * The string is owned by the error system and must not be freed. * - * See also: vips_error_clear(). + * ::: seealso + * [func@error_clear]. * * Returns: the error buffer as a C string which must not be freed */ @@ -222,7 +223,8 @@ vips_error_buffer_copy(void) * * Append a message to the error buffer. * - * See also: vips_error(). + * ::: seealso + * [func@error]. */ void vips_verror(const char *domain, const char *fmt, va_list ap) @@ -263,7 +265,8 @@ vips_verror(const char *domain, const char *fmt, va_list ap) * * Format the string in the style of printf() and append to the error buffer. * - * See also: vips_error_system(), vips_verror(). + * ::: seealso + * [func@error_system], [func@verror]. */ void vips_error(const char *domain, const char *fmt, ...) @@ -286,7 +289,8 @@ vips_error(const char *domain, const char *fmt, ...) * Then create and append a localised message based on the system error code, * usually the value of errno. * - * See also: vips_error_system(). + * ::: seealso + * [func@error_system]. */ void vips_verror_system(int err, const char *domain, const char *fmt, va_list ap) @@ -306,7 +310,8 @@ vips_verror_system(int err, const char *domain, const char *fmt, va_list ap) * Then create and append a localised message based on the system error code, * usually the value of errno. * - * See also: vips_verror_system(). + * ::: seealso + * [func@verror_system]. */ void vips_error_system(int err, const char *domain, const char *fmt, ...) @@ -325,9 +330,10 @@ vips_error_system(int err, const char *domain, const char *fmt, ...) * This function sets the glib error pointer from the vips error buffer and * clears it. It's handy for returning errors to glib functions from vips. * - * See vips_g_error() for the inverse operation. + * See [func@g_error] for the inverse operation. * - * See also: g_set_error(), vips_g_error(). + * ::: seealso + * [func@GLib.set_error], [func@g_error]. */ void vips_error_g(GError **error) @@ -352,9 +358,10 @@ vips_error_g(GError **error) * @error: glib error pointer * * This function adds the %GError to the vips error buffer and clears it. It's - * the opposite of vips_error_g(). + * the opposite of [func@error_g]. * - * See also: vips_error_g(). + * ::: seealso + * [func@error_g]. */ void vips_g_error(GError **error) @@ -373,7 +380,8 @@ vips_g_error(GError **error) * Clear and reset the error buffer. This is typically called after presenting * an error to the user. * - * See also: vips_error_buffer(). + * ::: seealso + * [func@error_buffer]. */ void vips_error_clear(void) @@ -395,7 +403,8 @@ vips_error_clear(void) * @fmt may be %NULL, in which case only the error buffer is printed before * exiting. * - * See also: vips_error(). + * ::: seealso + * [func@error]. */ void vips_error_exit(const char *fmt, ...) @@ -431,7 +440,8 @@ vips_error_exit(const char *fmt, ...) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 on OK, or -1 on error. */ @@ -455,7 +465,8 @@ vips_check_uncoded(const char *domain, VipsImage *im) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 on OK, or -1 on error. */ @@ -483,7 +494,8 @@ vips_check_coding_noneorlabq(const char *domain, VipsImage *im) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 on OK, or -1 on error. */ @@ -512,7 +524,8 @@ vips_check_coding_known(const char *domain, VipsImage *im) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 on OK, or -1 on error. */ @@ -537,7 +550,8 @@ vips_check_coding(const char *domain, VipsImage *im, VipsCoding coding) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -562,7 +576,8 @@ vips_check_mono(const char *domain, VipsImage *im) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -586,7 +601,8 @@ vips_check_bands(const char *domain, VipsImage *im, int bands) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -612,7 +628,8 @@ vips_check_bands_1or3(const char *domain, VipsImage *im) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -639,7 +656,8 @@ vips_check_bands_atleast(const char *domain, VipsImage *im, int bands) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 on OK, or -1 on error. */ @@ -664,11 +682,12 @@ vips_check_bands_1orn(const char *domain, VipsImage *im1, VipsImage *im2) * @n: number of bands, or 1 * * Check that an image has 1 or @n bands. Handy for unary operations, cf. - * vips_check_bands_1orn(). + * [func@check_bands_1orn]. * If not, set an error message * and return non-zero. * - * See also: vips_check_bands_1orn(). + * ::: seealso + * [func@check_bands_1orn]. * * Returns: 0 on OK, or -1 on error. */ @@ -692,7 +711,8 @@ vips_check_bands_1orn_unary(const char *domain, VipsImage *im, int n) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -716,7 +736,8 @@ vips_check_noncomplex(const char *domain, VipsImage *im) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -741,7 +762,8 @@ vips_check_complex(const char *domain, VipsImage *im) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -768,7 +790,8 @@ vips_check_twocomponents(const char *domain, VipsImage *im) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -794,7 +817,8 @@ vips_check_format(const char *domain, VipsImage *im, VipsBandFormat fmt) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -818,7 +842,8 @@ vips_check_int(const char *domain, VipsImage *im) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -843,7 +868,8 @@ vips_check_uint(const char *domain, VipsImage *im) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -871,7 +897,8 @@ vips_check_8or16(const char *domain, VipsImage *im) * Otherwise set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -896,7 +923,8 @@ vips_check_u8or16(const char *domain, VipsImage *im) * Check that the image is 8 or 16-bit unsigned integer, or float. * Otherwise set an error message and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -922,7 +950,8 @@ vips_check_u8or16orf(const char *domain, VipsImage *im) * Check that the image is unsigned int or float. * Otherwise set an error message and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -951,7 +980,8 @@ vips_check_uintorf(const char *domain, VipsImage *im) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -976,7 +1006,8 @@ vips_check_size_same(const char *domain, VipsImage *im1, VipsImage *im2) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -1003,7 +1034,8 @@ vips_check_oddsquare(const char *domain, VipsImage *im) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -1030,7 +1062,8 @@ vips_check_bands_same(const char *domain, VipsImage *im1, VipsImage *im2) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -1057,7 +1090,8 @@ vips_check_bandno(const char *domain, VipsImage *im, int bandno) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -1083,7 +1117,8 @@ vips_check_format_same(const char *domain, VipsImage *im1, VipsImage *im2) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -1107,7 +1142,8 @@ vips_check_coding_same(const char *domain, VipsImage *im1, VipsImage *im2) * * Check that @n == @len. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -1132,7 +1168,8 @@ vips_check_vector_length(const char *domain, int n, int len) * the same number of elements as there are bands in the image, or a 1-band * image and a many-element vector. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -1169,7 +1206,8 @@ vips_check_vector(const char *domain, int n, VipsImage *im) * 65536 elements. Return 0 if the image will pass as a histogram, or -1 and * set an error message otherwise. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -1203,11 +1241,12 @@ vips_check_hist(const char *domain, VipsImage *im) * message otherwise. * * @out is set to be @im cast to double and stored in memory. Use - * VIPS_MATRIX() to address values in @out. + * [func@MATRIX] to address values in @out. * * You must unref @out when you are done with it. * - * See also: VIPS_MATRIX(), vips_object_local() + * ::: seealso + * [func@MATRIX]. * * Returns: 0 if OK, -1 otherwise. */ @@ -1249,7 +1288,8 @@ vips_check_matrix(const char *domain, VipsImage *im, VipsImage **out) * Return 0 if the image will pass, or -1 and * set an error message otherwise. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 if OK, -1 otherwise. */ @@ -1275,7 +1315,8 @@ vips_check_separable(const char *domain, VipsImage *im) * If not, set an error message * and return non-zero. * - * See also: vips_error(). + * ::: seealso + * [func@error]. * * Returns: 0 on OK, or -1 on error. */ diff --git a/libvips/iofuncs/gate.c b/libvips/iofuncs/gate.c index 029bbd057a..06958e06c4 100644 --- a/libvips/iofuncs/gate.c +++ b/libvips/iofuncs/gate.c @@ -250,7 +250,7 @@ vips_thread_profile_get(void) /* This usually happens automatically when a thread shuts down, but that will * not happen for the main thread. * - * Shut down any stats on the main thread with this, see vips_shutdown() + * Shut down any stats on the main thread with this, see vips_shutdown(). */ void vips__thread_profile_detach(void) diff --git a/libvips/iofuncs/generate.c b/libvips/iofuncs/generate.c index 3c2d417448..614619b9d3 100644 --- a/libvips/iofuncs/generate.c +++ b/libvips/iofuncs/generate.c @@ -368,7 +368,8 @@ vips__demand_hint_array(VipsImage *image, * VIPS uses the list of input images to build the tree of operations it needs * for the cache invalidation system. * - * See also: vips_image_pipelinev(), vips_image_generate(). + * ::: seealso + * [method@Image.pipelinev], [method@Image.generate]. * * Returns: 0 on success, -1 on error. */ @@ -402,9 +403,10 @@ vips_image_pipeline_array(VipsImage *image, * @hint: hint for this image * @...: %NULL-terminated list of input images * - * Build an array and call vips_image_pipeline_array(). + * Build an array and call [func@Image.pipeline_array]. * - * See also: vips_image_generate(). + * ::: seealso + * [method@Image.generate]. */ int vips_image_pipelinev(VipsImage *image, VipsDemandStyle hint, ...) @@ -438,7 +440,8 @@ vips_image_pipelinev(VipsImage *image, VipsDemandStyle hint, ...) * * Start function for one image in. Input image is @a. * - * See also: vips_image_generate(). + * ::: seealso + * [method@Image.generate]. */ void * vips_start_one(VipsImage *out, void *a, void *b) @@ -456,7 +459,8 @@ vips_start_one(VipsImage *out, void *a, void *b) * * Stop function for one image in. Input image is @a. * - * See also: vips_image_generate(). + * ::: seealso + * [method@Image.generate]. */ int vips_stop_one(void *seq, void *a, void *b) @@ -477,7 +481,8 @@ vips_stop_one(void *seq, void *a, void *b) * Stop function for many images in. @a is a pointer to * a %NULL-terminated array of input images. * - * See also: vips_image_generate(). + * ::: seealso + * [method@Image.generate]. */ int vips_stop_many(void *seq, void *a, void *b) @@ -504,7 +509,8 @@ vips_stop_many(void *seq, void *a, void *b) * Start function for many images in. @a is a pointer to * a %NULL-terminated array of input images. * - * See also: vips_image_generate(), vips_allocate_input_array() + * ::: seealso + * [method@Image.generate], [func@allocate_input_array] */ void * vips_start_many(VipsImage *out, void *a, void *b) @@ -542,9 +548,10 @@ vips_start_many(VipsImage *out, void *a, void *b) * @...: %NULL-terminated list of input images * * Convenience function --- make a %NULL-terminated array of input images. - * Use with vips_start_many(). + * Use with [func@start_many]. * - * See also: vips_image_generate(), vips_start_many(). + * ::: seealso + * [method@Image.generate], [func@start_many]. * * Returns: (transfer none) (nullable): %NULL-terminated array of images. * Do not free the result. @@ -588,14 +595,15 @@ vips_allocate_input_array(VipsImage *out, ...) * Start a new processing sequence for this generate function. This allocates * per-thread state, such as an input region. * - * See also: vips_start_one(), vips_start_many(). + * ::: seealso + * [func@start_one], [func@start_many]. * * Returns: a new sequence value */ /** * VipsGenerateFn: - * @out: #VipsRegion to fill + * @out: [class@Region] to fill * @seq: sequence value * @a: user data * @b: user data @@ -604,7 +612,8 @@ vips_allocate_input_array(VipsImage *out, ...) * Fill @out->valid with pixels. @seq contains per-thread state, such as the * input regions. Set @stop to %TRUE to stop processing. * - * See also: vips_image_generate(), vips_stop_many(). + * ::: seealso + * [method@Image.generate], [func@stop_many]. * * Returns: 0 on success, -1 on error. */ @@ -618,7 +627,8 @@ vips_allocate_input_array(VipsImage *out, ...) * Stop a processing sequence. This frees * per-thread state, such as an input region. * - * See also: vips_stop_one(), vips_stop_many(). + * ::: seealso + * [func@stop_one], [func@stop_many]. * * Returns: 0 on success, -1 on error. */ @@ -664,18 +674,19 @@ write_vips(VipsRegion *region, VipsRect *area, void *a) * * Generates an image. The action depends on the image type. * - * For images created with vips_image_new(), vips_image_generate() just + * For images created with [ctor@Image.new], vips_image_generate() just * attaches the start/generate/stop callbacks and returns. * - * For images created with vips_image_new_memory(), memory is allocated for - * the whole image and it is entirely generated using vips_sink_memory(). + * For images created with [ctor@Image.new_memory], memory is allocated for + * the whole image and it is entirely generated using [func@sink_memory]. * - * For images created with vips_image_new_temp_file() and friends, memory for + * For images created with [ctor@Image.new_temp_file] and friends, memory for * a few scanlines is allocated and - * vips_sink_disc() used to generate the image in small chunks. As each + * [method@Image.sink_disc] used to generate the image in small chunks. As each * chunk is generated, it is written to disc. * - * See also: vips_sink(), vips_image_new(), vips_region_prepare(). + * ::: seealso + * [func@sink_memory], [ctor@Image.new], [method@Region.prepare]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/iofuncs/ginputsource.c b/libvips/iofuncs/ginputsource.c index 71ab781cf1..6ec91b120c 100644 --- a/libvips/iofuncs/ginputsource.c +++ b/libvips/iofuncs/ginputsource.c @@ -287,10 +287,14 @@ vips_g_input_stream_init(VipsGInputStream *gstream) * vips_g_input_stream_new_from_source: * @source: vips source to wrap * - * Create a new #GInputStream wrapping a #VipsSource. This is useful for - * loaders like SVG and PDF which support GInput methods. + * Create a new [class@Gio.InputStream] wrapping a [class@Source]. This is + * useful for loaders like SVG and PDF which support [class@Gio.InputStream] + * methods. * - * Returns: (transfer full): a new #GInputStream + * ::: seealso + * [func@Source.g_input_stream_new] + * + * Returns: (transfer full): a new [class@Gio.InputStream] */ GInputStream * vips_g_input_stream_new_from_source(VipsSource *source) diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index b95c2fb61d..3d1cad1c34 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -1010,7 +1010,8 @@ vips_image_get_orientation_swap(VipsImage *image) * Since this function modifies @image, it is not threadsafe. Only call it on * images which you are sure have not been shared with another thread. * - * See also: [method@Image.wio_input] or [method@Image.copy_memory]. + * ::: seealso + * [method@Image.wio_input] or [method@Image.copy_memory]. * * Returns: (nullable) (transfer none): a pointer to pixel data, if possible. */ @@ -1042,7 +1043,8 @@ vips_image_get_data(VipsImage *image) * [ctor@Image.black] or [ctor@Image.jpegload], you do need to set all the * fields yourself. * - * See also: [method.Image.pipelinev]. + * ::: seealso + * [method.Image.pipelinev]. */ void vips_image_init_fields(VipsImage *image, @@ -1180,7 +1182,8 @@ vips__image_copy_fields_array(VipsImage *out, VipsImage *in[]) * g_value_unset(&value); * ``` * - * See also: [method@Image.image_get]. + * ::: seealso + * [method@Image.image_get]. */ void vips_image_set(VipsImage *image, const char *name, GValue *value) @@ -1282,7 +1285,8 @@ vips_set_value_from_pointer(GValue *value, void *data) * g_value_unset(&value); * ``` * - * See also: [method@Image.image_get_typeof] or [method@Image.image_get_double]. + * ::: seealso + * [method@Image.image_get_typeof] or [method@Image.image_get_double]. * * Returns: (skip): 0 on success, -1 otherwise. */ @@ -1344,7 +1348,8 @@ vips_image_get(const VipsImage *image, const char *name, GValue *value_copy) * Read the [alias@GObject.Type] for a header field. Returns zero if there * is no field of that name. * - * See also: [method@Image.image_get]. + * ::: seealso + * [method@Image.image_get]. * * Returns: the [alias@GObject.Type] of the field, or zero if there is no * field of that name. @@ -1388,7 +1393,8 @@ vips_image_get_typeof(const VipsImage *image, const char *name) * Find and remove an item of metadata. Return `FALSE` if no metadata of that * name was found. * - * See also: [method@Image.image_set] or [method@Image.image_get_typeof]. + * ::: seealso + * [method@Image.image_set] or [method@Image.image_get_typeof]. * * Returns: `TRUE` if an item of metadata of that name was found and removed */ @@ -1451,7 +1457,8 @@ vips_image_map_fn(VipsMeta *meta, VipsImageMapFn fn, void *a) * Like all _map functions, the user function should return `NULL` to continue * iteration, or a non-`NULL` pointer to indicate early termination. * - * See also: [method@Image.image_get_typeof] or [method@Image.image_get]. + * ::: seealso + * [method@Image.image_get_typeof] or [method@Image.image_get]. * * Returns: (nullable) (transfer none): `NULL` on success, the failing * pointer otherwise. @@ -1542,7 +1549,8 @@ vips_image_get_fields(VipsImage *image) * Attaches @data as a metadata item on @image under the name @name. When * VIPS no longer needs the metadata, it will be freed with @free_fn. * - * See also: [method@Image.image_get_double] or [method@Image.image_set]. + * ::: seealso + * [method@Image.image_get_double] or [method@Image.image_set]. */ void vips_image_set_area(VipsImage *image, const char *name, @@ -1589,7 +1597,8 @@ meta_get_value(const VipsImage *image, * function over [method@Image.image_get]. Use [method@Image.image_get_typeof] to * test for the existence of a piece of metadata. * - * See also: [method@Image.set_area], [method@Image.image_get] or + * ::: seealso + * [method@Image.set_area], [method@Image.image_get] or * [method@Image.image_get_typeof]. * * Returns: 0 on success, -1 otherwise. @@ -1620,7 +1629,8 @@ vips_image_get_area(const VipsImage *image, * * Attaches @data as a metadata item on @image under the name @name. * - * See also: [method@Image.image_get_blob] or [method@Image.image_set]. + * ::: seealso + * [method@Image.image_get_blob] or [method@Image.image_set]. */ void vips_image_set_blob(VipsImage *image, const char *name, @@ -1644,7 +1654,8 @@ vips_image_set_blob(VipsImage *image, const char *name, * Attaches @data as a metadata item on @image under the name @name, taking * a copy of the memory area. * - * See also: [method@Image.image_get_blob] or [method@Image.image_set]. + * ::: seealso + * [method@Image.image_get_blob] or [method@Image.image_set]. */ void vips_image_set_blob_copy(VipsImage *image, @@ -1684,7 +1695,8 @@ vips_image_set_blob_copy(VipsImage *image, * length in @length. Use [method@Image.image_get_typeof] to test for the existence * of a piece of metadata. * - * See also: [method@Image.image_get], [method@Image.image_get_typeof] or + * ::: seealso + * [method@Image.image_get], [method@Image.image_get_typeof] or * [method@Blob.get]. * * Returns: 0 on success, -1 otherwise. @@ -1713,7 +1725,8 @@ vips_image_get_blob(const VipsImage *image, const char *name, * Gets @out from @im under the name @name. * The value will be transformed into an int, if possible. * - * See also: [method@Image.image_get] or [method@Image.image_get_typeof]. + * ::: seealso + * [method@Image.image_get] or [method@Image.image_get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1739,7 +1752,8 @@ vips_image_get_int(const VipsImage *image, const char *name, int *out) * Attaches @i as a metadata item on @image under the name @name. A * convenience function over [method@Image.image_set]. * - * See also: [method@Image.image_get_int] or [method@Image.image_set]. + * ::: seealso + * [method@Image.image_get_int] or [method@Image.image_set]. */ void vips_image_set_int(VipsImage *image, const char *name, int i) @@ -1761,7 +1775,8 @@ vips_image_set_int(VipsImage *image, const char *name, int i) * Gets @out from @im under the name @name. * The value will be transformed into a double, if possible. * - * See also: [method@Image.image_get] or [method@Image.image_get_typeof]. + * ::: seealso + * [method@Image.image_get] or [method@Image.image_get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1787,7 +1802,8 @@ vips_image_get_double(const VipsImage *image, const char *name, double *out) * Attaches @d as a metadata item on @image as @name. A * convenience function over [method@Image.image_set]. * - * See also: [method@Image.image_get_double] or [method@Image.image_set]. + * ::: seealso + * [method@Image.image_get_double] or [method@Image.image_set]. */ void vips_image_set_double(VipsImage *image, const char *name, double d) @@ -1813,7 +1829,8 @@ vips_image_set_double(VipsImage *image, const char *name, double d) * * Use [method@Image.get_as_string] to fetch any field as a string. * - * See also: [method@Image.image_get] or [method@Image.image_get_typeof]. + * ::: seealso + * [method@Image.image_get] or [method@Image.image_get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1860,7 +1877,8 @@ vips_image_get_string(const VipsImage *image, const char *name, * A convenience * function over [method@Image.image_set] using `VIPS_TYPE_REF_STRING`. * - * See also: [method@Image.image_get_double] or [method@Image.image_set]. + * ::: seealso + * [method@Image.image_get_double] or [method@Image.image_set]. */ void vips_image_set_string(VipsImage *image, const char *name, const char *str) @@ -1881,12 +1899,13 @@ vips_image_set_string(VipsImage *image, const char *name, const char *str) * * Returns @name from @image in @out. * This function will read any field, returning it as a printable string. - * You need to free the string with g_free() when you are done with it. + * You need to free the string with [func@GLib.free] when you are done with it. * * This will base64-encode BLOBs, for example. Use [method@Buf.appendg] to * make a string that's for humans. * - * See also: [method@Image.image_get], [method@Image.image_get_typeof] or + * ::: seealso + * [method@Image.image_get], [method@Image.image_get_typeof] or * [method@Buf.appendg]. * * Returns: 0 on success, -1 otherwise. @@ -1952,7 +1971,7 @@ vips_image_print_field(const VipsImage *image, const char *name) * * Gets @out from @im under the name @name. * The field must be of type `VIPS_TYPE_IMAGE`. - * You must unref @out with g_object_unref(). + * You must unref @out with [method@GObject.Object.unref]. * * Use [method@Image.image_get_typeof] to test for the * existence of a piece of metadata. @@ -1984,7 +2003,8 @@ vips_image_get_image(const VipsImage *image, * Attaches @im as a metadata item on @image as @name. * A convenience function over [method@Image.image_set]. * - * See also: [method@Image.image_get_image] or [method@Image.image_set]. + * ::: seealso + * [method@Image.image_get_image] or [method@Image.image_set]. */ void vips_image_set_image(VipsImage *image, const char *name, VipsImage *im) @@ -2040,7 +2060,8 @@ vips_image_get_array_int(VipsImage *image, const char *name, * Attaches @array as a metadata item on @image as @name. * A convenience function over [method@Image.image_set]. * - * See also: [method@Image.image_get_image] or [method@Image.image_set]. + * ::: seealso + * [method@Image.image_get_image] or [method@Image.image_set]. */ void vips_image_set_array_int(VipsImage *image, const char *name, @@ -2097,7 +2118,8 @@ vips_image_get_array_double(VipsImage *image, const char *name, * Attaches @array as a metadata item on @image as @name. * A convenience function over [method@Image.image_set]. * - * See also: [method@Image.image_get_image] or [method@Image.image_set]. + * ::: seealso + * [method@Image.image_get_image] or [method@Image.image_set]. */ void vips_image_set_array_double(VipsImage *image, const char *name, @@ -2182,7 +2204,8 @@ vips_image_history_printf(VipsImage *image, const char *fmt, ...) * [method@Image.history_printf]. A convenience function for * command-line programs. * - * See also: [method@Image.get_history]. + * ::: seealso + * [method@Image.get_history]. * * Returns: 0 on success, -1 on error. */ @@ -2219,7 +2242,8 @@ vips_image_history_args(VipsImage *image, * [method@Image.history_printf] for each action they perform, setting the * command-line equivalent for the action. * - * See also: [method@Image.history_printf]. + * ::: seealso + * [method@Image.history_printf]. * * Returns: (transfer none): The history of @image as a C string. Do not free! */ diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index ba3d6b5839..10098640d6 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -19,7 +19,7 @@ * 9/10/18 * - fix up vips_image_dump(), it was still using ints not enums * 10/12/19 - * - add vips_image_new_from_source() / vips_image_write_to_target() + * - add vips_image_new_from_source / vips_image_write_to_target() */ /* @@ -150,8 +150,8 @@ * @VIPS_ACCESS_RANDOM: can read anywhere * @VIPS_ACCESS_SEQUENTIAL: top-to-bottom reading only, but with a small buffer * - * The type of access an operation has to supply. See vips_tilecache() - * and #VipsForeign. + * The type of access an operation has to supply. See [method@Image.tilecache] + * and [class@Foreign]. * * @VIPS_ACCESS_RANDOM means requests can come in any order. * @@ -166,34 +166,35 @@ * @VIPS_DEMAND_STYLE_THINSTRIP: demand in thin (typically 1 pixel high) strips * @VIPS_DEMAND_STYLE_ANY: demand geometry does not matter * - * See vips_image_pipelinev(). Operations can hint + * See [method@Image.pipelinev]. Operations can hint * the kind of demand geometry they prefer * to the VIPS image IO system. * * These demand styles are given below in order of increasing * specialisation. When demanding output from a pipeline, - * vips_image_generate() + * [method@Image.generate] * will use the most general style requested by the operations * in the pipeline. * - * #VIPS_DEMAND_STYLE_SMALLTILE --- This is the most general demand format. + * @VIPS_DEMAND_STYLE_SMALLTILE -- This is the most general demand format. * Output is demanded in small (around 100x100 pel) sections. This style works * reasonably efficiently, even for bizarre operations like 45 degree rotate. * - * #VIPS_DEMAND_STYLE_FATSTRIP --- This operation would like to output strips + * @VIPS_DEMAND_STYLE_FATSTRIP -- This operation would like to output strips * the width of the image and as high as possible. This option is suitable * for area operations which do not violently transform coordinates, such - * as vips_conv(). + * as [method@Image.conv]. * - * #VIPS_DEMAND_STYLE_THINSTRIP --- This operation would like to output strips + * @VIPS_DEMAND_STYLE_THINSTRIP -- This operation would like to output strips * the width of the image and a few pels high. This option is suitable for * point-to-point operations, such as those in the arithmetic package. * - * #VIPS_DEMAND_STYLE_ANY --- This image is not being demand-read from a disc + * @VIPS_DEMAND_STYLE_ANY -- This image is not being demand-read from a disc * file (even indirectly) so any demand style is OK. It's used for things like - * vips_black() where the pixels are calculated. + * [ctor@Image.black] where the pixels are calculated. * - * See also: vips_image_pipelinev(). + * ::: seealso + * [method@Image.pipelinev]. */ /** @@ -205,7 +206,7 @@ * @VIPS_INTERPRETATION_XYZ: the first three bands are CIE XYZ * @VIPS_INTERPRETATION_LAB: pixels are in CIE Lab space * @VIPS_INTERPRETATION_CMYK: the first four bands are in CMYK space - * @VIPS_INTERPRETATION_LABQ: implies #VIPS_CODING_LABQ + * @VIPS_INTERPRETATION_LABQ: implies @VIPS_CODING_LABQ * @VIPS_INTERPRETATION_RGB: generic RGB space * @VIPS_INTERPRETATION_CMC: a uniform colourspace based on CMC(1:1) * @VIPS_INTERPRETATION_LCH: pixels are in CIE LCh space @@ -219,7 +220,7 @@ * @VIPS_INTERPRETATION_MATRIX: a matrix * * How the values in an image should be interpreted. For example, a - * three-band float image of type #VIPS_INTERPRETATION_LAB should have its + * three-band float image of type @VIPS_INTERPRETATION_LAB should have its * pixels interpreted as coordinates in CIE Lab space. * * RGB and sRGB are treated in the same way. Use the colourspace functions if @@ -246,7 +247,7 @@ * The format used for each band element. * * Each corresponds to a native C type for the current machine. For example, - * #VIPS_FORMAT_USHORT is unsigned short. + * [enum@Vips.BandFormat.USHORT] is unsigned short. */ /** @@ -275,77 +276,78 @@ * @start: Start time * * A structure available to eval callbacks giving information on evaluation - * progress. See #VipsImage::eval. + * progress. See [signal@Image::eval]. */ /** * VIPS_IMAGE_SIZEOF_ELEMENT: - * @I: a #VipsImage + * @I: a [class@Image] * * Returns: sizeof() a band element. */ /** * VIPS_IMAGE_SIZEOF_PEL: - * @I: a #VipsImage + * @I: a [class@Image] * * Returns: sizeof() a pixel. */ /** * VIPS_IMAGE_SIZEOF_LINE: - * @I: a #VipsImage + * @I: a [class@Image] * * Returns: sizeof() a scanline of pixels. */ /** * VIPS_IMAGE_N_ELEMENTS: - * @I: a #VipsImage + * @I: a [class@Image] * * Returns: The number of band elements in a scanline. */ /** * VIPS_IMAGE_N_PELS: - * @I: a #VipsImage + * @I: a [class@Image] * * Returns: The number of pels in an image. A 64-bit unsigned int. */ /** * VIPS_IMAGE_ADDR: - * @I: a #VipsImage + * @I: a [class@Image] * @X: x coordinate * @Y: y coordinate * - * This macro returns a pointer to a pixel in an image, cast to a #VipsPel *. - * It only works for - * images which are fully available in memory, so memory buffers and small - * mapped images only. + * This macro returns a pointer to a pixel in an image, cast to a [alias@Pel]*. + * It only works for images which are fully available in memory, so memory + * buffers and small mapped images only. * * If VIPS_DEBUG is defined, you get a version that checks bounds for you. * - * See also: vips_image_wio_input(), vips_image_inplace(), VIPS_REGION_ADDR(). + * ::: seealso + * [method@Image.wio_input], [method@Image.inplace], VIPS_REGION_ADDR(). * * Returns: The address of pixel (@X,@Y) in @I. */ /** * VIPS_MATRIX: - * @I: a #VipsImage + * @I: a [class@Image] * @X: x coordinate * @Y: y coordinate * * This macro returns a pointer to a pixel in an image, cast to a double*. The - * image must have a single band, be #VIPS_FORMAT_DOUBLE and be + * image must have a single band, be [enum@Vips.BandFormat.DOUBLE] and be * fully available in memory, so memory buffers and small * mapped images only. * * If VIPS_DEBUG is defined, you get a version that checks bounds and image * type for you. * - * See also: vips_image_wio_input(), vips_image_inplace(), vips_check_matrix(). + * ::: seealso + * [method@Image.wio_input], [method@Image.inplace], [func@check_matrix]. * * Returns: The address of pixel (@X,@Y) in @I. */ @@ -585,8 +587,7 @@ vips_image_dump(VipsObject *object, VipsBuf *buf) vips_image_get_bands(image)), vips_image_get_width(image), vips_image_get_height(image), - vips_enum_nick(VIPS_TYPE_BAND_FORMAT, - vips_image_get_format(image)), + vips_enum_nick(VIPS_TYPE_BAND_FORMAT, vips_image_get_format(image)), vips_image_get_bands(image), vips_enum_nick(VIPS_TYPE_INTERPRETATION, vips_image_get_interpretation(image))); @@ -617,8 +618,7 @@ vips_image_summary(VipsObject *object, VipsBuf *buf) " %s, %d band, %s", " %s, %d bands, %s", vips_image_get_bands(image)), - vips_enum_nick(VIPS_TYPE_BAND_FORMAT, - vips_image_get_format(image)), + vips_enum_nick(VIPS_TYPE_BAND_FORMAT, vips_image_get_format(image)), vips_image_get_bands(image), vips_enum_nick(VIPS_TYPE_INTERPRETATION, vips_image_get_interpretation(image))); @@ -833,7 +833,7 @@ vips_image_build(VipsObject *object) switch (mode[0]) { case 'v': /* Used by 'r' for native open of vips, see below. Also by - * vips_image_rewind_output(). + * [method@Image.rewind_output]. */ if (vips_image_open_input(image)) return -1; @@ -1200,12 +1200,12 @@ vips_image_class_init(VipsImageClass *class) /** * VipsImage::preeval: * @image: the image to be calculated - * @progress: (type VipsProgress): #VipsProgress for this image + * @progress: (type VipsProgress): [struct@Progress] for this image * - * The ::preeval signal is emitted once before computation of @image + * This signal is emitted once before computation of @image * starts. It's a good place to set up evaluation feedback. * - * Use vips_image_set_progress() to turn on progress reporting for an + * Use [method@Image.set_progress] to turn on progress reporting for an * image. */ vips_image_signals[SIG_PREEVAL] = g_signal_new("preeval", @@ -1220,16 +1220,16 @@ vips_image_class_init(VipsImageClass *class) /** * VipsImage::eval: * @image: the image being calculated - * @progress: (type VipsProgress): #VipsProgress for this image + * @progress: (type VipsProgress): [struct@Progress] for this image * - * The ::eval signal is emitted once per work unit (typically a 128 x + * This signal is emitted once per work unit (typically a 128 x * 128 area of pixels) during image computation. * * You can use this signal to update user-interfaces with progress * feedback. Beware of updating too frequently: you will usually * need some throttling mechanism. * - * Use vips_image_set_progress() to turn on progress reporting for an + * Use [method@Image.set_progress] to turn on progress reporting for an * image. */ vips_image_signals[SIG_EVAL] = g_signal_new("eval", @@ -1244,12 +1244,12 @@ vips_image_class_init(VipsImageClass *class) /** * VipsImage::posteval: * @image: the image that was calculated - * @progress: (type VipsProgress): #VipsProgress for this image + * @progress: (type VipsProgress): [struct@Progress] for this image * - * The ::posteval signal is emitted once at the end of the computation + * This signal is emitted once at the end of the computation * of @image. It's a good place to shut down evaluation feedback. * - * Use vips_image_set_progress() to turn on progress reporting for an + * Use [method@Image.set_progress] to turn on progress reporting for an * image. */ vips_image_signals[SIG_POSTEVAL] = g_signal_new("posteval", @@ -1266,7 +1266,7 @@ vips_image_class_init(VipsImageClass *class) * @image: the image that was calculated * @result: (out) (type gint): set to non-zero to indicate error * - * The ::written signal is emitted just after an image has been + * This signal is emitted just after an image has been * written to. It is * used by vips to implement things like write to foreign file * formats. @@ -1284,9 +1284,9 @@ vips_image_class_init(VipsImageClass *class) * VipsImage::invalidate: * @image: the image that has changed * - * The ::invalidate signal is emitted when an image or one of it's + * This signal is emitted when an image or one of it's * upstream data sources has been destructively modified. See - * vips_image_invalidate_all(). + * [method@Image.invalidate_all]. */ vips_image_signals[SIG_INVALIDATE] = g_signal_new("invalidate", G_TYPE_FROM_CLASS(class), @@ -1300,9 +1300,9 @@ vips_image_class_init(VipsImageClass *class) * VipsImage::minimise: * @image: the image that is being minimised * - * The ::minimise signal is emitted when an image has been asked to + * This signal is emitted when an image has been asked to * minimise memory usage. All non-essential caches are dropped. - * See vips_image_minimise_all(). + * See [method@Image.minimise_all]. */ vips_image_signals[SIG_MINIMISE] = g_signal_new("minimise", G_TYPE_FROM_CLASS(class), @@ -1375,18 +1375,19 @@ vips_image_invalidate_all_cb(VipsImage *image, void *a, void *b) /** * vips_image_invalidate_all: - * @image: #VipsImage to invalidate + * @image: [class@Image] to invalidate * * Invalidate all pixel caches on @image and any downstream images, that * is, images which depend on this image. Additionally, all operations which * depend upon this image are dropped from the VIPS operation cache. * - * You should call this function after - * destructively modifying an image with something like vips_draw_circle(). + * You should call this function after destructively modifying an image with + * something like [method@Image.draw_circle]. * - * The #VipsImage::invalidate signal is emitted for all invalidated images. + * The [signal@Image::invalidate] signal is emitted for all invalidated images. * - * See also: vips_region_invalidate(). + * ::: seealso + * [method@Region.invalidate]. */ void vips_image_invalidate_all(VipsImage *image) @@ -1415,13 +1416,13 @@ vips_image_minimise_all_cb(VipsImage *image, void *a, void *b) /** * vips_image_minimise_all: - * @image: #VipsImage to minimise + * @image: [class@Image] to minimise * * Minimise memory use on this image and any upstream images, that is, images * which this image depends upon. This function is called automatically at the * end of a computation, but it might be useful to call at other times. * - * The #VipsImage::minimise signal is emitted for all minimised images. + * The [signal@Image::minimise] signal is emitted for all minimised images. */ void vips_image_minimise_all(VipsImage *image) @@ -1439,7 +1440,7 @@ vips_image_minimise_all(VipsImage *image) /** * vips_image_is_sequential: - * @image: #VipsImage to minimise + * @image: [class@Image] to minimise * * TRUE if any of the images upstream from @image were opened in sequential * mode. Some operations change behaviour slightly in sequential mode to @@ -1517,7 +1518,7 @@ vips_image_preeval(VipsImage *image) /* For vips7 compat, we also have to make sure ->time on the * image that was originally marked with - * vips_image_set_progress() is valid. + * [method@Image.set_progress] is valid. */ (void) vips_progress_add(image->progress_signal); @@ -1594,10 +1595,10 @@ vips_image_posteval(VipsImage *image) * @image: image to signal progress on * @progress: turn progress reporting on or off * - * vips signals evaluation progress via the #VipsImage::preeval, - * #VipsImage::eval and #VipsImage::posteval + * vips signals evaluation progress via the [signal@Image::preeval], + * [signal@Image::eval] and [signal@Image::posteval] * signals. Progress is signalled on the most-downstream image for which - * vips_image_set_progress() was called. + * [method@Image.set_progress] was called. */ void vips_image_set_progress(VipsImage *image, gboolean progress) @@ -1616,12 +1617,13 @@ vips_image_set_progress(VipsImage *image, gboolean progress) * vips_image_iskilled: * @image: image to test * - * If @image has been killed (see vips_image_set_kill()), set an error message, - * clear the #VipsImage.kill flag and return %TRUE. Otherwise return %FALSE. + * If @image has been killed (see [method@Image.set_kill]), set an error message, + * clear the [class@Image].kill flag and return %TRUE. Otherwise return %FALSE. * * Handy for loops which need to run sets of threads which can fail. * - * See also: vips_image_set_kill(). + * ::: seealso + * [method@Image.set_kill]. * * Returns: %TRUE if @image has been killed. */ @@ -1658,10 +1660,11 @@ vips_image_iskilled(VipsImage *image) * @image: image to test * @kill: the kill state * - * Set the #VipsImage.kill flag on an image. Handy for stopping sets of + * Set the [class@Image].kill flag on an image. Handy for stopping sets of * threads. * - * See also: vips_image_iskilled(). + * ::: seealso + * [method@Image.iskilled]. */ void vips_image_set_kill(VipsImage *image, gboolean kill) @@ -1693,15 +1696,15 @@ vips_image_temp_name(char *name, int size) /** * vips_image_new: (constructor) * - * vips_image_new() creates a new, empty #VipsImage. + * [ctor@Image.new] creates a new, empty [class@Image]. * If you write to one of these images, vips will just attach some callbacks, * no pixels will be generated. * - * Write pixels to an image with vips_image_generate() or - * vips_image_write_line(). Write a whole image to another image with - * vips_image_write(). + * Write pixels to an image with [method@Image.generate] or + * [method@Image.write_line]. Write a whole image to another image with + * [method@Image.write]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new(void) @@ -1752,12 +1755,13 @@ vips_image_new_mode(const char *filename, const char *mode) /** * vips_image_new_memory: (skip) * - * vips_image_new_memory() creates a new #VipsImage which, when written to, will + * [ctor@Image.new_memory] creates a new [class@Image] which, when written to, will * create a memory image. * - * See also: vips_image_new(). + * ::: seealso + * [ctor@Image.new]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_memory(void) @@ -1771,12 +1775,13 @@ vips_image_new_memory(void) /** * vips_image_memory: (constructor) * - * A renamed vips_image_new_memory() ... Some gobject binding systems do not + * A renamed [ctor@Image.new_memory] ... Some gobject binding systems do not * like more than one _new() method. * - * See also: vips_image_new_memory(). + * ::: seealso + * [ctor@Image.new_memory]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_memory(void) @@ -1793,7 +1798,8 @@ vips_image_memory(void) * * Useful for language bindings. * - * See also: vips_filename_get_options(). + * ::: seealso + * [func@filename_get_options]. * * Returns: transfer full: just the filename component. */ @@ -1817,7 +1823,8 @@ vips_filename_get_filename(const char *vips_filename) * * Useful for language bindings. * - * See also: vips_filename_get_filename(). + * ::: seealso + * [func@filename_get_filename]. * * Returns: transfer full: just the options component. */ @@ -1837,42 +1844,41 @@ vips_filename_get_options(const char *vips_filename) * @name: file to open * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @access: hint #VipsAccess mode to loader - * * @memory: force load via memory + * ::: note "Optional arguments" + * * @access: hint [enum@Access] mode to loader + * * @memory: force load via memory * - * vips_image_new_from_file() opens @name for reading. It can load files + * [ctor@Image.new_from_file] opens @name for reading. It can load files * in many image formats, including VIPS, TIFF, PNG, JPEG, FITS, Matlab, * OpenEXR, CSV, WebP, Radiance, RAW, PPM and others. * * Load options may be appended to @filename as "[name=value,...]" or given as * a NULL-terminated list of name-value pairs at the end of the arguments. * Options given in the function call override options given in the filename. - * Many loaders add extra options, see vips_jpegload(), for example. + * Many loaders add extra options, see [ctor@Image.jpegload], for example. * - * vips_image_new_from_file() always returns immediately with the header + * [ctor@Image.new_from_file] always returns immediately with the header * fields filled in. No pixels are actually read until you first access them. * - * @access lets you set a #VipsAccess hint giving the expected access pattern + * @access lets you set a [enum@Access] hint giving the expected access pattern * for this file. - * #VIPS_ACCESS_RANDOM means you can fetch pixels randomly from the image. - * This is the default mode. #VIPS_ACCESS_SEQUENTIAL means you will read the - * whole image exactly once, top-to-bottom. In this mode, vips can avoid - * converting the whole image in one go, for a large memory saving. You are - * allowed to make small non-local references, so area operations like + * [enum@Vips.Access.RANDOM] means you can fetch pixels randomly from the image. + * This is the default mode. [enum@Vips.Access.SEQUENTIAL] means you will + * read the whole image exactly once, top-to-bottom. In this mode, libvips + * can avoid converting the whole image in one go, for a large memory saving. + * You are allowed to make small non-local references, so area operations like * convolution will work. * - * In #VIPS_ACCESS_RANDOM mode, small images are decompressed to memory and - * then processed from there. Large images are decompressed to temporary + * In [enum@Vips.Access.RANDOM] mode, small images are decompressed to memory + * and then processed from there. Large images are decompressed to temporary * random-access files on disc and then processed from there. * * Set @memory to %TRUE to force loading via memory. The default is to load * large random access images via temporary disc files. See - * vips_image_new_temp_file() for an + * [ctor@Image.new_temp_file] for an * explanation of how VIPS selects a location for the temporary file. * - * The disc threshold can be set with the "--vips-disc-threshold" + * The disc threshold can be set with the `--vips-disc-threshold` * command-line argument, or the `VIPS_DISC_THRESHOLD` environment variable. * The value is a simple integer, but can take a unit postfix of "k", * "m" or "g" to indicate kilobytes, megabytes or gigabytes. @@ -1880,30 +1886,31 @@ vips_filename_get_options(const char *vips_filename) * * For example: * - * |[ + * ```c * VipsImage *image = vips_image_new_from_file("fred.tif", * "page", 12, * NULL); - * ]| + * ``` * * Will open "fred.tif", reading page 12. * - * |[ + * ```c * VipsImage *image = vips_image_new_from_file("fred.jpg[shrink=2]", * NULL); - * ]| + * ``` * - * Will open "fred.jpg", downsampling by a factor of two. + * Will open `fred.jpg`, downsampling by a factor of two. * - * Use vips_foreign_find_load() or vips_foreign_is_a() to see what format a + * Use [func@Foreign.find_load] or [func@Foreign.is_a] to see what format a * file is in and therefore what options are available. If you need more * control over the loading process, you can call loaders directly, see - * vips_jpegload(), for example. + * [ctor@Image.jpegload], for example. * - * See also: vips_foreign_find_load(), vips_foreign_is_a(), - * vips_image_write_to_file(). + * ::: seealso + * [func@Foreign.find_load], [func@Foreign.is_a], + * [method@Image.write_to_file]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_from_file(const char *name, ...) @@ -1941,9 +1948,10 @@ vips_image_new_from_file(const char *name, ...) * work for VIPS files in a format native to your machine. It is only for * paintbox-type applications. * - * See also: vips_draw_circle(). + * ::: seealso + * [method@Image.draw_circle]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_from_file_RW(const char *filename) @@ -1959,15 +1967,16 @@ vips_image_new_from_file_RW(const char *filename) * @bands: image bands (or bytes per pixel) * @offset: bytes to skip at start of file * - * This function maps the named file and returns a #VipsImage you can use to + * This function maps the named file and returns a [class@Image] you can use to * read it. * * It returns an 8-bit image with @bands bands. If the image is not 8-bit, use - * vips_copy() to transform the descriptor after loading it. + * [method@Image.copy] to transform the descriptor after loading it. * - * See also: vips_copy(), vips_rawload(), vips_image_new_from_file(). + * ::: seealso + * [method@Image.copy], [ctor@Image.rawload], [ctor@Image.new_from_file]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_from_file_raw(const char *filename, @@ -2003,26 +2012,27 @@ vips_image_new_from_file_raw(const char *filename, * @bands: image bands (or bytes per pixel) * @format: image format * - * This function wraps a #VipsImage around a memory area. The memory area + * This function wraps a [class@Image] around a memory area. The memory area * must be a simple array, for example RGBRGBRGB, left-to-right, - * top-to-bottom. Use vips_image_new_from_buffer() to load an area of memory + * top-to-bottom. Use [ctor@Image.new_from_buffer] to load an area of memory * containing an image in a format. * * VIPS does not take * responsibility for the area of memory, it's up to you to make sure it's - * freed when the image is closed. See for example #VipsObject::close. + * freed when the image is closed. See for example [signal@Object::close]. * * Because VIPS is "borrowing" @data from the caller, this function is * extremely dangerous. Unless you are very careful, you will get crashes or - * memory corruption. Use vips_image_new_from_memory_copy() instead if you are + * memory corruption. Use [ctor@Image.new_from_memory_copy] instead if you are * at all unsure. * - * Use vips_copy() to set other image properties. + * Use [method@Image.copy] to set other image properties. * - * See also: vips_image_new(), vips_image_write_to_memory(), - * vips_image_new_from_memory_copy(). + * ::: seealso + * [ctor@Image.new], [method@Image.write_to_memory], + * [ctor@Image.new_from_memory_copy]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_from_memory(const void *data, size_t size, @@ -2076,13 +2086,14 @@ vips_image_new_from_memory_copy_cb(VipsImage *image, void *data_copy) * @bands: image bands (or bytes per pixel) * @format: image format * - * Like vips_image_new_from_memory(), but VIPS will make a copy of the memory + * Like [ctor@Image.new_from_memory], but VIPS will make a copy of the memory * area. This means more memory use and an extra copy operation, but is much * simpler and safer. * - * See also: vips_image_new_from_memory(). + * ::: seealso + * [ctor@Image.new_from_memory]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_from_memory_copy(const void *data, size_t size, @@ -2116,21 +2127,22 @@ vips_image_new_from_memory_copy(const void *data, size_t size, * @...: %NULL-terminated list of optional named arguments * * Loads an image from the formatted area of memory @buf, @len using the - * loader recommended by vips_foreign_find_load_buffer(). + * loader recommended by [func@Foreign.find_load_buffer]. * To load an unformatted area of memory, use - * vips_image_new_from_memory(). + * [ctor@Image.new_from_memory]. * * VIPS does not take * responsibility for the area of memory, it's up to you to make sure it's - * freed when the image is closed. See for example #VipsObject::close. + * freed when the image is closed. See for example [signal@Object::close]. * * Load options may be given in @option_string as "[name=value,...]" or given as * a NULL-terminated list of name-value pairs at the end of the arguments. * Options given in the function call override options given in the filename. * - * See also: vips_image_write_to_buffer(). + * ::: seealso + * [method@Image.write_to_buffer]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_from_buffer(const void *buf, size_t len, @@ -2171,15 +2183,16 @@ vips_image_new_from_buffer(const void *buf, size_t len, * @...: %NULL-terminated list of optional named arguments * * Loads an image from the formatted source @input, - * loader recommended by vips_foreign_find_load_source(). + * loader recommended by [func@Foreign.find_load_source]. * * Load options may be given in @option_string as "[name=value,...]" or given as * a NULL-terminated list of name-value pairs at the end of the arguments. * Options given in the function call override options given in the string. * - * See also: vips_image_write_to_target(). + * ::: seealso + * [method@Image.write_to_target]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_from_source(VipsSource *source, @@ -2256,15 +2269,16 @@ vips_image_new_from_source(VipsSource *source, * @height: image height * * This convenience function makes an image which is a matrix: a one-band - * #VIPS_FORMAT_DOUBLE image held in memory. + * [enum@Vips.BandFormat.DOUBLE] image held in memory. * - * Use VIPS_IMAGE_ADDR(), or VIPS_MATRIX() to address pixels in the image. + * Use [func@IMAGE_ADDR], or [func@MATRIX] to address pixels in the image. * - * Use vips_image_set_double() to set "scale" and "offset", if required. + * Use [method@Image.set_double] to set "scale" and "offset", if required. * - * See also: vips_image_new_matrixv() + * ::: seealso + * [ctor@Image.new_matrixv] * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_matrix(int width, int height) @@ -2302,13 +2316,14 @@ vips_image_new_matrix(int width, int height) * @height: image height * @...: matrix coefficients * - * As vips_image_new_matrix(), but initialise the matrix from the argument + * As [ctor@Image.new_matrix], but initialise the matrix from the argument * list. After @height should be @width * @height double constants which are * used to set the matrix elements. * - * See also: vips_image_new_matrix() + * ::: seealso + * [ctor@Image.new_matrix] * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_matrixv(int width, int height, ...) @@ -2337,9 +2352,9 @@ vips_image_new_matrixv(int width, int height, ...) * @array: (array length=size) (transfer none): array of elements * @size: (type gsize): number of elements * - * A binding-friendly version of vips_image_new_matrixv(). + * A binding-friendly version of [ctor@Image.new_matrixv]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_matrix_from_array(int width, int height, @@ -2375,10 +2390,10 @@ vips_image_new_matrix_from_array(int width, int height, * @array: (array length=size) (transfer none): array of elements * @size: (type gsize): number of elements * - * A renamed vips_image_new_matrix_from_array(). Some gobject bindings do not + * A renamed [ctor@Image.new_matrix_from_array]. Some gobject bindings do not * like more than one _new method. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_matrix_from_array(int width, int height, @@ -2398,9 +2413,10 @@ vips_image_matrix_from_array(int width, int height, * and offset taken from @image, but with number of bands taken from @n and the * value of each band element set from @c. * - * See also: vips_image_new_from_image1() + * ::: seealso + * [ctor@Image.new_from_image1] * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_from_image(VipsImage *image, const double *c, int n) @@ -2452,9 +2468,10 @@ vips_image_new_from_image(VipsImage *image, const double *c, int n) * and offset taken from @image, but with one band and each pixel having the * value @c. * - * See also: vips_image_new_from_image() + * ::: seealso + * [ctor@Image.new_from_image] * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_from_image1(VipsImage *image, double c) @@ -2473,7 +2490,8 @@ vips_image_new_from_image1(VipsImage *image, double c) * * This function is clearly extremely dangerous, use with great caution. * - * See also: vips_image_new_temp_file(). + * ::: seealso + * [ctor@Image.new_temp_file]. */ void vips_image_set_delete_on_close(VipsImage *image, gboolean delete_on_close) @@ -2493,7 +2511,7 @@ vips_image_set_delete_on_close(VipsImage *image, gboolean delete_on_close) * Return the number of bytes at which we flip between open via memory and * open via disc. This defaults to 100mb, but can be changed with the * VIPS_DISC_THRESHOLD environment variable or the --vips-disc-threshold - * command-line flag. See vips_image_new_from_file(). + * command-line flag. See [ctor@Image.new_from_file]. * * Returns: disc threshold in bytes. */ @@ -2534,7 +2552,7 @@ vips_get_disc_threshold(void) * vips_image_new_temp_file: (constructor) * @format: format of file * - * Make a #VipsImage which, when written to, will create a temporary file on + * Make a [class@Image] which, when written to, will create a temporary file on * disc. The file will be automatically deleted when the image is destroyed. * @format is something like "%s.v" for a vips file. * @@ -2543,9 +2561,10 @@ vips_get_disc_threshold(void) * will default to /tmp. On Windows, vips uses GetTempPath() to find the * temporary directory. * - * See also: vips_image_new(). + * ::: seealso + * [ctor@Image.new]. * - * Returns: the new #VipsImage, or %NULL on error. + * Returns: the new [class@Image], or %NULL on error. */ VipsImage * vips_image_new_temp_file(const char *format) @@ -2598,10 +2617,11 @@ vips_image_write_gen(VipsRegion *out_region, * @image: image to write * @out: (out): write to this image * - * Write @image to @out. Use vips_image_new() and friends to create the - * #VipsImage you want to write to. + * Write @image to @out. Use [ctor@Image.new] and friends to create the + * [class@Image] you want to write to. * - * See also: vips_image_new(), vips_copy(), vips_image_write_to_file(). + * ::: seealso + * [ctor@Image.new], [method@Image.copy], [method@Image.write_to_file]. * * Returns: 0 on success, or -1 on error. */ @@ -2632,7 +2652,7 @@ vips_image_write(VipsImage *image, VipsImage *out) * * If it's not partial, perhaps a file we write to or a memory image, * we need to break any links between @image and @out created by - * vips_image_pipelinev(). + * [method@Image.pipelinev]. */ if (vips_image_ispartial(out)) { vips_object_local(out, image); @@ -2653,13 +2673,14 @@ vips_image_write(VipsImage *image, VipsImage *out) * @...: %NULL-terminated list of optional named arguments * * Writes @in to @name using the saver recommended by - * vips_foreign_find_save(). + * [func@Foreign.find_save]. * * Save options may be appended to @filename as "[name=value,...]" or given as * a NULL-terminated list of name-value pairs at the end of the arguments. * Options given in the function call override options given in the filename. * - * See also: vips_image_new_from_file(). + * ::: seealso + * [ctor@Image.new_from_file]. * * Returns: 0 on success, or -1 on error. */ @@ -2725,9 +2746,10 @@ vips_image_write_to_file(VipsImage *image, const char *name, ...) * Currently only TIFF, JPEG and PNG formats are supported. * * You can call the various save operations directly if you wish, see - * vips_jpegsave_buffer(), for example. + * [method@Image.jpegsave_buffer], for example. * - * See also: vips_image_write_to_memory(), vips_image_new_from_buffer(). + * ::: seealso + * [method@Image.write_to_memory], [ctor@Image.new_from_buffer]. * * Returns: 0 on success, -1 on error */ @@ -2768,9 +2790,7 @@ vips_image_write_to_buffer(VipsImage *in, g_object_get(target, "blob", &blob, NULL); VIPS_UNREF(target); } - else if ((operation_name = - vips_foreign_find_save_buffer(filename))) { - + else if ((operation_name = vips_foreign_find_save_buffer(filename))) { va_start(ap, size); result = vips_call_split_option_string(operation_name, option_string, ap, in, &blob); @@ -2814,9 +2834,10 @@ vips_image_write_to_buffer(VipsImage *in, * Options given in the function call override options given in the filename. * * You can call the various save operations directly if you wish, see - * vips_jpegsave_target(), for example. + * [method@Image.jpegsave_target], for example. * - * See also: vips_image_write_to_file(). + * ::: seealso + * [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error */ @@ -2854,7 +2875,8 @@ vips_image_write_to_target(VipsImage *in, * * The caller is responsible for freeing this memory with g_free(). * - * See also: vips_image_write_to_buffer(). + * ::: seealso + * [method@Image.write_to_buffer]. * * Returns: (array length=size) (element-type guint8) (transfer full): return buffer start here */ @@ -2896,19 +2918,20 @@ vips_image_write_to_memory(VipsImage *in, size_t *size_out) * @out: (out): write to this image * * A convenience function to unpack to a format that we can compute with. - * @out.coding is always #VIPS_CODING_NONE. + * @out.coding is always [enum@Vips.Coding.NONE]. * - * This unpacks LABQ to plain LAB. Use vips_LabQ2LabS() for a bit more speed - * if you need it. + * This unpacks LABQ to plain LAB. Use [method@Image.LabQ2LabS] for a bit + * more speed if you need it. * - * See also: vips_image_encode(), vips_LabQ2Lab(), vips_rad2float(). + * ::: seealso + * [method@Image.encode], [method@Image.LabQ2Lab], [method@Image.rad2float]. * * Returns: 0 on success, or -1 on error. */ int vips_image_decode(VipsImage *in, VipsImage **out) { - /* Keep in sync with vips__vector_to_ink(). + /* Keep in sync with [func@_vector_to_ink]. */ if (in->Coding == VIPS_CODING_LABQ) { if (vips_LabQ2Lab(in, out, NULL)) @@ -2935,7 +2958,8 @@ vips_image_decode(VipsImage *in, VipsImage **out) * We often need to know what an image will decode to without actually * decoding it, for example, in arg checking. * - * See also: vips_image_decode(). + * ::: seealso + * [method@Image.decode]. */ int vips_image_decode_predict(VipsImage *in, @@ -2972,9 +2996,10 @@ vips_image_decode_predict(VipsImage *in, * @coding: coding to apply * * A convenience function to pack to a coding. The inverse of - * vips_image_decode(). + * [method@Image.decode]. * - * See also: vips_image_decode(). + * ::: seealso + * [method@Image.decode]. * * Returns: 0 on success, or -1 on error. */ @@ -3062,8 +3087,8 @@ vips_image_ispartial(VipsImage *image) * @image: image to check * * Look at an image's interpretation and see if it has extra alpha bands. For - * example, a 4-band #VIPS_INTERPRETATION_sRGB would, but a six-band - * #VIPS_INTERPRETATION_MULTIBAND would not. + * example, a 4-band [enum@Vips.Interpretation.sRGB] would, but a six-band + * [enum@Vips.Interpretation.MULTIBAND] would not. * * Return %TRUE if @image has an alpha channel. */ @@ -3111,8 +3136,8 @@ vips_image_hasalpha(VipsImage *image) * Call this after setting header fields (width, height, and so on) to * allocate resources ready for writing. * - * Normally this function is called for you by vips_image_generate() or - * vips_image_write_line(). You will need to call it yourself if you plan to + * Normally this function is called for you by [method@Image.generate] or + * [method@Image.write_line]. You will need to call it yourself if you plan to * write directly to the ->data member of a memory image. * * Returns: 0 on success, or -1 on error. @@ -3175,10 +3200,11 @@ vips_image_write_prepare(VipsImage *image) * @linebuffer: scanline of pixels * * Write a line of pixels to an image. This function must be called repeatedly - * with @ypos increasing from 0 to #VipsImage::height . + * with @ypos increasing from 0 to [property@Image:height]. * @linebuffer must be VIPS_IMAGE_SIZEOF_LINE() bytes long. * - * See also: vips_image_generate(). + * ::: seealso + * [method@Image.generate]. * * Returns: 0 on success, or -1 on error. */ @@ -3194,7 +3220,7 @@ vips_image_write_line(VipsImage *image, int ypos, VipsPel *linebuffer) return -1; /* Always clear kill before we start looping. See the - * call to vips_image_iskilled() below. + * call to [method@Image.iskilled] below. */ vips_image_set_kill(image, FALSE); vips_image_write_prepare(image); @@ -3314,17 +3340,18 @@ vips_image_rewind_output(VipsImage *image) * Call this before using the draw operations to make sure you have a * memory image that can be modified. * - * vips_copy() adds a null "copy" node to a pipeline. Use that + * [method@Image.copy] adds a null "copy" node to a pipeline. Use that * instead if you want to change metadata and not pixels. * - * This operation is thread-safe, unlike vips_image_wio_input(). + * This operation is thread-safe, unlike [method@Image.wio_input]. * * If you are sure that @image is not shared with another thread (perhaps you - * have made it yourself), use vips_image_wio_input() instead. + * have made it yourself), use [method@Image.wio_input] instead. * - * See also: vips_image_wio_input(). + * ::: seealso + * [method@Image.wio_input]. * - * Returns: (transfer full): the new #VipsImage, or %NULL on error. + * Returns: (transfer full): the new [class@Image], or %NULL on error. */ VipsImage * vips_image_copy_memory(VipsImage *image) @@ -3373,10 +3400,11 @@ vips_image_copy_memory(VipsImage *image) * Since this function modifies @image, it is not thread-safe. Only call it on * images which you are sure have not been shared with another thread. If the * image might have been shared, use the less efficient - * vips_image_copy_memory() instead. + * [method@Image.copy_memory] instead. * - * See also: vips_image_copy_memory(), vips_image_pio_input(), - * vips_image_inplace(), VIPS_IMAGE_ADDR(). + * ::: seealso + * [method@Image.copy_memory], [method@Image.pio_input], + * [method@Image.inplace], VIPS_IMAGE_ADDR(). * * Returns: 0 on success, or -1 on error. */ @@ -3438,7 +3466,7 @@ vips_image_wio_input(VipsImage *image) g_object_unref(t1); /* We need to zap any start/gen/stop callbacks. If we don't, - * calling vips_region_prepare_to() later to read from this + * calling [method@Region.prepare_to] later to read from this * image will fail, since it will think it needs to create the * image, not read from it. */ @@ -3522,7 +3550,7 @@ vips__image_wio_output(VipsImage *image) * * We used to check that ->data was null and warn about * writing twice, but we no longer insist that this is called - * before vips_image_write_prepare(), so we can't do that any + * before [method@Image.write_prepare], so we can't do that any * more. */ break; @@ -3540,9 +3568,9 @@ vips__image_wio_output(VipsImage *image) * vips_image_inplace: * @image: image to make read-write * - * Gets @image ready for an in-place operation, such as vips_draw_circle(). - * After calling this function you can both read and write the image with - * VIPS_IMAGE_ADDR(). + * Gets @image ready for an in-place operation, such as + * [method@Image.draw_circle]. After calling this function you can both read + * and write the image with VIPS_IMAGE_ADDR(). * * This method is called for you by the base class of the draw operations, * there's no need to call it yourself. @@ -3552,14 +3580,15 @@ vips__image_wio_output(VipsImage *image) * All in-place operations are inherently not thread-safe, so you need to take * great care in any case. * - * See also: vips_draw_circle(), vips_image_wio_input(). + * ::: seealso + * [method@Image.draw_circle], [method@Image.wio_input]. * * Returns: 0 on success, or -1 on error. */ int vips_image_inplace(VipsImage *image) { - /* Do an vips_image_wio_input(). This will rewind, generate, etc. + /* Do an [method@Image.wio_input]. This will rewind, generate, etc. */ if (vips_image_wio_input(image)) return -1; @@ -3600,11 +3629,12 @@ vips_image_inplace(VipsImage *image) * vips_image_pio_input: * @image: image to check * - * Check that an image is readable with vips_region_prepare() and friends. - * If it isn't, try to transform the image so that vips_region_prepare() can + * Check that an image is readable with [method@Region.prepare] and friends. + * If it isn't, try to transform the image so that [method@Region.prepare] can * work. * - * See also: vips_image_pio_output(), vips_region_prepare(). + * ::: seealso + * [method@Image.pio_output], [method@Region.prepare]. * * Returns: 0 on success, or -1 on error. */ @@ -3672,10 +3702,11 @@ vips_image_pio_input(VipsImage *image) * vips_image_pio_output: * @image: image to check * - * Check that an image is writeable with vips_image_generate(). If it isn't, - * try to transform the image so that vips_image_generate() can work. + * Check that an image is writeable with [method@Image.generate]. If it isn't, + * try to transform the image so that [method@Image.generate] can work. * - * See also: vips_image_pio_input(). + * ::: seealso + * [method@Image.pio_input]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 5605686eaf..d80cef7689 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -167,11 +167,11 @@ vips_max_coord_get(void) /** * vips_get_argv0: * - * See also: VIPS_INIT(). + * ::: seealso + * [func@INIT]. * * Returns: (transfer none): a pointer to an internal copy of the - * argv0 string passed to - * VIPS_INIT(). Do not free this value + * argv0 string passed to [func@INIT]. Do not free this value */ const char * vips_get_argv0(void) @@ -182,9 +182,10 @@ vips_get_argv0(void) /** * vips_get_prgname: * - * Return the program name. This can be useful for the user tio see,. + * Return the program name. * - * See also: VIPS_INIT(). + * ::: seealso + * [func@INIT]. * * Returns: (transfer none): a pointer to an internal copy of the program * name. Do not free this value @@ -204,9 +205,9 @@ vips_get_prgname(void) * VIPS_INIT: * @ARGV0: name of application * - * VIPS_INIT() starts up the world of VIPS. You should call this on + * [func@INIT] starts up the world of VIPS. You should call this on * program startup before using any other VIPS operations. If you do not call - * VIPS_INIT(), VIPS will call it for you when you use your first VIPS + * [func@INIT], VIPS will call it for you when you use your first VIPS * operation, but it may not be able to get hold of @ARGV0 and VIPS may * therefore be unable to find its data files. It is much better to call * this macro yourself. @@ -215,23 +216,23 @@ vips_get_prgname(void) * relocated. If you don't need a relocatable package, you can just pass `""` * and it'll be fine. * - * Additionally, VIPS_INIT() can be run from any thread, but it must not be + * Additionally, [func@INIT] can be run from any thread, but it must not be * called from more than one thread at the same time. This is much easier to * guarantee if you call it yourself. * - * VIPS_INIT() is a macro, since it tries to check ABI compatibility - * between the caller and the library. You can also call vips_init(), the + * [func@INIT] is a macro, since it tries to check ABI compatibility + * between the caller and the library. You can also call [func@init], the * non-macro version, if macros are not available to you. * - * You may call VIPS_INIT() many times and vips_shutdown() many times, but you - * must not call VIPS_INIT() after vips_shutdown(). In other words, you cannot + * You may call [func@INIT] many times and [func@shutdown] many times, but you + * must not call [func@INIT] after [func@shutdown]. In other words, you cannot * stop and restart vips. * * Use the environment variable `VIPS_MIN_STACK_SIZE` to set the minimum stack * size. For example, `2m` for a minimum of two megabytes of stack. This can * be important for systems like musl where the default stack is very small. * - * VIPS_INIT() does approximately the following: + * [func@INIT] does approximately the following: * * + checks that the libvips your program is expecting is * binary-compatible with the vips library you're running against @@ -242,16 +243,16 @@ vips_get_prgname(void) * and the threading system, if necessary * * + guesses where the VIPS data files are and sets up - * internationalisation --- see vips_guess_prefix() + * internationalisation --- see [func@guess_prefix] * - * + creates the main vips types, including #VipsImage and friends + * + creates the main vips types, including [class@Image] and friends * * + loads any plugins from $libdir/vips-x.y/, where x and y are the * major and minor version numbers for this VIPS. * * Example: * - * |[ + * ```c * int main(int argc, char **argv) * { * if (VIPS_INIT(argv[0])) @@ -261,10 +262,11 @@ vips_get_prgname(void) * * return 0; * } - * ]| + * ``` * - * See also: vips_shutdown(), vips_add_option_entries(), vips_version(), - * vips_guess_prefix(), vips_guess_libdir(). + * ::: seealso + * [func@shutdown], [func@add_option_entries], [func@version], + * [func@guess_prefix], [func@guess_libdir]. * * Returns: 0 on success, -1 otherwise */ @@ -404,8 +406,7 @@ vips_leak(void) vips_buf_appends(&buf, "\n"); if (strlen(vips_error_buffer()) > 0) { - vips_buf_appendf(&buf, "error buffer: %s", - vips_error_buffer()); + vips_buf_appendf(&buf, "error buffer: %s", vips_error_buffer()); n_leaks += strlen(vips_error_buffer()); } @@ -424,12 +425,13 @@ vips_leak(void) * vips_init: * @argv0: name of application * - * This function starts up libvips, see VIPS_INIT(). + * This function starts up libvips, see [func@INIT]. * * This function is for bindings which need to start up vips. C programs - * should use the VIPS_INIT() macro, which does some extra checks. + * should use the [func@INIT] macro, which does some extra checks. * - * See also: VIPS_INIT(). + * ::: seealso + * [func@INIT]. * * Returns: 0 on success, -1 otherwise */ @@ -577,7 +579,7 @@ vips_init(const char *argv0) /* Start up packages. */ - (void) vips_system_get_type(); + vips_system_get_type(); vips_arithmetic_operation_init(); vips_conversion_operation_init(); vips_create_operation_init(); @@ -639,7 +641,7 @@ vips_init(const char *argv0) /* If VIPS_WARNING is defined, suppress all warning messages from vips. * - * Libraries should not call g_log_set_handler(), it is + * Libraries should not call [func@GLib.log_set_handler], it is * supposed to be for the application layer, but this can be awkward to * set up if you are using libvips from something like Ruby. Allow this * env var hack as a workaround. @@ -670,7 +672,7 @@ void vips_check_init(void) { /* Pass in a nonsense name for argv0 ... this init path is only here - * for old programs which are missing an vips_init() call. We need + * for old programs which are missing an [func@init] call. We need * i18n set up before we can translate. */ if (vips_init("vips")) @@ -683,8 +685,8 @@ vips_check_init(void) * Free any thread-private data and flush any profiling information. * * This function needs to be called when a thread that has been using vips - * exits. It is called for you by vips_shutdown() and for any threads created - * within the #VipsThreadPool. + * exits. It is called for you by [func@shutdown] and for any threads created + * within the thread pool. * * You will need to call it from threads created in * other ways or there will be memory leaks. If you do not call it, vips @@ -706,15 +708,16 @@ vips_thread_shutdown(void) * Call this to drop caches, close plugins, terminate background threads, and * finalize any internal library testing. * - * vips_shutdown() is optional. If you don't call it, your platform will + * [func@shutdown] is optional. If you don't call it, your platform will * clean up for you. The only negative consequences are that the leak checker * and the profiler will not work. * - * You may call VIPS_INIT() many times and vips_shutdown() many times, but you - * must not call VIPS_INIT() after vips_shutdown(). In other words, you cannot + * You may call [func@INIT] many times and [func@shutdown] many times, but you + * must not call [func@INIT] after [func@shutdown]. In other words, you cannot * stop and restart libvips. * - * See also: vips_profile_set(), vips_leak_set(). + * ::: seealso + * [func@profile_set], [func@leak_set]. */ void vips_shutdown(void) @@ -916,9 +919,11 @@ static GOptionEntry option_entries[] = { * vips_add_option_entries: * @option_group: group to add to * - * Add the standard vips %GOptionEntry to a %GOptionGroup. + * Add the standard vips [struct@GLib.OptionEntry] to a + * [struct@GLib.OptionGroup]. * - * See also: g_option_group_new(). + * ::: seealso + * [ctor@GLib.OptionGroup.new]. */ void vips_add_option_entries(GOptionGroup *option_group) @@ -1127,17 +1132,18 @@ guess_prefix(const char *argv0, const char *name) * @argv0: program name (typically argv[0]) * @env_name: save prefix in this environment variable * - * vips_guess_prefix() tries to guess the install directory. You should pass + * [func@guess_prefix] tries to guess the install directory. You should pass * in the value of argv[0] (the name your program was run as) as a clue to * help it out, plus the name of the environment variable you let the user * override your package install area with (eg. "VIPSHOME"). * - * On success, vips_guess_prefix() returns the prefix it discovered, and as a + * On success, [func@guess_prefix] returns the prefix it discovered, and as a * side effect, sets the environment variable (if it's not set). * * Don't free the return string! * - * See also: vips_guess_libdir(). + * ::: seealso + * [func@guess_libdir]. * * Returns: (transfer none): the install prefix as a static string, do not free. */ @@ -1173,18 +1179,19 @@ vips_guess_prefix(const char *argv0, const char *env_name) * @argv0: program name (typically argv[0]) * @env_name: save prefix in this environment variable * - * vips_guess_libdir() tries to guess the install directory (usually the + * [func@guess_libdir] tries to guess the install directory (usually the * configure libdir, or $prefix/lib). You should pass * in the value of argv[0] (the name your program was run as) as a clue to * help it out, plus the name of the environment variable you let the user * override your package install area with (eg. "VIPSHOME"). * - * On success, vips_guess_libdir() returns the libdir it discovered, and as a + * On success, [func@guess_libdir] returns the libdir it discovered, and as a * side effect, sets the prefix environment variable (if it's not set). * * Don't free the return string! * - * See also: vips_guess_prefix(). + * ::: seealso + * [func@guess_prefix]. * * Returns: (transfer none): the libdir as a static string, do not free. */ @@ -1275,8 +1282,8 @@ vips_version(int flag) * vips_leak_set: * @leak: turn leak checking on or off * - * Turn on or off vips leak checking. See also --vips-leak, - * vips_add_option_entries() and the `VIPS_LEAK` environment variable. + * Turn on or off vips leak checking. See also `--vips-leak`, + * [func@add_option_entries] and the `VIPS_LEAK` environment variable. * * You should call this very early in your program. */ @@ -1304,9 +1311,9 @@ vips_block_untrusted_set_operation(VipsOperationClass *class, gboolean *state) * * Set the block state on all untrusted operations. * - * |[ + * ```c * vips_block_untrusted_set(TRUE); - * ]| + * ``` * * Will block all untrusted operations from running. * @@ -1314,7 +1321,7 @@ vips_block_untrusted_set_operation(VipsOperationClass *class, gboolean *state) * operations are marked as untrusted. * * Set the environment variable `VIPS_BLOCK_UNTRUSTED` to block all untrusted - * operations on vips_init(). + * operations on [func@init]. */ void vips_block_untrusted_set(gboolean state) diff --git a/libvips/iofuncs/memory.c b/libvips/iofuncs/memory.c index 9e7e2b5f50..9c3862f8ce 100644 --- a/libvips/iofuncs/memory.c +++ b/libvips/iofuncs/memory.c @@ -16,7 +16,7 @@ * 20/10/09 * - gtkdoc comment * 6/11/09 - * - im_malloc()/im_free() now call g_try_malloc()/g_free() ... removes + * - im_malloc()/im_free() now call g_try_malloc/g_free() ... removes * confusion over whether to use im_free() or g_free() for things like * im_header_string() * 21/9/11 @@ -84,12 +84,12 @@ * These functions cover two main areas. * * First, some simple utility functions over the underlying - * g_malloc()/g_free() functions. Memory allocated and freeded using these + * [func@GLib.malloc]/[func@GLib.free] functions. Memory allocated and freeded using these * functions is interchangeable with any other glib library. * - * Second, a pair of functions, vips_tracked_malloc() and vips_tracked_free(), - * which are NOT compatible. If you g_free() memory that has been allocated - * with vips_tracked_malloc() you will see crashes. + * Second, a pair of functions, [func@tracked_malloc] and [func@tracked_free], + * which are NOT compatible. If you [func@GLib.free] memory that has been allocated + * with [func@tracked_malloc] you will see crashes. * * The tracked functions are * only suitable for large allocations internal to the library, for example @@ -124,10 +124,11 @@ static GMutex vips_tracked_mutex; * Allocate memory for a thing of type @T. The memory is not * cleared. * - * This macro cannot fail. See vips_tracked_malloc() if you are + * This macro cannot fail. See [func@tracked_malloc] if you are * allocating large amounts of memory. * - * See also: vips_malloc(). + * ::: seealso + * [func@malloc]. * * Returns: A pointer of type @T *. */ @@ -141,10 +142,11 @@ static GMutex vips_tracked_mutex; * Allocate memory for an array of objects of type @T. The memory is not * cleared. * - * This macro cannot fail. See vips_tracked_malloc() if you are + * This macro cannot fail. See [func@tracked_malloc] if you are * allocating large amounts of memory. * - * See also: vips_malloc(). + * ::: seealso + * [func@malloc]. * * Returns: A pointer of type @T *. */ @@ -157,17 +159,18 @@ vips_malloc_cb(VipsObject *object, char *buf) /** * vips_malloc: - * @object: (nullable): allocate memory local to this #VipsObject, or %NULL + * @object: (nullable): allocate memory local to this [class@Object], or %NULL * @size: number of bytes to allocate * - * g_malloc() local to @object, that is, the memory will be automatically + * [func@GLib.malloc] local to @object, that is, the memory will be automatically * freed for you when the object is closed. If @object is %NULL, you need to - * free the memory explicitly with g_free(). + * free the memory explicitly with [func@GLib.free]. * - * This function cannot fail. See vips_tracked_malloc() if you are + * This function cannot fail. See [func@tracked_malloc] if you are * allocating large amounts of memory. * - * See also: vips_tracked_malloc(). + * ::: seealso + * [func@tracked_malloc]. * * Returns: (transfer full): a pointer to the allocated memory. */ @@ -189,16 +192,17 @@ vips_malloc(VipsObject *object, size_t size) /** * vips_strdup: - * @object: (nullable): allocate memory local to this #VipsObject, or %NULL + * @object: (nullable): allocate memory local to this [class@Object], or %NULL * @str: string to copy * - * g_strdup() a string. When @object is freed, the string will be freed for + * [func@GLib.strdup] a string. When @object is freed, the string will be freed for * you. If @object is %NULL, you need to - * free the memory yourself with g_free(). + * free the memory yourself with [func@GLib.free]. * * This function cannot fail. * - * See also: vips_malloc(). + * ::: seealso + * [func@malloc]. * * Returns: (transfer full): a pointer to the allocated memory */ @@ -223,10 +227,11 @@ vips_strdup(VipsObject *object, const char *str) * @s: (transfer full): memory to free * * Only use it to free memory that was - * previously allocated with vips_tracked_malloc() + * previously allocated with [func@tracked_malloc] * with a %NULL first argument. * - * See also: vips_tracked_malloc(). + * ::: seealso + * [func@tracked_malloc]. */ void vips_tracked_free(void *s) @@ -263,10 +268,11 @@ vips_tracked_free(void *s) * @s: (transfer full): memory to free * * Only use it to free memory that was - * previously allocated with vips_tracked_aligned_alloc() + * previously allocated with [func@tracked_aligned_alloc] * with a %NULL first argument. * - * See also: vips_tracked_aligned_alloc(). + * ::: seealso + * [func@tracked_aligned_alloc]. */ void vips_tracked_aligned_free(void *s) @@ -303,15 +309,16 @@ vips_tracked_aligned_free(void *s) * vips_tracked_malloc: * @size: number of bytes to allocate * - * Allocate an area of memory that will be tracked by vips_tracked_get_mem() + * Allocate an area of memory that will be tracked by [func@tracked_get_mem] * and friends. * - * If allocation fails, vips_tracked_malloc() returns %NULL and + * If allocation fails, [func@tracked_malloc] returns %NULL and * sets an error message. * - * You must only free the memory returned with vips_tracked_free(). + * You must only free the memory returned with [func@tracked_free]. * - * See also: vips_tracked_free(), vips_malloc(). + * ::: seealso + * [func@tracked_free], [func@malloc]. * * Returns: (transfer full): a pointer to the allocated memory, or %NULL on error. */ @@ -367,15 +374,16 @@ vips_tracked_malloc(size_t size) * @align: specifies the alignment * * Allocate an area of memory aligned on a boundary specified - * by @align that will be tracked by vips_tracked_get_mem() + * by @align that will be tracked by [func@tracked_get_mem] * and friends. * - * If allocation fails, vips_tracked_aligned_alloc() returns %NULL + * If allocation fails, [func@tracked_aligned_alloc] returns %NULL * and sets an error message. * - * You must only free the memory returned with vips_tracked_aligned_free(). + * You must only free the memory returned with [func@tracked_aligned_free]. * - * See also: vips_tracked_malloc(), vips_tracked_aligned_free(), vips_malloc(). + * ::: seealso + * [func@tracked_malloc], [func@tracked_aligned_free], [func@malloc]. * * Returns: (transfer full): a pointer to the allocated memory, or %NULL on error. */ @@ -442,15 +450,16 @@ vips_tracked_aligned_alloc(size_t size, size_t align) * @mode: open mode * * Exactly as open(2), but the number of files currently open via - * vips_tracked_open() is available via vips_tracked_get_files(). This is used + * [func@tracked_open] is available via [func@tracked_get_files]. This is used * by the vips operation cache to drop cache when the number of files * available is low. * - * You must only close the file descriptor with vips_tracked_close(). + * You must only close the file descriptor with [func@tracked_close]. * * @pathname should be utf8. * - * See also: vips_tracked_close(), vips_tracked_get_files(). + * ::: seealso + * [func@tracked_close], [func@tracked_get_files]. * * Returns: a file descriptor, or -1 on error. */ @@ -480,13 +489,14 @@ vips_tracked_open(const char *pathname, int flags, int mode) * @fd: file to close() * * Exactly as close(2), but update the number of files currently open via - * vips_tracked_get_files(). This is used + * [func@tracked_get_files]. This is used * by the vips operation cache to drop cache when the number of files * available is low. * - * You must only close file descriptors opened with vips_tracked_open(). + * You must only close file descriptors opened with [func@tracked_open]. * - * See also: vips_tracked_open(), vips_tracked_get_files(). + * ::: seealso + * [func@tracked_open], [func@tracked_get_files]. * * Returns: a file descriptor, or -1 on error. */ @@ -518,9 +528,9 @@ vips_tracked_close(int fd) /** * vips_tracked_get_mem: * - * Returns the number of bytes currently allocated via vips_malloc() and + * Returns the number of bytes currently allocated via [func@malloc] and * friends. vips uses this figure to decide when to start dropping cache, see - * #VipsOperation. + * [class@Operation]. * * Returns: the number of currently allocated bytes */ @@ -542,7 +552,7 @@ vips_tracked_get_mem(void) * vips_tracked_get_mem_highwater: * * Returns the largest number of bytes simultaneously allocated via - * vips_tracked_malloc(). Handy for estimating max memory requirements for a + * [func@tracked_malloc]. Handy for estimating max memory requirements for a * program. * * Returns: the largest number of currently allocated bytes diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index fd16886f37..a194c7cd74 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -227,7 +227,8 @@ G_DEFINE_ABSTRACT_TYPE(VipsObject, vips_object, G_TYPE_OBJECT); /** * vips_argument_get_id: (skip) * - * Allocate a new property id. See g_object_class_install_property(). + * Allocate a new property id. See + * [method@GObject.ObjectClass.install_property]. * * Returns: a new property id > 0 */ @@ -575,9 +576,9 @@ vips_argument_table_destroy(VipsArgumentTable *table) } /** - * vips_argument_map: (skip) + * vips_argument_map: * @object: object whose args should be enumerated - * @fn: call this function for every argument + * @fn: (scope call) (closure a): call this function for every argument * @a: client data * @b: client data * @@ -824,7 +825,7 @@ vips_object_argument_isset(VipsObject *object, const char *name) * * Convenience: get the flags for an argument. Useful for bindings. * - * Returns: The #VipsArgumentFlags for this argument. + * Returns: The [flags@ArgumentFlags] for this argument. */ VipsArgumentFlags vips_object_get_argument_flags(VipsObject *object, const char *name) @@ -932,7 +933,7 @@ vips_object_dispose_argument(VipsObject *object, GParamSpec *pspec, /* Free all args on this object which may be holding resources. * - * Note that this is not the same as vips_object_unref_outputs(). That + * Note that this is not the same as [method@Object.unref_outputs]. That * looks for output objects which may have been created during _build() which * hold refs to this object and unrefs them. * @@ -1402,7 +1403,7 @@ vips_object_get_property(GObject *gobject, argument_class->offset); /* Copy the boxed into our pointer (will use eg. - * vips__object_vector_dup ()). + * vips__object_vector_dup()). */ g_value_set_boxed(value, *member); } @@ -2301,13 +2302,13 @@ vips_object_find_args(VipsObject *object, * vips_object_get_args: (skip) * @object: object whose args should be retrieved * @names: (transfer none) (array length=n_args) (allow-none): output array of %GParamSpec names - * @flags: (transfer none) (array length=n_args) (allow-none): output array of #VipsArgumentFlags + * @flags: (transfer none) (array length=n_args) (allow-none): output array of [flags@ArgumentFlags] * @n_args: (allow-none): length of output arrays * - * Get all %GParamSpec names and #VipsArgumentFlags for an object. + * Get all %GParamSpec names and [flags@ArgumentFlags] for an object. * * This is handy for language bindings. From C, it's usually more convenient to - * use vips_argument_map(). + * use [func@Argument.map]. * * Returns: 0 on success, -1 on error */ @@ -2348,8 +2349,8 @@ vips_object_get_args(VipsObject *object, * @a: client data * @b: client data * - * g_object_new() the object, set any arguments with @set, call - * vips_object_build() and return the complete object. + * [ctor@GObject.Object.new] the object, set any arguments with @set, call + * [method@Object.build] and return the complete object. * * Returns: the new object */ @@ -2380,7 +2381,7 @@ vips_object_new(GType type, VipsObjectSetArguments set, void *a, void *b) * @object: object to set arguments on * @ap: %NULL-terminated list of argument/value pairs * - * See vips_object_set(). + * See [method@Object.set]. * * Returns: 0 on success, -1 on error */ @@ -2421,17 +2422,18 @@ vips_object_set_valist(VipsObject *object, va_list ap) * * Set a list of vips object arguments. For example: * - * |[ + * ```c * vips_object_set(operation, * "input", in, * "output", &out, * NULL); - * ]| + * ``` * * Input arguments are given in-line, output arguments are given as pointers * to where the output value should be written. * - * See also: vips_object_set_valist(), vips_object_set_from_string(). + * ::: seealso + * [method@Object.set_valist], [method@Object.set_from_string]. * * Returns: 0 on success, -1 on error */ @@ -2556,8 +2558,9 @@ vips_object_set_args(VipsObject *object, const char *p) * * You'd typically use this between creating the object and building it. * - * See also: vips_object_set(), vips_object_build(), - * vips_cache_operation_buildp(). + * ::: seealso + * [method@Object.set], [method@Object.build], + * [func@cache_operation_buildp]. * * Returns: 0 on success, -1 on error */ @@ -2672,8 +2675,8 @@ vips_object_to_string_optional(VipsObject *object, * @object: object to stringify * @buf: write string here * - * The inverse of vips_object_new_from_string(): turn @object into eg. - * "VipsInterpolateSnohalo1(blur=.333333)". + * The inverse of [ctor@Object.new_from_string]: turn @object into eg. + * `"VipsInterpolateSnohalo1(blur=.333333)"`. */ void vips_object_to_string(VipsObject *object, VipsBuf *buf) @@ -2874,7 +2877,8 @@ test_name(VipsObjectClass *class, const char *nickname) * Search below @basename, return the first class whose name or @nickname * matches. * - * See also: vips_type_find() + * ::: seealso + * [func@type_find] * * Returns: (transfer none): the found class. */ @@ -2952,11 +2956,12 @@ vips_class_build_hash_cb(void *dummy) * * Search below @basename, return the %GType of the class whose name or * @nickname matches, or 0 for not found. - * If @basename is NULL, the whole of #VipsObject is searched. + * If @basename is NULL, the whole of [class@Object] is searched. * * This function uses a cache, so it should be quick. * - * See also: vips_class_find() + * ::: seealso + * [func@class_find] * * Returns: the %GType of the class, or 0 if the class is not found. */ @@ -3020,7 +3025,7 @@ vips_nickname_find(GType type) return NULL; } -/* The vips_object_local() macro uses this as its callback. +/* The vips_object_local_array() macro uses this as its callback. */ void vips_object_local_cb(VipsObject *vobject, GObject *gobject) @@ -3059,7 +3064,7 @@ vips_object_local_array_cb(VipsObject *parent, VipsObjectLocal *local) * * Example: * - * |[ + * ```c * VipsObject **t; * * t = vips_object_local_array(parent, 5); @@ -3068,9 +3073,7 @@ vips_object_local_array_cb(VipsObject *parent, VipsObjectLocal *local) * vips_add(t[1], t[0], &t[2], NULL) || * vips_costra(t[2], out, NULL)) * return -1; - * ]| - * - * See also: vips_object_local(). + * ``` * * Returns: an array of NULL pointers of length @n */ @@ -3223,7 +3226,8 @@ vips_object_unref_outputs_sub(VipsObject *object, * been made so far. This function can also be useful for callers when * they've finished processing outputs themselves. * - * See also: vips_cache_operation_build(). + * ::: seealso + * [func@cache_operation_build]. */ void vips_object_unref_outputs(VipsObject *object) diff --git a/libvips/iofuncs/operation.c b/libvips/iofuncs/operation.c index ad7260db04..286b5c1fa5 100644 --- a/libvips/iofuncs/operation.c +++ b/libvips/iofuncs/operation.c @@ -102,9 +102,9 @@ * ``` * * This will invert `im` and return a new [class@Image], `t1`. As the caller - * of [method@Image.invert], you are responsible for `t1` and must unref it when - * you no longer need it. If [method@Image.invert] fails, no `t1` is returned and - * you don't need to do anything. + * of [method@Image.invert], you are responsible for `t1` and must unref it + * when you no longer need it. If [method@Image.invert] fails, no `t1` is + * returned and you don't need to do anything. * * If you don't need to use `im` for another operation, you can unref `im` * immediately after the call. If `im` is needed to calculate `t1`, @@ -172,9 +172,9 @@ * * Flags we associate with an operation. * - * @VIPS_OPERATION_SEQUENTIAL means that the operation works like vips_conv(): - * it can process images top-to-bottom with only small non-local - * references. + * @VIPS_OPERATION_SEQUENTIAL means that the operation works like + * [method@Image.conv]: it can process images top-to-bottom with only small + * non-local references. * * Every scan-line must be requested, you are not allowed to skip * ahead, but as a special case, the very first request can be for a region @@ -194,11 +194,11 @@ * * @VIPS_OPERATION_UNTRUSTED means the operation depends on external libraries * which have not been hardened against attack. It should probably not be used - * on untrusted input. Use vips_block_untrusted_set() to block all + * on untrusted input. Use [func@block_untrusted_set] to block all * untrusted operations. * * @VIPS_OPERATION_BLOCKED means the operation is prevented from executing. Use - * vips_operation_block_set() to enable and disable groups of operations. + * [func@Operation.block_set] to enable and disable groups of operations. * * @VIPS_OPERATION_REVALIDATE force the operation to run, updating the cache * with the new value. This is used by eg. VipsForeignLoad to implement the @@ -722,11 +722,11 @@ vips_operation_invalidate(VipsOperation *operation) * vips_operation_new: (constructor) * @name: nickname of operation to create * - * Return a new #VipsOperation with the specified nickname. Useful for + * Return a new [class@Operation] with the specified nickname. Useful for * language bindings. * * You'll need to set any arguments and build the operation before you can use - * it. See vips_call() for a higher-level way to make new operations. + * it. See [func@call] for a higher-level way to make new operations. * * Returns: (transfer full): the new operation. */ @@ -1033,15 +1033,15 @@ vips_call_by_name(const char *operation_name, * @operation_name: name of operation to call * @...: required args, then a %NULL-terminated list of argument/value pairs * - * vips_call() calls the named operation, passing in required arguments and + * [func@call] calls the named operation, passing in required arguments and * then setting any optional ones from the remainder of the arguments as a set * of name/value pairs. * - * For example, vips_embed() takes six required arguments, @in, @out, @x, @y, - * @width, @height, and has two optional arguments, @extend and @background. - * You can run it with vips_call() like this: + * For example, [method@Image.embed] takes six required arguments, @in, @out, + * @x, @y, @width, @height, and has two optional arguments, @extend and + * @background. You can run it with [func@call] like this: * - * |[ + * ```c * VipsImage *in = ... * VipsImage *out; * @@ -1049,12 +1049,13 @@ vips_call_by_name(const char *operation_name, * "extend", VIPS_EXTEND_COPY, * NULL)) * ... error - * ]| + * ``` * - * Normally of course you'd just use the vips_embed() wrapper function and get + * Normally of course you'd just use the [method@Image.embed] wrapper function and get * type-safety for the required arguments. * - * See also: vips_call_split(), vips_call_options(). + * ::: seealso + * [func@call_split], [func@call_options]. * * Returns: 0 on success, -1 on error */ @@ -1424,7 +1425,7 @@ vips_call_argv_output(VipsObject *object, * the GOption parser already, see above. * * We don't create the operation, so we must not unref it. The caller must - * unref on error too. The caller must also call vips_object_unref_outputs() on + * unref on error too. The caller must also call [method@Object.unref_outputs] on * all code paths. */ int @@ -1516,10 +1517,10 @@ vips_operation_block_set_operation(VipsOperationClass *class, gboolean *state) * * For example: * - * |[ + * ```c * vips_operation_block_set("VipsForeignLoad", TRUE); * vips_operation_block_set("VipsForeignLoadJpeg", FALSE); - * ]| + * ``` * * Will block all load operations, except JPEG. * @@ -1527,7 +1528,8 @@ vips_operation_block_set_operation(VipsOperationClass *class, gboolean *state) * * This call does nothing if the named operation is not found. * - * See also: vips_block_untrusted_set(). + * ::: seealso + * [func@block_untrusted_set]. */ void vips_operation_block_set(const char *name, gboolean state) diff --git a/libvips/iofuncs/rect.c b/libvips/iofuncs/rect.c index 6e13c991e8..ac83389c4c 100644 --- a/libvips/iofuncs/rect.c +++ b/libvips/iofuncs/rect.c @@ -217,7 +217,7 @@ vips_rect_unionrect(const VipsRect *r1, const VipsRect *r2, VipsRect *out) * vips_rect_dup: (skip) * @r: rectangle to duplicate * - * Duplicate a rect to the heap. You need to free the result with g_free(). + * Duplicate a rect to the heap. You need to free the result with [func@GLib.free]. * * Returns: (transfer full): a pointer to copy of @r allocated on the heap. */ diff --git a/libvips/iofuncs/region.c b/libvips/iofuncs/region.c index 199786fb2b..15bdcba096 100644 --- a/libvips/iofuncs/region.c +++ b/libvips/iofuncs/region.c @@ -126,49 +126,51 @@ /** * VIPS_REGION_LSKIP: - * @R: a #VipsRegion + * @R: a [class@Region] * * Returns: The number of bytes to add to move down a scanline. */ /** * VIPS_REGION_N_ELEMENTS: - * @R: a #VipsRegion + * @R: a [class@Region] * * Returns: The number of band elements across a region. */ /** * VIPS_REGION_SIZEOF_LINE: - * @R: a #VipsRegion + * @R: a [class@Region] * * Returns: The number of bytes across a region. */ /** * VIPS_REGION_ADDR: - * @R: a #VipsRegion + * @R: a [class@Region] * @X: x coordinate * @Y: y coordinate * * This macro returns a pointer to a pixel in a region. The (@X, @Y) - * coordinates need to be within the #VipsRect (@R->valid). + * coordinates need to be within the [struct@Rect] (@R->valid). * * If DEBUG is defined, you get a version that checks bounds for you. * - * See also: vips_region_prepare(). + * ::: seealso + * [method@Region.prepare]. * * Returns: The address of pixel (@X,@Y) in @R. */ /** * VIPS_REGION_ADDR_TOPLEFT: - * @R: a #VipsRegion + * @R: a [class@Region] * - * This macro returns a pointer to the top-left pixel in the #VipsRegion, that + * This macro returns a pointer to the top-left pixel in the [class@Region], that * is, the pixel at (@R->valid.left, @R->valid.top). * - * See also: vips_region_prepare(). + * ::: seealso + * [method@Region.prepare]. * * Returns: The address of the top-left pixel in the region. */ @@ -354,14 +356,14 @@ vips_region_summary(VipsObject *object, VipsBuf *buf) /* If a region is being created in one thread (eg. the main thread) and then * used in another (eg. a worker thread), the new thread needs to tell VIPS - * to stop sanity g_assert() fails. The previous owner needs to - * vips__region_no_ownership() before we can call this. + * to stop sanity [func@GLib.assert] fails. The previous owner needs to + * [func@_region_no_ownership] before we can call this. */ void vips__region_take_ownership(VipsRegion *region) { /* Lock so that there's a memory barrier with the thread doing the - * vips__region_no_ownership() before us. + * [func@_region_no_ownership] before us. */ VIPS_GATE_START("vips__region_take_ownership: wait"); @@ -478,10 +480,11 @@ vips_region_init(VipsRegion *region) * vips_region_new: (constructor) * @image: image to create this region on * - * Create a region. #VipsRegion s start out empty, you need to call - * vips_region_prepare() to fill them with pixels. + * Create a region. [class@Region] start out empty, you need to call + * [method@Region.prepare] to fill them with pixels. * - * See also: vips_region_prepare(). + * ::: seealso + * [method@Region.prepare]. */ VipsRegion * vips_region_new(VipsImage *image) @@ -516,7 +519,7 @@ vips_region_new(VipsImage *image) /** * vips_region_buffer: * @reg: region to operate upon - * @r: #VipsRect of pixels you need to be able to address + * @r: [struct@Rect] of pixels you need to be able to address * * The region is transformed so that at least @r pixels are available as a * memory buffer that can be written to. @@ -585,7 +588,7 @@ vips_region_buffer(VipsRegion *reg, const VipsRect *r) /** * vips_region_image: * @reg: region to operate upon - * @r: #VipsRect of pixels you need to be able to address + * @r: [struct@Rect] of pixels you need to be able to address * * The region is transformed so that at least @r pixels are available to be * read from the image. The image needs to be a memory buffer or represent a @@ -666,11 +669,11 @@ vips_region_image(VipsRegion *reg, const VipsRect *r) * vips_region_region: * @reg: region to operate upon * @dest: region to connect to - * @r: #VipsRect of pixels you need to be able to address + * @r: [struct@Rect] of pixels you need to be able to address * @x: position of @r in @dest * @y: position of @r in @dest * - * Make VIPS_REGION_ADDR() on @reg go to @dest instead. + * Make [func@REGION_ADDR] on @reg go to @dest instead. * * @r is the part of @reg which you want to be able to address (this * effectively becomes the valid field), (@x, @y) is the top LH corner of the @@ -781,11 +784,11 @@ vips_region_region(VipsRegion *reg, * * Do two regions point to the same piece of image? ie. * - * |[ + * ```c * VIPS_REGION_ADDR(reg1, x, y) == VIPS_REGION_ADDR(reg2, x, y) && * *VIPS_REGION_ADDR(reg1, x, y) == * *VIPS_REGION_ADDR(reg2, x, y) for all x, y, reg1, reg2. - * ]| + * ``` * * Returns: non-zero on equality. */ @@ -899,7 +902,8 @@ vips_region_fill(VipsRegion *reg, * @r is clipped against * @reg->valid. * - * See also: vips_region_black(). + * ::: seealso + * [method@Region.black]. */ void vips_region_paint(VipsRegion *reg, const VipsRect *r, int value) @@ -963,7 +967,8 @@ vips_region_paint(VipsRegion *reg, const VipsRect *r, int value) * @ink should be a byte array of the same size as an image pixel containing * the binary value to write into the pixels. * - * See also: vips_region_paint(). + * ::: seealso + * [method@Region.paint]. */ void vips_region_paint_pel(VipsRegion *reg, const VipsRect *r, const VipsPel *ink) @@ -1008,7 +1013,8 @@ vips_region_paint_pel(VipsRegion *reg, const VipsRect *r, const VipsPel *ink) * * Paints 0 into the valid part of @reg. * - * See also: vips_region_paint(). + * ::: seealso + * [method@Region.paint]. */ void vips_region_black(VipsRegion *reg) @@ -1020,7 +1026,7 @@ vips_region_black(VipsRegion *reg) * vips_region_copy: * @reg: source region * @dest: (inout): destination region - * @r: #VipsRect of pixels you need to copy + * @r: [struct@Rect] of pixels you need to copy * @x: position of @r in @dest * @y: position of @r in @dest * @@ -1028,7 +1034,8 @@ vips_region_black(VipsRegion *reg) * positioning the area of pixels at @x, @y. The two regions must have pixels * which are the same size. * - * See also: vips_region_paint(). + * ::: seealso + * [method@Region.paint]. */ void vips_region_copy(VipsRegion *reg, @@ -1530,16 +1537,18 @@ vips_region_shrink_alpha(VipsRegion *from, * vips_region_shrink_method: * @from: source region * @to: (inout): destination region - * @target: #VipsRect of pixels you need to copy + * @target: [struct@Rect] of pixels you need to copy * @method: method to use when generating target pixels * * Write the pixels @target in @to from the x2 larger area in @from. * Non-complex uncoded images and LABQ only. Images with alpha (see - * vips_image_hasalpha()) shrink with pixels scaled by alpha to avoid fringing. + * [method@Image.hasalpha]) shrink with pixels scaled by alpha to avoid + * fringing. * * @method selects the method used to do the 2x2 shrink. * - * See also: vips_region_copy(). + * ::: seealso + * [method@Region.copy]. */ int vips_region_shrink_method(VipsRegion *from, VipsRegion *to, @@ -1551,8 +1560,7 @@ vips_region_shrink_method(VipsRegion *from, VipsRegion *to, return -1; if (from->im->Coding == VIPS_CODING_NONE) { - if (vips_check_noncomplex("vips_region_shrink_method", - image)) + if (vips_check_noncomplex("vips_region_shrink_method", image)) return -1; if (vips_image_hasalpha(image)) @@ -1570,15 +1578,16 @@ vips_region_shrink_method(VipsRegion *from, VipsRegion *to, * vips_region_shrink: (skip) * @from: source region * @to: (inout): destination region - * @target: #VipsRect of pixels you need to copy + * @target: [struct@Rect] of pixels you need to copy * * Write the pixels @target in @to from the x2 larger area in @from. * Non-complex uncoded images and LABQ only. Images with alpha (see - * vips_image_hasalpha()) shrink with pixels scaled by alpha to avoid fringing. + * [method@Image.hasalpha]) shrink with pixels scaled by alpha to avoid fringing. * - * This is a compatibility stub that just calls vips_region_shrink_method(). + * This is a compatibility stub that just calls [method@Region.shrink_method]. * - * See also: vips_region_shrink_method(). + * ::: seealso + * [method@Region.shrink_method]. */ int vips_region_shrink(VipsRegion *from, VipsRegion *to, const VipsRect *target) @@ -1607,8 +1616,7 @@ vips_region_generate(VipsRegion *reg, void *a) if (im->generate_fn(reg, reg->seq, im->client1, im->client2, &stop)) return -1; if (stop) { - vips_error("vips_region_generate", - "%s", _("stop requested")); + vips_error("vips_region_generate", "%s", _("stop requested")); return -1; } @@ -1618,20 +1626,21 @@ vips_region_generate(VipsRegion *reg, void *a) /** * vips_region_prepare: * @reg: region to prepare - * @r: #VipsRect of pixels you need to be able to address + * @r: [struct@Rect] of pixels you need to be able to address * - * vips_region_prepare() fills @reg with pixels. After calling, - * you can address at least the area @r with VIPS_REGION_ADDR() and get + * [method@Region.prepare] fills @reg with pixels. After calling, + * you can address at least the area @r with [func@REGION_ADDR] and get * valid pixels. * - * vips_region_prepare() runs in-line, that is, computation is done by + * [method@Region.prepare] runs in-line, that is, computation is done by * the calling thread, no new threads are involved, and computation * blocks until the pixels are ready. * - * Use vips_sink_screen() to calculate an area of pixels in the + * Use [method@Image.sink_screen] to calculate an area of pixels in the * background. * - * See also: vips_sink_screen(), vips_region_prepare_to(). + * ::: seealso + * [method@Image.sink_screen], [method@Region.prepare_to]. * * Returns: 0 on success, or -1 on error. */ @@ -1714,8 +1723,7 @@ vips_region_prepare_to_generate(VipsRegion *reg, VipsPel *p; if (!im->generate_fn) { - vips_error("vips_region_prepare_to", - "%s", _("incomplete header")); + vips_error("vips_region_prepare_to", "%s", _("incomplete header")); return -1; } @@ -1745,22 +1753,23 @@ vips_region_prepare_to_generate(VipsRegion *reg, * vips_region_prepare_to: * @reg: region to prepare * @dest: region to write to - * @r: #VipsRect of pixels you need to be able to address + * @r: [struct@Rect] of pixels you need to be able to address * @x: position of @r in @dest * @y: position of @r in @dest * - * Like vips_region_prepare(): fill @reg with the pixels in area @r. + * Like [method@Region.prepare]: fill @reg with the pixels in area @r. * - * Unlike vips_region_prepare(), rather than writing the result to @reg, the + * Unlike [method@Region.prepare], rather than writing the result to @reg, the * pixels are written into @dest at offset @x, @y. * - * Also unlike vips_region_prepare(), @dest is not set up for writing for - * you with vips_region_buffer(). You can + * Also unlike [method@Region.prepare], @dest is not set up for writing for + * you with [method@Region.buffer]. You can * point @dest at anything, and pixels really will be written there. - * This makes vips_region_prepare_to() useful for making the ends of + * This makes [method@Region.prepare_to] useful for making the ends of * pipelines. * - * See also: vips_region_prepare(), vips_sink_disc(). + * ::: seealso + * [method@Region.prepare], [method@Image.sink_disc]. * * Returns: 0 on success, or -1 on error */ @@ -1790,7 +1799,7 @@ vips_region_prepare_to(VipsRegion *reg, /* clip r first against the size of reg->im, then again against the * memory we have available to write to on dest. Just like - * vips_region_region() + * [method@Region.region] */ image.top = 0; image.left = 0; @@ -1809,8 +1818,7 @@ vips_region_prepare_to(VipsRegion *reg, /* Test that dest->valid is large enough. */ if (!vips_rect_includesrect(&dest->valid, &wanted)) { - vips_error("vips_region_prepare_to", - "%s", _("dest too small")); + vips_error("vips_region_prepare_to", "%s", _("dest too small")); return -1; } @@ -1867,8 +1875,7 @@ vips_region_prepare_to(VipsRegion *reg, * function, we are outputting. */ if (im->generate_fn) { - if (vips_region_prepare_to_generate(reg, - dest, &final, x, y)) + if (vips_region_prepare_to_generate(reg, dest, &final, x, y)) return -1; } else { @@ -1890,7 +1897,7 @@ vips_region_prepare_to(VipsRegion *reg, * was). * * We need this extra thing here because, unlike - * vips_region_prepare(), we don't vips_region_buffer() dest before + * [method@Region.prepare], we don't [method@Region.buffer] dest before * writing it. */ dest->invalid = FALSE; @@ -1898,7 +1905,7 @@ vips_region_prepare_to(VipsRegion *reg, return 0; } -/* Don't use this, use vips_reorder_prepare_many() instead. +/* Don't use this, use [func@reorder_prepare_many] instead. */ int vips_region_prepare_many(VipsRegion **reg, const VipsRect *r) @@ -1919,9 +1926,10 @@ vips_region_prepare_many(VipsRegion **reg, const VipsRect *r) * @height: area of pixels to fetch * * Generate an area of pixels and return a copy. The result must be freed - * with g_free(). The requested area must be completely inside the image. + * with [func@GLib.free]. The requested area must be completely inside the + * image. * - * This is equivalent to vips_region_prepare(), followed by a memcpy. It is + * This is equivalent to [method@Region.prepare], followed by a memcpy. It is * convenient for language bindings. * * Returns: A copy of the pixel data. @@ -2003,13 +2011,14 @@ vips_region_height(VipsRegion *region) * @reg: region to invalidate * * Mark a region as containing invalid pixels. Calling this function means - * that the next time vips_region_prepare() is called, the region will be + * that the next time [method@Region.prepare] is called, the region will be * recalculated. * - * This is faster than calling vips_image_invalidate_all(), but obviously only + * This is faster than calling [method@Image.invalidate_all], but obviously only * affects a single region. * - * See also: vips_image_invalidate_all(), vips_region_prepare(). + * ::: seealso + * [method@Image.invalidate_all], [method@Region.prepare]. */ void vips_region_invalidate(VipsRegion *reg) diff --git a/libvips/iofuncs/reorder.c b/libvips/iofuncs/reorder.c index 003d0441eb..0e18863799 100644 --- a/libvips/iofuncs/reorder.c +++ b/libvips/iofuncs/reorder.c @@ -318,15 +318,16 @@ vips__reorder_set_input(VipsImage *image, VipsImage **in) * vips_reorder_prepare_many: (method) * @image: the image that's being written * @regions: (array): the set of regions to prepare - * @r: the #VipsRect to prepare on each region + * @r: the [struct@Rect] to prepare on each region * - * vips_reorder_prepare_many() runs vips_region_prepare() on each region in - * @regions, requesting the pixels in @r. + * [method@Image.reorder_prepare_many] runs [method@Region.prepare] on each + * region in @regions, requesting the pixels in @r. * * It tries to request the regions in the order which will cause least * recomputation. This can give a large speedup, in some cases. * - * See also: vips_region_prepare(), vips_reorder_margin_hint(). + * ::: seealso + * [method@Region.prepare], [method@Image.reorder_margin_hint]. * * Returns: 0 on success, or -1 on error. */ @@ -353,15 +354,16 @@ vips_reorder_prepare_many(VipsImage *image, VipsRegion **regions, VipsRect *r) * @image: the image to hint on * @margin: the size of the margin this operation has added * - * vips_reorder_margin_hint() sets a hint that @image contains a margin, that - * is, that each vips_region_prepare() on @image will request a slightly larger - * region from it's inputs. A good value for @margin is (width * height) for - * the window the operation uses. + * [method@Image.reorder_margin_hint] sets a hint that @image contains a + * margin, that is, that each [method@Region.prepare] on @image will request + * a slightly larger region from it's inputs. A good value for @margin is + * (width * height) for the window the operation uses. * - * This information is used by vips_image_prepare_many() to attempt to reorder - * computations to minimise recomputation. + * This information is used by [method@Image.reorder_prepare_many] to attempt to + * reorder computations to minimise recomputation. * - * See also: vips_image_prepare_many(). + * ::: seealso + * [method@Image.reorder_prepare_many]. */ void vips_reorder_margin_hint(VipsImage *image, int margin) diff --git a/libvips/iofuncs/sbuf.c b/libvips/iofuncs/sbuf.c index a0d3edcdce..3d5282a054 100644 --- a/libvips/iofuncs/sbuf.c +++ b/libvips/iofuncs/sbuf.c @@ -99,9 +99,9 @@ vips_sbuf_init(VipsSbuf *sbuf) * vips_sbuf_new_from_source: * @source: source to operate on * - * Create a VipsSbuf wrapping a source. + * Create a [class@Sbuf] wrapping a source. * - * Returns: a new #VipsSbuf + * Returns: a new [class@Sbuf] */ VipsSbuf * vips_sbuf_new_from_source(VipsSource *source) @@ -127,7 +127,7 @@ vips_sbuf_new_from_source(VipsSource *source) * @sbuf: source to operate on * * Discard the input buffer and reset the read point. You must call this - * before using read or seek on the underlying #VipsSource class. + * before using read or seek on the underlying [class@Source] class. */ void vips_sbuf_unbuffer(VipsSbuf *sbuf) @@ -204,7 +204,7 @@ vips_sbuf_getc(VipsSbuf *sbuf) * vips_sbuf_ungetc: * @sbuf: source to operate on * - * The opposite of vips_sbuf_getc(): undo the previous getc. + * The opposite of [method@Sbuf.getc]: undo the previous getc. * * unget more than one character is undefined. Unget at the start of the file * does nothing. @@ -222,7 +222,7 @@ vips_sbuf_ungetc(VipsSbuf *sbuf) * VIPS_SBUF_UNGETC: * @sbuf: source to operate on * - * The opposite of vips_sbuf_getc(): undo the previous getc. + * The opposite of [method@Sbuf.getc]: undo the previous getc. * * unget more than one character is undefined. Unget at the start of the file * does nothing. @@ -327,7 +327,7 @@ vips_sbuf_require(VipsSbuf *sbuf, int require) * * If the line is longer than some arbitrary (but large) limit, it is * truncated. If you need to be able to read very long lines, use the - * slower vips_sbuf_get_line_copy(). + * slower [method@Sbuf.get_line_copy]. * * The return value is owned by @sbuf and must not be freed. It * is valid until the next get call to @sbuf. @@ -393,9 +393,9 @@ vips_sbuf_get_line(VipsSbuf *sbuf) * line character (or characters, for DOS files) are removed, and the string * is terminated with a null (`\0` character). * - * The return result must be freed with g_free(). + * The return result must be freed with [func@GLib.free]. * - * This is slower than vips_sbuf_get_line(), but can work with lines of + * This is slower than [method@Sbuf.get_line], but can work with lines of * any length. * * Returns: the next line of text, or NULL on EOF or read error. diff --git a/libvips/iofuncs/sink.c b/libvips/iofuncs/sink.c index 67f1a8eab0..8d94bdccc1 100644 --- a/libvips/iofuncs/sink.c +++ b/libvips/iofuncs/sink.c @@ -460,7 +460,8 @@ vips_sink_base_progress(void *a) * image edges). This is handy for things like writing a tiled TIFF image, * where tiles have to be generated with a certain size. * - * See also: vips_sink(), vips_get_tile_size(). + * ::: seealso + * [method@Image.sink], [method@Image.get_tile_size]. * * Returns: 0 on success, or -1 on error. */ @@ -520,14 +521,15 @@ vips_sink_tile(VipsImage *im, * @b: user data * * Loops over an image. @generate_fn is called for every pixel in - * the image, with - * the @reg argument being a region of calculated pixels. vips_sink() is - * used to implement operations like vips_avg() which have no image output. + * the image, with the @reg argument being a region of calculated pixels. + * [method@Image.sink] is used to implement operations like + * [method@Image.avg] which have no image output. * * Each set of pixels is sized according to the requirements of the image * pipeline that generated @im. * - * See also: vips_image_generate(), vips_image_new(). + * ::: seealso + * [method@Image.generate], [ctor@Image.new]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/iofuncs/sinkmemory.c b/libvips/iofuncs/sinkmemory.c index 2871ec57ff..5045b5fee0 100644 --- a/libvips/iofuncs/sinkmemory.c +++ b/libvips/iofuncs/sinkmemory.c @@ -76,7 +76,7 @@ typedef struct _SinkMemory { SinkMemoryArea *old_area; /* A region covering the whole of the output image ... we write to - * this from many workers with vips_region_prepare_to(). + * this from many workers with [method@Region.prepare_to]. */ VipsRegion *region; } SinkMemory; @@ -314,7 +314,9 @@ sink_memory_init(SinkMemory *memory, VipsImage *image) * Loops over @im, generating it to a memory buffer attached to @im. It is * used by vips to implement writing to a memory buffer. * - * See also: vips_sink(), vips_get_tile_size(), vips_image_new_memory(). + * ::: seealso + * [method@Image.sink], [method@Image.get_tile_size], + * [ctor@Image.new_memory]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/iofuncs/sinkscreen.c b/libvips/iofuncs/sinkscreen.c index d05123edb2..b5505f4ab4 100644 --- a/libvips/iofuncs/sinkscreen.c +++ b/libvips/iofuncs/sinkscreen.c @@ -1152,23 +1152,24 @@ vips__sink_screen_once(void *data) * consisting of a single tile. Single tile images are effectively * single-threaded, so all these renders are evaluated together. * - * Calls to vips_region_prepare() on @out return immediately and hold - * whatever is currently in cache for that #VipsRect (check @mask to see - * which parts of the #VipsRect are valid). Any pixels in the #VipsRect + * Calls to [method@Region.prepare] on @out return immediately and hold + * whatever is currently in cache for that [struct@Rect] (check @mask to see + * which parts of the [struct@Rect] are valid). Any pixels in the [struct@Rect] * which are not in cache are added to a queue, and the @notify_fn * callback will trigger when those pixels are ready. * * The @notify_fn callback is run from one of the background threads. In the * callback you need to somehow send a message to the main thread that the * pixels are ready. In a glib-based application, this is easily done with - * g_idle_add(). + * [func@GLib.idle_add]. * - * If @notify_fn is %NULL then vips_sink_screen() runs synchronously. - * vips_region_prepare() on @out will always block until the pixels have been + * If @notify_fn is %NULL then [method@Image.sink_screen] runs synchronously. + * [method@Region.prepare] on @out will always block until the pixels have been * calculated. * - * See also: vips_tilecache(), vips_region_prepare(), - * vips_sink_disc(), vips_sink(). + * ::: seealso + * [method@Image.tilecache], [method@Region.prepare], + * [method@Image.sink_disc], [method@Image.sink]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/iofuncs/source.c b/libvips/iofuncs/source.c index 56839984b4..1da8894193 100644 --- a/libvips/iofuncs/source.c +++ b/libvips/iofuncs/source.c @@ -119,7 +119,7 @@ /* -1 on a pipe isn't actually unbounded. Have a limit to prevent * huge sources accidentally filling memory. * - * This can be configured with vips_pipe_read_limit_set(). + * This can be configured with [func@pipe_read_limit_set]. */ static gint64 vips__pipe_read_limit = 1024 * 1024 * 1024; @@ -132,12 +132,13 @@ static gint64 vips__pipe_read_limit = 1024 * 1024 * 1024; * automatically read into memory to EOF before the loader starts. This can * produce high memory use if the descriptor represents a large object. * - * Use vips_pipe_read_limit_set() to limit the size of object that + * Use [func@pipe_read_limit_set] to limit the size of object that * will be read in this way. The default is 1GB. * * Set a value of -1 to mean no limit. * - * See also: `--vips-pipe-read-limit` and the environment variable + * ::: seealso + * `--vips-pipe-read-limit` and the environment variable * `VIPS_PIPE_READ_LIMIT`. */ void @@ -163,7 +164,7 @@ vips_source_test_seek(VipsSource *source) /* Can we seek this input? * * We need to call the method directly rather than via - * vips_source_seek() etc. or we might trigger seek emulation. + * [func@source_seek] etc. or we might trigger seek emulation. */ if (source->data || class->seek(source, 0, SEEK_CUR) != -1) { @@ -376,7 +377,7 @@ vips_source_seek_real(VipsSource *source, gint64 offset, int whence) VIPS_DEBUG_MSG("vips_source_seek_real:\n"); /* Like _read_real(), we must not set a vips_error. We need to use the - * vips__seek() wrapper so we can seek long files on Windows. + * vips__seek wrapper so we can seek long files on Windows. */ if (connection->descriptor != -1) return vips__seek_no_error(connection->descriptor, offset, whence); @@ -460,7 +461,7 @@ vips_source_new_from_descriptor(int descriptor) * automatically read into memory to EOF before the loader starts. This can * produce high memory use if the descriptor represents a large object. * - * Use vips_pipe_read_limit_set() to limit the size of object that + * Use [func@pipe_read_limit_set] to limit the size of object that * will be read in this way. The default is 1GB. * * Returns: a new source. @@ -622,7 +623,7 @@ vips_source_new_from_options(const char *options) * @source: source to operate on * * Minimise the source. As many resources as can be safely removed are - * removed. Use vips_source_unminimise() to restore the source if you wish to + * removed. Use [method@Source.unminimise] to restore the source if you wish to * use it again. * * Loaders should call this in response to the minimise signal on their output @@ -662,7 +663,8 @@ vips_source_minimise(VipsSource *source) * Restore the source after minimisation. This is called at the start * of every source method, so loaders should not usually need this. * - * See also: vips_source_minimise(). + * ::: seealso + * [method@Source.minimise]. * * Returns: 0 on success, or -1 on error. */ @@ -720,7 +722,8 @@ vips_source_unminimise(VipsSource *source) * * Loaders should call this at the end of header read. * - * See also: vips_source_unminimise(). + * ::: seealso + * [method@Source.unminimise]. * * Returns: 0 on success, -1 on error. */ @@ -737,7 +740,7 @@ vips_source_decode(VipsSource *source) VIPS_FREEF(g_byte_array_unref, source->sniff); /* Now decode is set, header_bytes will be freed once it's - * exhausted, see vips_source_read(). + * exhausted, see [func@source_read]. */ } @@ -1020,7 +1023,7 @@ vips_source_descriptor_to_memory(VipsSource *source) * @source: source to operate on * * Some sources can be efficiently mapped into memory. - * You can still use vips_source_map() if this function returns %FALSE, + * You can still use [method@Source.map] if this function returns %FALSE, * but it will be slow. * * Returns: %TRUE if the source can be efficiently mapped into memory. @@ -1047,7 +1050,7 @@ vips_source_is_mappable(VipsSource *source) * * Test if this source is a simple file with support for seek. Named pipes, * for example, will fail this test. If TRUE, you can use - * vips_connection_filename() to find the filename. + * [method@Connection.filename] to find the filename. * * Use this to add basic source support for older loaders which can only work * on files. @@ -1075,7 +1078,7 @@ vips_source_is_file(VipsSource *source) * Map the source entirely into memory and return a pointer to the * start. If @length is non-NULL, the source size is written to it. * - * This operation can take a long time. Use vips_source_is_mappable() to + * This operation can take a long time. Use [method@Source.is_mappable] to * check if a source can be mapped efficiently. * * The pointer is valid for as long as @source is alive. @@ -1136,10 +1139,10 @@ vips_source_map_cb(void *a, VipsArea *area) * vips_source_map_blob: * @source: source to operate on * - * Just like vips_source_map(), but return a #VipsBlob containing the + * Just like [method@Source.map], but return a [struct@Blob] containing the * pointer. @source will stay alive as long as the result is alive. * - * Returns: a new #VipsBlob containing the data, or NULL on error. + * Returns: a new [struct@Blob] containing the data, or NULL on error. */ VipsBlob * vips_source_map_blob(VipsSource *source) diff --git a/libvips/iofuncs/sourcecustom.c b/libvips/iofuncs/sourcecustom.c index c90028f27e..3dd95ab7e0 100644 --- a/libvips/iofuncs/sourcecustom.c +++ b/libvips/iofuncs/sourcecustom.c @@ -229,9 +229,9 @@ vips_source_custom_init(VipsSourceCustom *source_custom) /** * vips_source_custom_new: * - * Create a #VipsSourceCustom. Attach signals to implement read and seek. + * Create a [class@SourceCustom]. Attach signals to implement read and seek. * - * Returns: a new #VipsSourceCustom + * Returns: a new [class@SourceCustom] */ VipsSourceCustom * vips_source_custom_new(void) diff --git a/libvips/iofuncs/sourceginput.c b/libvips/iofuncs/sourceginput.c index ee2aa6cd59..ea5d55b7ef 100644 --- a/libvips/iofuncs/sourceginput.c +++ b/libvips/iofuncs/sourceginput.c @@ -240,7 +240,10 @@ vips_source_g_input_stream_init(VipsSourceGInputStream *source) * vips_source_g_input_stream_new: * @stream: read from this stream * - * Create a #VipsSourceGInputStream which wraps @stream. + * Create a [struct@SourceGInputStream] which wraps @stream. + * + * ::: seealso + * [func@g_input_stream_new_from_source] * * Returns: (transfer full): the new source. */ diff --git a/libvips/iofuncs/system.c b/libvips/iofuncs/system.c index 51dbc37737..ec9a1b0408 100644 --- a/libvips/iofuncs/system.c +++ b/libvips/iofuncs/system.c @@ -7,7 +7,7 @@ * 10/3/03 JC * - out can be NULL * 23/12/04 - * - use g_mkstemp() + * - use [func@GLib.mkstemp] * 8/9/09 * - add .v suffix (thanks Roland) * - use vipsbuf @@ -325,37 +325,36 @@ vips_system_init(VipsSystem *system) * @cmd_format: command to run * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * ::: note "Optional arguments" + * * @in: array of input images + * * @out: output image + * * @in_format: write input files like this + * * @out_format: write output filename like this + * * @log: stdout of command is returned here * - * * @in: array of input images - * * @out: output image - * * @in_format: write input files like this - * * @out_format: write output filename like this - * * @log: stdout of command is returned here - * - * vips_system() runs a command, optionally passing a set of images in and + * [ctor@Image.system] runs a command, optionally passing a set of images in and * optionally getting an image back. The command's stdout is returned in @log. * * First, if @in is set, the array of images are written to files. See - * vips_image_new_temp_file() to see how temporary files are created. - * If @in_format is - * something like %s.png, the file will be written in PNG format. By - * default, @in_format is %s.tif. + * [ctor@Image.new_temp_file] to see how temporary files are created. + * If @in_format is something like `%s.png`, the file will be written in PNG + * format. By default, @in_format is `%s.tif`. * * If @out_format is set, an output filename is formed in the same way. Any - * trailing [options] are stripped from @out_format. + * trailing `[options]` are stripped from @out_format. * - * The command string to run is made by substituting the first set of %s + * The command string to run is made by substituting the first set of `%s` * in @cmd_format for the names of the input files, if @in is set, and then - * the next %s for the output filename, if @out_format is set. - * You can put a number between the % and the s to change the order + * the next `%s` for the output filename, if @out_format is set. + * You can put a number between the `%` and the `s` to change the order * in which the substitution occurs. * * The command is executed with popen() and the output captured in @log. * * After the command finishes, if @out_format is set, the output image is - * opened and returned in @out. You can append [options] to @out_format to + * opened and returned in @out. You can append `[options]` to @out_format to * control how this open happens. + * * Closing @out image will automatically delete the output file. * * Finally the input images are deleted. @@ -363,7 +362,7 @@ vips_system_init(VipsSystem *system) * For example, this call will run the ImageMagick convert program on an * image, using JPEG files to pass images into and out of the convert command. * - * |[ + * ```c * VipsArrayImage *in; * VipsImage *out; * char *log; @@ -376,7 +375,7 @@ vips_system_init(VipsSystem *system) * "log", &log, * NULL)) * error ... - * ]| + * ``` * * Returns: 0 on success, -1 on failure. */ diff --git a/libvips/iofuncs/target.c b/libvips/iofuncs/target.c index a6709adc93..a400d4d7b9 100644 --- a/libvips/iofuncs/target.c +++ b/libvips/iofuncs/target.c @@ -322,7 +322,8 @@ vips_target_init(VipsTarget *target) * Create a target attached to a file descriptor. * @descriptor is kept open until the target is finalized. * - * See also: [ctor@Target.new_to_file]. + * ::: seealso + * [ctor@Target.new_to_file]. * * Returns: a new target. */ @@ -380,7 +381,8 @@ vips_target_new_to_file(const char *filename) * Create a target which will write to a memory area. Read from @blob to get * memory. * - * See also: [ctor@Target.new_to_file]. + * ::: seealso + * [ctor@Target.new_to_file]. * * Returns: a new target. */ @@ -410,7 +412,8 @@ vips_target_new_to_memory(void) * Create a temporary target -- either a temporary file on disc, or an area in * memory, depending on what sort of target @based_on is. * - * See also: [ctor@Target.new_to_file]. + * ::: seealso + * [ctor@Target.new_to_file]. * * Returns: a new target. */ diff --git a/libvips/iofuncs/targetcustom.c b/libvips/iofuncs/targetcustom.c index 84aaca2d94..da68025c45 100644 --- a/libvips/iofuncs/targetcustom.c +++ b/libvips/iofuncs/targetcustom.c @@ -348,9 +348,9 @@ vips_target_custom_init(VipsTargetCustom *target_custom) /** * vips_target_custom_new: * - * Create a #VipsTargetCustom. Attach signals to implement write and finish. + * Create a [class@TargetCustom]. Attach signals to implement write and finish. * - * Returns: a new #VipsTargetCustom + * Returns: a new [class@TargetCustom] */ VipsTargetCustom * vips_target_custom_new(void) diff --git a/libvips/iofuncs/thread.c b/libvips/iofuncs/thread.c index a15ba85b9f..24bbaa0371 100644 --- a/libvips/iofuncs/thread.c +++ b/libvips/iofuncs/thread.c @@ -120,9 +120,10 @@ vips_thread_run(gpointer data) * @func: (scope async) (closure data): a function to execute in the new thread * @data: (nullable): an argument to supply to the new thread * - * Wrapper for g_thread_try_new(). + * Wrapper for [ctor@GLib.Thread.try_new]. * - * Returns: (transfer full): the new #GThread, or %NULL if an error occurred + * Returns: (transfer full): the new [struct@GLib.Thread], or %NULL if an + * error occurred */ GThread * vips_g_thread_new(const char *domain, GThreadFunc func, gpointer data) @@ -191,14 +192,15 @@ vips__concurrency_get_default(void) * vips_concurrency_set: * @concurrency: number of threads to run * - * Sets the number of worker threads that vips should use when running a - * #VipsThreadPool. + * Sets the number of worker threads that vips should use when running + * [func@threadpool_run]. * * The special value 0 means "default". In this case, the number of threads * is set by the environment variable VIPS_CONCURRENCY, or if that is not * set, the number of threads available on the host machine. * - * See also: vips_concurrency_get(). + * ::: seealso + * [func@concurrency_get]. */ void vips_concurrency_set(int concurrency) @@ -219,16 +221,16 @@ vips_concurrency_set(int concurrency) /** * vips_concurrency_get: * - * Returns the number of worker threads that vips should use when running a - * #VipsThreadPool. + * Returns the number of worker threads that vips should use when running + * [func@threadpool_run]. * * vips gets this values from these sources in turn: * - * If vips_concurrency_set() has been called, this value is used. The special + * If [func@concurrency_set] has been called, this value is used. The special * value 0 means "default". You can also use the command-line argument * "--vips-concurrency" to set this value. * - * If vips_concurrency_set() has not been called and no command-line argument + * If [func@concurrency_set] has not been called and no command-line argument * was used, vips uses the value of the environment variable VIPS_CONCURRENCY, * * If VIPS_CONCURRENCY has not been set, vips finds the number of hardware @@ -236,7 +238,8 @@ vips_concurrency_set(int concurrency) * * The final value is clipped to the range 1 - 1024. * - * See also: vips_concurrency_get(). + * ::: seealso + * [func@concurrency_get]. * * Returns: number of worker threads to use. */ @@ -254,7 +257,7 @@ vips_concurrency_get(void) * @n_lines: (out): return buffer height in scanlines * * Pick a tile size and a buffer height for this image and the current - * value of vips_concurrency_get(). The buffer height + * value of [func@concurrency_get]. The buffer height * will always be a multiple of tile_height. * * The buffer height is the height of each buffer we fill in sink disc. Since diff --git a/libvips/iofuncs/threadpool.c b/libvips/iofuncs/threadpool.c index a84ca93112..808eb16a88 100644 --- a/libvips/iofuncs/threadpool.c +++ b/libvips/iofuncs/threadpool.c @@ -85,7 +85,8 @@ * [callback@ThreadpoolAllocateFn] functions can use these members to * communicate with [callback@ThreadpoolWorkFn] functions. * - * See also: [func@threadpool_run]. + * ::: seealso + * [func@threadpool_run]. */ /* Set to stall threads for debugging. @@ -545,14 +546,16 @@ vips_threadpool_new(VipsImage *im) * * This function is called once by each worker just before the first time work * is allocated to it to build the per-thread state. Per-thread state is used - * by #VipsThreadpoolAllocate and #VipsThreadpoolWork to communicate. + * by [callback@ThreadpoolAllocateFn] and [callback@ThreadpoolWorkFn] to + * communicate. * - * #VipsThreadState is a subclass of #VipsObject. Start functions are called - * from allocate, that is, they are single-threaded. + * [class@ThreadState] is a subclass of [class@Object]. Start functions are + * called from allocate, that is, they are single-threaded. * - * See also: vips_threadpool_run(). + * ::: seealso + * [func@threadpool_run]. * - * Returns: a new #VipsThreadState object, or NULL on error + * Returns: a new [class@ThreadState] object, or NULL on error */ /** @@ -568,7 +571,8 @@ vips_threadpool_new(VipsImage *im) * It should set @stop to %TRUE to indicate that no work could be allocated * because the job is done. * - * See also: vips_threadpool_run(). + * ::: seealso + * [func@threadpool_run]. * * Returns: 0 on success, or -1 on error */ @@ -582,7 +586,8 @@ vips_threadpool_new(VipsImage *im) * at once, so it should not write to the per-pool state. It can write to * per-thread state. * - * See also: vips_threadpool_run(). + * ::: seealso + * [func@threadpool_run]. * * Returns: 0 on success, or -1 on error */ @@ -594,7 +599,8 @@ vips_threadpool_new(VipsImage *im) * This function is called by the main thread once for every work unit * processed. It can be used to give the user progress feedback. * - * See also: vips_threadpool_run(). + * ::: seealso + * [func@threadpool_run]. * * Returns: 0 on success, or -1 on error */ @@ -616,14 +622,15 @@ vips_threadpool_new(VipsImage *im) * progress feedback. @progress may be %NULL. * * The object returned by @start must be an instance of a subclass of - * #VipsThreadState. Use this to communicate between @allocate and @work. + * [class@ThreadState]. Use this to communicate between @allocate and @work. * * @allocate and @start are always single-threaded (so they can write to the * per-pool state), whereas @work can be executed concurrently. @progress is * always called by - * the main thread (ie. the thread which called vips_threadpool_run()). + * the main thread (ie. the thread which called [func@threadpool_run]). * - * See also: vips_concurrency_set(). + * ::: seealso + * [func@concurrency_set]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/iofuncs/threadset.c b/libvips/iofuncs/threadset.c index e242d50c63..8c221c03f1 100644 --- a/libvips/iofuncs/threadset.c +++ b/libvips/iofuncs/threadset.c @@ -252,10 +252,10 @@ vips_threadset_add_thread(VipsThreadset *set) * Create a new threadset. * * If @max_threads is 0, new threads will be created when necessary by - * vips_threadset_run(), with no limit on the number of threads. + * [func@threadset_run], with no limit on the number of threads. * * If @max_threads is > 0, then that many threads will be created by - * vips_threadset_new() during startup and vips_threadset_run() will + * [ctor@Threadset.new] during startup and [func@threadset_run] will * not spawn any additional threads. * * Returns: the new threadset. @@ -292,7 +292,8 @@ vips_threadset_new(int max_threads) * thread limit specified by @max_threads has not been reached, a new thread * will be spawned. * - * See also: vips_threadset_new(). + * ::: seealso + * [ctor@Threadset.new]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index 8eed55a357..692e62ed29 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -93,7 +93,7 @@ * vips_thing_new: * @i: * - * Returns: (transfer full): a new #VipsThing. + * Returns: (transfer full): a new [struct@Thing]. */ VipsThing * vips_thing_new(int i) @@ -240,14 +240,15 @@ VipsArrayImage_unref(VipsArrayImage *array) * function. It also keeps a count and a %GType, so the area can be an array. * * This type is used for things like passing an array of double or an array of - * #VipsObject pointers to operations, and for reference-counted immutable + * [class@Object] pointers to operations, and for reference-counted immutable * strings. * * Initial count == 1, so _unref() after attaching somewhere. * - * See also: vips_area_unref(). + * ::: seealso + * [method@Area.unref]. * - * Returns: (transfer full): the new #VipsArea. + * Returns: (transfer full): the new [struct@Area]. */ VipsArea * vips_area_new(VipsCallbackFn free_fn, void *data) @@ -314,9 +315,10 @@ vips__type_leak(void) * An area which holds an array of elements of some %GType. To set values for * the elements, get the pointer and write. * - * See also: vips_area_unref(). + * ::: seealso + * [method@Area.unref]. * - * Returns: (transfer full): the new #VipsArea. + * Returns: (transfer full): the new [struct@Area]. */ VipsArea * vips_area_new_array(GType type, size_t sizeof_type, int n) @@ -352,15 +354,16 @@ vips_area_free_array_object(GObject **array, VipsArea *area) * vips_area_new_array_object: (constructor) * @n: number of elements in the array * - * An area which holds an array of %GObject s. See vips_area_new_array(). When - * the area is freed, each %GObject will be unreffed. + * An area which holds an array of [class@GObject.Object] s. See [ctor@Area.new_array]. When + * the area is freed, each [class@GObject.Object] will be unreffed. * * Add an extra NULL element at the end, handy for eg. - * vips_image_pipeline_array() etc. + * [func@Image.pipeline_array] etc. * - * See also: vips_area_unref(). + * ::: seealso + * [method@Area.unref]. * - * Returns: (transfer full): the new #VipsArea. + * Returns: (transfer full): the new [struct@Area]. */ VipsArea * vips_area_new_array_object(int n) @@ -381,7 +384,7 @@ vips_area_new_array_object(int n) /** * vips_area_get_data: - * @area: #VipsArea to fetch from + * @area: [struct@Area] to fetch from * @length: (out) (optional): optionally return length in bytes here * @n: (out) (optional): optionally return number of elements here * @type: (out) (optional): optionally return element type here @@ -568,9 +571,11 @@ transform_save_string_ref_string(const GValue *src_value, GValue *dest_value) * * Strings must be valid utf-8; use blob for binary data. * - * See also: vips_area_unref(). + * ::: seealso + * [method@Area.unref]. * - * Returns: (transfer full) (nullable): the new #VipsRefString, or NULL on error. + * Returns: (transfer full) (nullable): the new [struct@RefString], or NULL on + * error. */ VipsRefString * vips_ref_string_new(const char *str) @@ -590,13 +595,14 @@ vips_ref_string_new(const char *str) /** * vips_ref_string_get: - * @refstr: the #VipsRefString to fetch from + * @refstr: the [struct@RefString] to fetch from * @length: (out) (optional): return length here, optionally * * Get a pointer to the private string inside a refstr. Handy for language * bindings. * - * See also: vips_value_get_ref_string(). + * ::: seealso + * [func@value_get_ref_string]. * * Returns: (transfer none): The C string held by @refstr. */ @@ -637,16 +643,17 @@ G_DEFINE_BOXED_TYPE_WITH_CODE(VipsRefString, vips_ref_string, * @data: (array length=length) (element-type guint8) (transfer full): data to store * @length: number of bytes in @data * - * Like vips_area_new(), but track a length as well. The returned #VipsBlob + * Like [ctor@Area.new], but track a length as well. The returned [struct@Blob] * takes ownership of @data and will free it with @free_fn. Pass %NULL for * @free_fn to not transfer ownership. * * An area of mem with a free func and a length (some sort of binary object, * like an ICC profile). * - * See also: vips_area_unref(). + * ::: seealso + * [method@Area.unref]. * - * Returns: (transfer full): the new #VipsBlob. + * Returns: (transfer full): the new [struct@Blob]. */ VipsBlob * vips_blob_new(VipsCallbackFn free_fn, const void *data, size_t length) @@ -664,12 +671,13 @@ vips_blob_new(VipsCallbackFn free_fn, const void *data, size_t length) * @data: (array length=length) (element-type guint8) (transfer none): data to store * @length: number of bytes in @data * - * Like vips_blob_new(), but take a copy of the data. Useful for bindings + * Like [ctor@Blob.new], but take a copy of the data. Useful for bindings * which struggle with callbacks. * - * See also: vips_blob_new(). + * ::: seealso + * [ctor@Blob.new]. * - * Returns: (transfer full): the new #VipsBlob. + * Returns: (transfer full): the new [struct@Blob]. */ VipsBlob * vips_blob_copy(const void *data, size_t length) @@ -687,12 +695,13 @@ vips_blob_copy(const void *data, size_t length) /** * vips_blob_get: - * @blob: #VipsBlob to fetch from + * @blob: [struct@Blob] to fetch from * @length: return number of bytes of data * - * Get the data from a #VipsBlob. + * Get the data from a [struct@Blob]. * - * See also: vips_blob_new(). + * ::: seealso + * [ctor@Blob.new]. * * Returns: (array length=length) (element-type guint8) (transfer none): the * data @@ -706,7 +715,7 @@ vips_blob_get(VipsBlob *blob, size_t *length) /** * vips_blob_set: - * @blob: #VipsBlob to set + * @blob: [struct@Blob] to set * @free_fn: (scope async) (allow-none): @data will be freed with this function * @data: (array length=length) (element-type guint8) (transfer full): data to store * @length: number of bytes in @data @@ -716,7 +725,8 @@ vips_blob_get(VipsBlob *blob, size_t *length) * It's sometimes useful to be able to create blobs as empty and then fill * them later. * - * See also: vips_blob_new(). + * ::: seealso + * [ctor@Blob.new]. */ void vips_blob_set(VipsBlob *blob, @@ -813,11 +823,12 @@ G_DEFINE_BOXED_TYPE_WITH_CODE(VipsBlob, vips_blob, * @n: number of ints * * Allocate a new array of ints and copy @array into it. Free with - * vips_area_unref(). + * [method@Area.unref]. * - * See also: #VipsArea. + * ::: seealso + * [struct@Area]. * - * Returns: (transfer full): A new #VipsArrayInt. + * Returns: (transfer full): A new [struct@ArrayInt]. */ VipsArrayInt * vips_array_int_new(const int *array, int n) @@ -838,11 +849,12 @@ vips_array_int_new(const int *array, int n) * @...: list of int arguments * * Allocate a new array of @n ints and copy @... into it. Free with - * vips_area_unref(). + * [method@Area.unref]. * - * See also: vips_array_int_new() + * ::: seealso + * [ctor@ArrayInt.new] * - * Returns: (transfer full): A new #VipsArrayInt. + * Returns: (transfer full): A new [struct@ArrayInt]. */ VipsArrayInt * vips_array_int_newv(int n, ...) @@ -865,10 +877,10 @@ vips_array_int_newv(int n, ...) /** * vips_array_int_get: - * @array: the #VipsArrayInt to fetch from + * @array: the [struct@ArrayInt] to fetch from * @n: length of array * - * Fetch an int array from a #VipsArrayInt. Useful for language bindings. + * Fetch an int array from a [struct@ArrayInt]. Useful for language bindings. * * Returns: (array length=n) (transfer none): array of int */ @@ -1058,11 +1070,12 @@ G_DEFINE_BOXED_TYPE_WITH_CODE(VipsArrayInt, vips_array_int, * @n: number of doubles * * Allocate a new array of doubles and copy @array into it. Free with - * vips_area_unref(). + * [method@Area.unref]. * - * See also: #VipsArea. + * ::: seealso + * [struct@Area]. * - * Returns: (transfer full): A new #VipsArrayDouble. + * Returns: (transfer full): A new [struct@ArrayDouble]. */ VipsArrayDouble * vips_array_double_new(const double *array, int n) @@ -1083,11 +1096,12 @@ vips_array_double_new(const double *array, int n) * @...: list of double arguments * * Allocate a new array of @n doubles and copy @... into it. Free with - * vips_area_unref(). + * [method@Area.unref]. * - * See also: vips_array_double_new() + * ::: seealso + * [ctor@ArrayDouble.new] * - * Returns: (transfer full): A new #VipsArrayDouble. + * Returns: (transfer full): A new [struct@ArrayDouble]. */ VipsArrayDouble * vips_array_double_newv(int n, ...) @@ -1110,10 +1124,10 @@ vips_array_double_newv(int n, ...) /** * vips_array_double_get: - * @array: the #VipsArrayDouble to fetch from + * @array: the [struct@ArrayDouble] to fetch from * @n: length of array * - * Fetch a double array from a #VipsArrayDouble. Useful for language bindings. + * Fetch a double array from a [struct@ArrayDouble]. Useful for language bindings. * * Returns: (array length=n) (transfer none): array of double */ @@ -1268,22 +1282,23 @@ G_DEFINE_BOXED_TYPE_WITH_CODE(VipsArrayDouble, vips_array_double, /** * vips_array_image_new: (constructor) - * @array: (array length=n): array of #VipsImage + * @array: (array length=n): array of [class@Image] * @n: number of images * * Allocate a new array of images and copy @array into it. Free with - * vips_area_unref(). + * [method@Area.unref]. * * The images will all be reffed by this function. They * will be automatically unreffed for you by - * vips_area_unref(). + * [method@Area.unref]. * * Add an extra NULL element at the end, handy for eg. - * vips_image_pipeline_array() etc. + * [func@Image.pipeline_array] etc. * - * See also: #VipsArea. + * ::: seealso + * [struct@Area]. * - * Returns: (transfer full): A new #VipsArrayImage. + * Returns: (transfer full): A new [struct@ArrayImage]. */ VipsArrayImage * vips_array_image_new(VipsImage **array, int n) @@ -1307,21 +1322,22 @@ vips_array_image_new(VipsImage **array, int n) /** * vips_array_image_newv: (constructor) * @n: number of images - * @...: list of #VipsImage arguments + * @...: list of [class@Image] arguments * - * Allocate a new array of @n #VipsImage and copy @... into it. Free with - * vips_area_unref(). + * Allocate a new array of @n [class@Image] and copy @... into it. Free with + * [method@Area.unref]. * * The images will all be reffed by this function. They * will be automatically unreffed for you by - * vips_area_unref(). + * [method@Area.unref]. * * Add an extra NULL element at the end, handy for eg. - * vips_image_pipeline_array() etc. + * [func@Image.pipeline_array] etc. * - * See also: vips_array_image_new() + * ::: seealso + * [ctor@ArrayImage.new] * - * Returns: (transfer full): A new #VipsArrayImage. + * Returns: (transfer full): A new [struct@ArrayImage]. */ VipsArrayImage * vips_array_image_newv(int n, ...) @@ -1395,12 +1411,13 @@ vips_array_image_new_from_string(const char *string, VipsAccess access) * vips_array_image_empty: (constructor) * * Make an empty image array. - * Handy with vips_array_image_add() for bindings + * Handy with [method@ArrayImage.append] for bindings * which can't handle object array arguments. * - * See also: vips_array_image_add(). + * ::: seealso + * [method@ArrayImage.append]. * - * Returns: (transfer full): A new #VipsArrayImage. + * Returns: (transfer full): A new [struct@ArrayImage]. */ VipsArrayImage * vips_array_image_empty(void) @@ -1413,14 +1430,15 @@ vips_array_image_empty(void) * @array: (transfer none): append to this * @image: add this * - * Make a new #VipsArrayImage, one larger than @array, with @image appended + * Make a new [struct@ArrayImage], one larger than @array, with @image appended * to the end. - * Handy with vips_array_image_empty() for bindings + * Handy with [ctor@ArrayImage.empty] for bindings * which can't handle object array arguments. * - * See also: vips_array_image_empty(). + * ::: seealso + * [ctor@ArrayImage.empty]. * - * Returns: (transfer full): A new #VipsArrayImage. + * Returns: (transfer full): A new [struct@ArrayImage]. */ VipsArrayImage * vips_array_image_append(VipsArrayImage *array, VipsImage *image) @@ -1450,12 +1468,12 @@ vips_array_image_append(VipsArrayImage *array, VipsImage *image) /** * vips_array_image_get: - * @array: the #VipsArrayImage to fetch from + * @array: the [struct@ArrayImage] to fetch from * @n: length of array * - * Fetch an image array from a #VipsArrayImage. Useful for language bindings. + * Fetch an image array from a [struct@ArrayImage]. Useful for language bindings. * - * Returns: (array length=n) (transfer none): array of #VipsImage + * Returns: (array length=n) (transfer none): array of [class@Image] */ VipsImage ** vips_array_image_get(VipsArrayImage *array, int *n) @@ -1479,7 +1497,7 @@ transform_g_string_array_image(const GValue *src_value, GValue *dest_value) str = g_value_dup_string(src_value); /* We can't get access here, just assume nothing. See the special case - * in vips_object_new_from_string() for how we usually get this right. + * in [method@Object.new_from_string] for how we usually get this right. */ if (!(array_image = vips_array_image_new_from_string(str, 0))) { /* Set the dest to length zero to indicate error. @@ -1600,10 +1618,10 @@ vips_value_set_save_stringf(GValue *value, const char *fmt, ...) /** * vips_value_get_ref_string: - * @value: %GValue to get from + * @value: [struct@GObject.Value] to get from * @length: (out) (optional): return length here, optionally * - * Get the C string held internally by the %GValue. + * Get the C string held internally by the [struct@GObject.Value]. * * Returns: (transfer none): The C string held by @value. */ @@ -1615,14 +1633,14 @@ vips_value_get_ref_string(const GValue *value, size_t *length) /** * vips_value_set_ref_string: - * @value: (out): %GValue to set + * @value: (out): [struct@GObject.Value] to set * @str: C string to copy into the GValue * * Copies the C string @str into @value. * * vips_ref_string are immutable C strings that are copied between images by * copying reference-counted pointers, making them much more efficient than - * regular %GValue strings. + * regular [struct@GObject.Value] strings. * * @str should be a valid utf-8 string. */ @@ -1654,7 +1672,8 @@ vips_value_set_ref_string(GValue *value, const char *str) * are saved to VIPS files for you coded as base64 inside the XML. They are * copied by copying reference-counted pointers. * - * See also: vips_value_get_blob() + * ::: seealso + * [func@value_get_blob] */ void vips_value_set_blob(GValue *value, @@ -1676,13 +1695,14 @@ vips_value_set_blob(GValue *value, * memory * @length: length of memory area * - * Just like vips_value_set_blob(), but when + * Just like [func@value_set_blob], but when * @value is freed, @data will be - * freed with g_free(). + * freed with [func@GLib.free]. * * This can be easier to call for language bindings. * - * See also: vips_value_set_blob() + * ::: seealso + * [func@value_set_blob] */ void vips_value_set_blob_free(GValue *value, void *data, size_t length) @@ -1707,7 +1727,8 @@ vips_value_set_blob_free(GValue *value, void *data, size_t length) * are saved to VIPS files for you coded as base64 inside the XML. They are * copied by copying reference-counted pointers. * - * See also: vips_value_set_blob() + * ::: seealso + * [func@value_set_blob] * * Returns: (transfer none) (array length=length) (element-type guint8): The pointer held * by @value. @@ -1720,7 +1741,7 @@ vips_value_get_blob(const GValue *value, size_t *length) /** * vips_value_set_array: - * @value: (out): %GValue to set + * @value: (out): [struct@GObject.Value] to set * @n: number of elements * @type: the type of each element * @sizeof_type: the sizeof each element @@ -1742,7 +1763,7 @@ vips_value_set_array(GValue *value, int n, GType type, size_t sizeof_type) /** * vips_value_get_array: - * @value: %GValue to get from + * @value: [struct@GObject.Value] to get from * @n: (out) (optional): return the number of elements here, optionally * @type: (out) (optional): return the type of each element here, optionally * @sizeof_type: (out) (optional): return the sizeof each element here, optionally @@ -1751,7 +1772,8 @@ vips_value_set_array(GValue *value, int n, GType type, size_t sizeof_type) * Optionally return the other properties of the array in @n, @type, * @sizeof_type. * - * See also: vips_value_set_array(). + * ::: seealso + * [func@value_set_array]. * * Returns: (transfer none): The array address. */ @@ -1762,7 +1784,7 @@ vips_value_get_array(const GValue *value, VipsArea *area; /* Can't check value type, because we may get called from - * vips_*_get_type(). + * [func@*_get_type]. */ if (!(area = g_value_get_boxed(value))) @@ -1779,13 +1801,14 @@ vips_value_get_array(const GValue *value, /** * vips_value_get_array_int: - * @value: %GValue to get from + * @value: [struct@GObject.Value] to get from * @n: (out) (optional): return the number of elements here, optionally * * Return the start of the array of ints held by @value. * optionally return the number of elements in @n. * - * See also: vips_array_int_new(). + * ::: seealso + * [ctor@ArrayInt.new]. * * Returns: (transfer none) (array length=n): The array address. */ @@ -1797,13 +1820,14 @@ vips_value_get_array_int(const GValue *value, int *n) /** * vips_value_set_array_int: - * @value: %GValue to get from + * @value: [struct@GObject.Value] to get from * @array: (array length=n) (allow-none): array of ints * @n: the number of elements * * Set @value to hold a copy of @array. Pass in the array length in @n. * - * See also: vips_array_int_get(). + * ::: seealso + * [method@ArrayInt.get]. */ void vips_value_set_array_int(GValue *value, const int *array, int n) @@ -1820,13 +1844,14 @@ vips_value_set_array_int(GValue *value, const int *array, int n) /** * vips_value_get_array_double: - * @value: %GValue to get from + * @value: [struct@GObject.Value] to get from * @n: (out) (optional): return the number of elements here, optionally * * Return the start of the array of doubles held by @value. * optionally return the number of elements in @n. * - * See also: vips_array_double_new(). + * ::: seealso + * [ctor@ArrayDouble.new]. * * Returns: (transfer none) (array length=n): The array address. */ @@ -1838,13 +1863,14 @@ vips_value_get_array_double(const GValue *value, int *n) /** * vips_value_set_array_double: - * @value: %GValue to get from + * @value: [struct@GObject.Value] to get from * @array: (array length=n) (allow-none): array of doubles * @n: the number of elements * * Set @value to hold a copy of @array. Pass in the array length in @n. * - * See also: vips_array_double_get(). + * ::: seealso + * [method@ArrayDouble.get]. */ void vips_value_set_array_double(GValue *value, const double *array, int n) @@ -1861,13 +1887,14 @@ vips_value_set_array_double(GValue *value, const double *array, int n) /** * vips_value_get_array_image: - * @value: %GValue to get from + * @value: [struct@GObject.Value] to get from * @n: (out) (optional): return the number of elements here, optionally * * Return the start of the array of images held by @value. * optionally return the number of elements in @n. * - * See also: vips_value_set_array_image(). + * ::: seealso + * [func@value_set_array_image]. * * Returns: (transfer none) (array length=n): The array address. */ @@ -1879,12 +1906,13 @@ vips_value_get_array_image(const GValue *value, int *n) /** * vips_value_set_array_image: - * @value: %GValue to get from + * @value: [struct@GObject.Value] to get from * @n: the number of elements * * Set @value to hold an array of images. Pass in the array length in @n. * - * See also: vips_array_image_get(). + * ::: seealso + * [method@ArrayImage.get]. */ void vips_value_set_array_image(GValue *value, int n) @@ -1899,13 +1927,14 @@ vips_value_set_array_image(GValue *value, int n) /** * vips_value_get_array_object: (skip) - * @value: %GValue to get from + * @value: [struct@GObject.Value] to get from * @n: (out) (optional): return the number of elements here, optionally * - * Return the start of the array of %GObject held by @value. + * Return the start of the array of [class@GObject.Object] held by @value. * Optionally return the number of elements in @n. * - * See also: vips_area_new_array_object(). + * ::: seealso + * [ctor@Area.new_array_object]. * * Returns: (transfer none) (array length=n): The array address. */ @@ -1917,12 +1946,13 @@ vips_value_get_array_object(const GValue *value, int *n) /** * vips_value_set_array_object: - * @value: (out): %GValue to set + * @value: (out): [struct@GObject.Value] to set * @n: the number of elements * - * Set @value to hold an array of %GObject. Pass in the array length in @n. + * Set @value to hold an array of [class@GObject.Object]. Pass in the array length in @n. * - * See also: vips_value_get_array_object(). + * ::: seealso + * [func@value_get_array_object]. */ void vips_value_set_array_object(GValue *value, int n) @@ -1934,7 +1964,7 @@ vips_value_set_array_object(GValue *value, int n) vips_area_unref(area); } -/* Make the types we need for basic functioning. Called from vips_init(). +/* Make the types we need for basic functioning. Called from [func@init]. */ void vips__meta_init_types(void) diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index 41e2db5b57..42804a94b0 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -266,7 +266,7 @@ vips_slist_free_all_cb(void *thing, void *dummy) * vips_slist_free_all: * @list: (element-type guint8): a #GSList * - * Free a g_slist of things which need g_free()ing. + * Free a [struct@GLib.SList] of things which need [func@GLib.free]ing. */ void vips_slist_free_all(GSList *list) @@ -299,7 +299,7 @@ vips_hash_table_predicate(const char *key, void *value, Pair *pair) /** * vips_hash_table_map: - * @hash: a #GHashTable + * @hash: a [struct@GLib.HashTable] * @fn: (scope call): function to apply to each hash value * @a: user data * @b: user data @@ -339,7 +339,7 @@ vips_iscasepostfix(const char *a, const char *b) } /* Test for string a starts string b. a is a known-good string, b may be - * random data. Use g_str_has_prefix() when both strings are non-NULL and + * random data. Use [func@GLib.str_has_prefix] when both strings are non-NULL and * NULL-terminated. */ gboolean diff --git a/libvips/iofuncs/vector.cpp b/libvips/iofuncs/vector.cpp index a0f92e760c..a98d72174e 100644 --- a/libvips/iofuncs/vector.cpp +++ b/libvips/iofuncs/vector.cpp @@ -133,7 +133,7 @@ vips_vector_get_builtin_targets(void) * vips_vector_get_supported_targets: * * Gets a bitfield of enabled targets that are supported on this CPU. The - * targets returned may change after calling vips_vector_disable_targets(). + * targets returned may change after calling [func@vector_disable_targets]. * * Returns: a bitfield of supported CPU targets. */ diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index cd44d7d1c5..4ae74fc03c 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -115,7 +115,7 @@ * VIPS is a relocatable package, meaning you can move the directory tree you * compiled it to at runtime and it will still be able to find all data files. * This is required for OS X and Windows, but slightly unusual in the Unix - * world. See vips_init() and vips_guess_prefix(). + * world. See [func@init] and [func@guess_prefix]. */ /* Open mode for image write. @@ -144,7 +144,7 @@ vips__open_image_read(const char *filename) { int fd; - /* Try to open read-write, so that calls to vips_image_inplace() will + /* Try to open read-write, so that calls to [method@Image.inplace] will * work. When we later mmap this file, we set read-only, so there * is little danger of scrubbing over files we own. */ @@ -184,7 +184,7 @@ vips__open_image_write(const char *filename, gboolean temp) * * This can fail since not all filesystems support it. In this case, * we open as a regular file and rely on the delete-on-close - * mechanism, see vips_image_delete(). + * mechanism, see [method@Image.delete]. */ if (temp) { char *dirname; @@ -946,7 +946,7 @@ vips__xml_properties_meta(VipsImage *image, } /* Make the xml we write to vips-properties in dzsave, or to TIFF. A simple - * dump of all vips metadata. Free with g_free(). + * dump of all vips metadata. Free with [func@GLib.free]. */ char * vips__xml_properties(VipsImage *image) From c8266c3b8bc2cc69944688b085b05a7d87ebd47e Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 1 Apr 2025 23:35:54 +0200 Subject: [PATCH 106/174] threadset: prevent possible thread oversubscription on Wasm (#4436) * threadset: prevent possible thread oversubscription on Wasm Track the number of threads that haven't reached their entry point to prevent thread oversubscription, which could occur on Wasm. This issue likely did not affect other environments, where thread spawning is usually instant. See: https://github.com/kleisauke/wasm-vips/issues/92. * Improve comment --- libvips/iofuncs/threadset.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libvips/iofuncs/threadset.c b/libvips/iofuncs/threadset.c index 8c221c03f1..40b9409a23 100644 --- a/libvips/iofuncs/threadset.c +++ b/libvips/iofuncs/threadset.c @@ -74,6 +74,10 @@ struct _VipsThreadset { */ VipsSemaphore idle; + /* The number of threads that haven't reached their entry point. + */ + int queue_guard; + /* The current number of (idle-)threads, the highwater mark, * and the max we allow before blocking thread creation. */ @@ -137,6 +141,8 @@ vips_threadset_work(void *pointer) g_async_queue_lock(set->queue); + set->queue_guard--; + for (;;) { /* Pop a task from the queue. If the number of threads is limited, * this will block until a task becomes available. Otherwise, it @@ -238,6 +244,7 @@ vips_threadset_add_thread(VipsThreadset *set) g_thread_unref(thread); set->n_threads++; + set->queue_guard++; set->n_threads_highwater = VIPS_MAX(set->n_threads_highwater, set->n_threads); } @@ -305,9 +312,11 @@ vips_threadset_run(VipsThreadset *set, g_async_queue_lock(set->queue); - /* Create a new thread if there are no waiting threads in the queue. + /* Create or reuse an idle thread if there are at least as many tasks + * in the queue as waiting threads. The guard comparison prevents + * oversubscription by threads that haven't started yet. */ - if (g_async_queue_length_unlocked(set->queue) >= 0) + if (g_async_queue_length_unlocked(set->queue) >= set->queue_guard) if (!vips_threadset_add_thread(set)) { g_async_queue_unlock(set->queue); From fe77c2ea8c772ebb9a9446741453ecc25b179db8 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 2 Apr 2025 15:18:26 +0100 Subject: [PATCH 107/174] update docs in arithmetic --- doc/rename.sed | 9 ++ libvips/arithmetic/abs.c | 7 +- libvips/arithmetic/add.c | 3 +- libvips/arithmetic/avg.c | 7 +- libvips/arithmetic/boolean.c | 137 ++++++++++++---------- libvips/arithmetic/clamp.c | 14 +-- libvips/arithmetic/complex.c | 69 +++++------ libvips/arithmetic/deviate.c | 7 +- libvips/arithmetic/divide.c | 5 +- libvips/arithmetic/find_trim.c | 18 +-- libvips/arithmetic/getpoint.c | 5 +- libvips/arithmetic/hist_find.c | 8 +- libvips/arithmetic/hist_find_indexed.c | 14 +-- libvips/arithmetic/hist_find_ndim.c | 8 +- libvips/arithmetic/hough_circle.c | 12 +- libvips/arithmetic/hough_line.c | 10 +- libvips/arithmetic/invert.c | 5 +- libvips/arithmetic/linear.c | 13 ++- libvips/arithmetic/math.c | 103 ++++++++--------- libvips/arithmetic/math2.c | 92 +++++++-------- libvips/arithmetic/max.c | 22 ++-- libvips/arithmetic/maxpair.c | 3 +- libvips/arithmetic/measure.c | 14 +-- libvips/arithmetic/min.c | 22 ++-- libvips/arithmetic/minpair.c | 3 +- libvips/arithmetic/multiply.c | 3 +- libvips/arithmetic/profile.c | 5 +- libvips/arithmetic/project.c | 5 +- libvips/arithmetic/relational.c | 151 +++++++++++++------------ libvips/arithmetic/remainder.c | 21 ++-- libvips/arithmetic/round.c | 35 +++--- libvips/arithmetic/sign.c | 3 +- libvips/arithmetic/stats.c | 7 +- libvips/arithmetic/subtract.c | 5 +- libvips/arithmetic/sum.c | 3 +- 35 files changed, 449 insertions(+), 399 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index ff2c6341cf..5ba6384c4c 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -332,6 +332,7 @@ s/vips_\(scharr\)()/[method@Image.\1]/g s/vips_\(scRGB2BW\)()/[method@Image.\1]/g s/vips_\(scRGB2sRGB\)()/[method@Image.\1]/g s/vips_\(scRGB2XYZ\)()/[method@Image.\1]/g +s/vips_\(sdf\)()/[ctor@Image.\1]/g s/vips_\(sequential\)()/[method@Image.\1]/g s/vips_\(sharpen\)()/[method@Image.\1]/g s/vips_\(shrinkh\)()/[method@Image.\1]/g @@ -416,6 +417,14 @@ s/#Vips\(ThreadpoolAllocateFn\)/[callback@\1]/g s/#Vips\(ThreadpoolWorkFn\)/[callback@\1]/g s/#Vips\(ThreadpoolProgressFn\)/[callback@\1]/g +s/#VIPS_OPERATION_MATH_\([^ ,.]*\)/[enum@Vips.OperationMath.\1]/g +s/#VIPS_OPERATION_MATH2_\([^ ,.]*\)/[enum@Vips.OperationMath2.\1]/g +s/#VIPS_OPERATION_RELATIONAL_\([^ ,.]*\)/[enum@Vips.OperationRelational.\1]/g +s/#VIPS_OPERATION_BOOLEAN_\([^ ,.]*\)/[enum@Vips.OperationBoolean.\1]/g +s/#VIPS_OPERATION_ROUND_\([^ ,.]*\)/[enum@Vips.OperationRound.\1]/g +s/#VIPS_OPERATION_COMPLEX_\([^ ,.]*\)/[enum@Vips.OperationComplex.\1]/g +s/#VIPS_OPERATION_COMPLEX2_\([^ ,.]*\)/[enum@Vips.OperationComplex2.\1]/g +s/#VIPS_OPERATION_COMPLEXGET_\([^ ,.]*\)/[enum@Vips.OperationComplexget.\1]/g s/#VIPS_OPERATION_\([^ ,.]*\)/[flags@Vips.OperationFlags.\1]/g s/#VIPS_FORMAT_\([^ ,.]*\)/[enum@Vips.BandFormat.\1]/g s/#VIPS_PRECISION_\([^ ,.]*\)/[enum@Vips.Precision.\1]/g diff --git a/libvips/arithmetic/abs.c b/libvips/arithmetic/abs.c index d29f821be3..5a80869291 100644 --- a/libvips/arithmetic/abs.c +++ b/libvips/arithmetic/abs.c @@ -212,8 +212,8 @@ vips_abs_init(VipsAbs *abs) /** * vips_abs: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * * This operation finds the absolute value of an image. It does a copy for @@ -222,7 +222,8 @@ vips_abs_init(VipsAbs *abs) * float types, and calculates modulus for complex * types. * - * See also: vips_sign(). + * ::: seealso + * [method@Image.sign]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/add.c b/libvips/arithmetic/add.c index 604e3d385d..514cfc7f8e 100644 --- a/libvips/arithmetic/add.c +++ b/libvips/arithmetic/add.c @@ -266,7 +266,8 @@ vips_add_init(VipsAdd *add) * In other words, the output type is just large enough to hold the whole * range of possible values. * - * See also: vips_subtract(), vips_linear(). + * ::: seealso + * [method@Image.subtract], [method@Image.linear]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/avg.c b/libvips/arithmetic/avg.c index 49c1dad9fc..dd6d658320 100644 --- a/libvips/arithmetic/avg.c +++ b/libvips/arithmetic/avg.c @@ -246,15 +246,16 @@ vips_avg_init(VipsAvg *avg) /** * vips_avg: (method) - * @in: input #VipsImage + * @in: input [class@Image] * @out: (out): output pixel average * @...: %NULL-terminated list of optional named arguments * * This operation finds the average value in an image. It operates on all - * bands of the input image: use vips_stats() if you need to calculate an + * bands of the input image: use [method@Image.stats] if you need to calculate an * average for each band. For complex images, return the average modulus. * - * See also: vips_stats(), vips_bandmean(), vips_deviate(), vips_rank() + * ::: seealso + * [method@Image.stats], [method@Image.bandmean], [method@Image.deviate], [method@Image.rank] * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/boolean.c b/libvips/arithmetic/boolean.c index 166b6fac29..6c97790b62 100644 --- a/libvips/arithmetic/boolean.c +++ b/libvips/arithmetic/boolean.c @@ -296,9 +296,9 @@ vips_booleanv(VipsImage *left, VipsImage *right, VipsImage **out, /** * vips_boolean: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @boolean: boolean operation to perform * @...: %NULL-terminated list of optional named arguments * @@ -320,7 +320,8 @@ vips_booleanv(VipsImage *left, VipsImage *right, VipsImage **out, * Smallest common format in * arithmetic). * - * See also: vips_boolean_const(). + * ::: seealso + * [method@Image.boolean_const]. * * Returns: 0 on success, -1 on error */ @@ -340,13 +341,13 @@ vips_boolean(VipsImage *left, VipsImage *right, VipsImage **out, /** * vips_andimage: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_AND on a pair of images. See - * vips_boolean(). + * Perform [enum@Vips.OperationBoolean.AND] on a pair of images. See + * [method@Image.boolean]. * * Returns: 0 on success, -1 on error */ @@ -366,13 +367,13 @@ vips_andimage(VipsImage *left, VipsImage *right, VipsImage **out, ...) /** * vips_orimage: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_OR on a pair of images. See - * vips_boolean(). + * Perform [enum@Vips.OperationBoolean.OR] on a pair of images. See + * [method@Image.boolean]. * * Returns: 0 on success, -1 on error */ @@ -392,13 +393,13 @@ vips_orimage(VipsImage *left, VipsImage *right, VipsImage **out, ...) /** * vips_eorimage: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_EOR on a pair of images. See - * vips_boolean(). + * Perform [enum@Vips.OperationBoolean.EOR] on a pair of images. See + * [method@Image.boolean]. * * Returns: 0 on success, -1 on error */ @@ -418,13 +419,13 @@ vips_eorimage(VipsImage *left, VipsImage *right, VipsImage **out, ...) /** * vips_lshift: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_LSHIFT on a pair of images. See - * vips_boolean(). + * Perform [enum@Vips.OperationBoolean.LSHIFT] on a pair of images. See + * [method@Image.boolean]. * * Returns: 0 on success, -1 on error */ @@ -444,13 +445,13 @@ vips_lshift(VipsImage *left, VipsImage *right, VipsImage **out, ...) /** * vips_rshift: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_RSHIFT on a pair of images. See - * vips_boolean(). + * Perform [enum@Vips.OperationBoolean.RSHIFT] on a pair of images. See + * [method@Image.boolean]. * * Returns: 0 on success, -1 on error */ @@ -630,7 +631,8 @@ vips_boolean_constv(VipsImage *in, VipsImage **out, * element and the image only has a single band, the result is a many-band * image where each band corresponds to one array element. * - * See also: vips_boolean(), vips_boolean_const1(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const1]. * * Returns: 0 on success, -1 on error */ @@ -656,10 +658,11 @@ vips_boolean_const(VipsImage *in, VipsImage **out, * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_AND on an image and an array of constants. - * See vips_boolean_const(). + * Perform [enum@Vips.OperationBoolean.AND] on an image and an array of constants. + * See [method@Image.boolean_const]. * - * See also: vips_boolean(), vips_boolean_const1(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const1]. * * Returns: 0 on success, -1 on error */ @@ -686,10 +689,11 @@ vips_andimage_const(VipsImage *in, VipsImage **out, * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_OR on an image and an array of constants. - * See vips_boolean_const(). + * Perform [enum@Vips.OperationBoolean.OR] on an image and an array of constants. + * See [method@Image.boolean_const]. * - * See also: vips_boolean(), vips_boolean_const1(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const1]. * * Returns: 0 on success, -1 on error */ @@ -716,10 +720,11 @@ vips_orimage_const(VipsImage *in, VipsImage **out, * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_EOR on an image and an array of constants. - * See vips_boolean_const(). + * Perform [enum@Vips.OperationBoolean.EOR] on an image and an array of constants. + * See [method@Image.boolean_const]. * - * See also: vips_boolean(), vips_boolean_const1(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const1]. * * Returns: 0 on success, -1 on error */ @@ -746,10 +751,11 @@ vips_eorimage_const(VipsImage *in, VipsImage **out, * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_LSHIFT on an image and an array of constants. - * See vips_boolean_const(). + * Perform [enum@Vips.OperationBoolean.LSHIFT] on an image and an array of constants. + * See [method@Image.boolean_const]. * - * See also: vips_boolean(), vips_boolean_const1(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const1]. * * Returns: 0 on success, -1 on error */ @@ -775,10 +781,11 @@ vips_lshift_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_LSHIFT on an image and an array of constants. - * See vips_boolean_const(). + * Perform [enum@Vips.OperationBoolean.LSHIFT] on an image and an array of constants. + * See [method@Image.boolean_const]. * - * See also: vips_boolean(), vips_boolean_const1(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const1]. * * Returns: 0 on success, -1 on error */ @@ -805,9 +812,10 @@ vips_rshift_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @...: %NULL-terminated list of optional named arguments * * Perform various boolean operations on an image with a single constant. See - * vips_boolean_const(). + * [method@Image.boolean_const]. * - * See also: vips_boolean(), vips_boolean_const(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const]. * * Returns: 0 on success, -1 on error */ @@ -832,10 +840,11 @@ vips_boolean_const1(VipsImage *in, VipsImage **out, * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_AND on an image and a constant. - * See vips_boolean_const1(). + * Perform [enum@Vips.OperationBoolean.AND] on an image and a constant. + * See [method@Image.boolean_const1]. * - * See also: vips_boolean(), vips_boolean_const(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const]. * * Returns: 0 on success, -1 on error */ @@ -860,10 +869,11 @@ vips_andimage_const1(VipsImage *in, VipsImage **out, double c, ...) * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_OR on an image and a constant. - * See vips_boolean_const1(). + * Perform [enum@Vips.OperationBoolean.OR] on an image and a constant. + * See [method@Image.boolean_const1]. * - * See also: vips_boolean(), vips_boolean_const(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const]. * * Returns: 0 on success, -1 on error */ @@ -888,10 +898,11 @@ vips_orimage_const1(VipsImage *in, VipsImage **out, double c, ...) * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_EOR on an image and a constant. - * See vips_boolean_const1(). + * Perform [enum@Vips.OperationBoolean.EOR] on an image and a constant. + * See [method@Image.boolean_const1]. * - * See also: vips_boolean(), vips_boolean_const(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const]. * * Returns: 0 on success, -1 on error */ @@ -916,10 +927,11 @@ vips_eorimage_const1(VipsImage *in, VipsImage **out, double c, ...) * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_LSHIFT on an image and a constant. - * See vips_boolean_const1(). + * Perform [enum@Vips.OperationBoolean.LSHIFT] on an image and a constant. + * See [method@Image.boolean_const1]. * - * See also: vips_boolean(), vips_boolean_const(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const]. * * Returns: 0 on success, -1 on error */ @@ -944,10 +956,11 @@ vips_lshift_const1(VipsImage *in, VipsImage **out, double c, ...) * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_RSHIFT on an image and a constant. - * See vips_boolean_const1(). + * Perform [enum@Vips.OperationBoolean.RSHIFT] on an image and a constant. + * See [method@Image.boolean_const1]. * - * See also: vips_boolean(), vips_boolean_const(). + * ::: seealso + * [method@Image.boolean], [method@Image.boolean_const]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/clamp.c b/libvips/arithmetic/clamp.c index aab866e725..02bb6278ae 100644 --- a/libvips/arithmetic/clamp.c +++ b/libvips/arithmetic/clamp.c @@ -182,20 +182,20 @@ vips_clamp_init(VipsClamp *clamp) /** * vips_clamp: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @min: %gdouble, minimum value - * * @max: %gdouble, maximum value + * ::: note "Optional arguments" + * * @min: %gdouble, minimum value + * * @max: %gdouble, maximum value * * This operation clamps pixel values to a range, by default 0 - 1. * * Use @min and @max to change the range. * - * See also: vips_sign(), vips_abs(), vips_sdf(). + * ::: seealso + * [method@Image.sign], [method@Image.abs], [ctor@Image.sdf]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/complex.c b/libvips/arithmetic/complex.c index c2480ce7a1..c06a0796d0 100644 --- a/libvips/arithmetic/complex.c +++ b/libvips/arithmetic/complex.c @@ -20,7 +20,7 @@ * 19/11/11 * - redo as a class * 21/11/11 - * - add vips_complexget() + * - add [method@Image.complexget] * 29/9/15 * - return 0 for cross-product where one arg is zero */ @@ -276,8 +276,8 @@ vips_complexv(VipsImage *in, VipsImage **out, /** * vips_complex: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @cmplx: complex operation to perform * @...: %NULL-terminated list of optional named arguments * @@ -303,11 +303,11 @@ vips_complex(VipsImage *in, VipsImage **out, VipsOperationComplex cmplx, ...) /** * vips_polar: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_COMPLEX_POLAR on an image. See vips_complex(). + * Perform [enum@Vips.OperationComplex.POLAR] on an image. See [method@Image.complex]. * * Returns: 0 on success, -1 on error */ @@ -326,11 +326,11 @@ vips_polar(VipsImage *in, VipsImage **out, ...) /** * vips_rect: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_COMPLEX_RECT on an image. See vips_complex(). + * Perform [enum@Vips.OperationComplex.RECT] on an image. See [method@Image.complex]. * * Returns: 0 on success, -1 on error */ @@ -349,11 +349,11 @@ vips_rect(VipsImage *in, VipsImage **out, ...) /** * vips_conj: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_COMPLEX_CONJ on an image. See vips_complex(). + * Perform [enum@Vips.OperationComplex.CONJ] on an image. See [method@Image.complex]. * * Returns: 0 on success, -1 on error */ @@ -557,9 +557,9 @@ vips_complex2v(VipsImage *left, VipsImage *right, VipsImage **out, /** * vips_complex2: (method) - * @left: input #VipsImage - * @right: input #VipsImage - * @out: (out): output #VipsImage + * @left: input [class@Image] + * @right: input [class@Image] + * @out: (out): output [class@Image] * @cmplx: complex2 operation to perform * @...: %NULL-terminated list of optional named arguments * @@ -586,13 +586,13 @@ vips_complex2(VipsImage *left, VipsImage *right, VipsImage **out, /** * vips_cross_phase: (method) - * @left: input #VipsImage - * @right: input #VipsImage - * @out: (out): output #VipsImage + * @left: input [class@Image] + * @right: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_COMPLEX2_CROSS_PHASE on an image. - * See vips_complex2(). + * Perform [enum@Vips.OperationComplex2.CROSS_PHASE] on an image. + * See [method@Image.complex2]. * * Returns: 0 on success, -1 on error */ @@ -790,16 +790,16 @@ vips_complexgetv(VipsImage *in, VipsImage **out, /** * vips_complexget: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @get: complex operation to perform * @...: %NULL-terminated list of optional named arguments * * Get components of complex images. * - * The output type is the same as the input type, except #VIPS_FORMAT_COMPLEX - * becomes #VIPS_FORMAT_FLOAT and #VIPS_FORMAT_DPCOMPLEX becomes - * #VIPS_FORMAT_DOUBLE. + * The output type is the same as the input type, except [enum@Vips.BandFormat.COMPLEX] + * becomes [enum@Vips.BandFormat.FLOAT] and [enum@Vips.BandFormat.DPCOMPLEX] becomes + * [enum@Vips.BandFormat.DOUBLE]. * * Returns: 0 on success, -1 on error */ @@ -819,11 +819,11 @@ vips_complexget(VipsImage *in, VipsImage **out, /** * vips_real: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_COMPLEXGET_REAL on an image. See vips_complexget(). + * Perform [enum@Vips.OperationComplexget.REAL] on an image. See [method@Image.complexget]. * * Returns: 0 on success, -1 on error */ @@ -843,11 +843,11 @@ vips_real(VipsImage *in, VipsImage **out, ...) /** * vips_imag: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_COMPLEXGET_IMAG on an image. See vips_complexget(). + * Perform [enum@Vips.OperationComplexget.IMAG] on an image. See [method@Image.complexget]. * * Returns: 0 on success, -1 on error */ @@ -997,8 +997,8 @@ vips_complexform_init(VipsComplexform *complexform) * @...: %NULL-terminated list of optional named arguments * * Compose two real images to make a complex image. If either @left or @right - * are #VIPS_FORMAT_DOUBLE, @out is #VIPS_FORMAT_DPCOMPLEX. Otherwise @out - * is #VIPS_FORMAT_COMPLEX. @left becomes the real component of @out and + * are [enum@Vips.BandFormat.DOUBLE], @out is [enum@Vips.BandFormat.DPCOMPLEX]. Otherwise @out + * is [enum@Vips.BandFormat.COMPLEX]. @left becomes the real component of @out and * @right the imaginary. * * If the number of bands differs, one of the images @@ -1006,7 +1006,8 @@ vips_complexform_init(VipsComplexform *complexform) * one-band image by joining n copies of the one-band image together, and then * the two n-band images are operated upon. * - * See also: vips_complexget(). + * ::: seealso + * [method@Image.complexget]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/deviate.c b/libvips/arithmetic/deviate.c index b5a05dab8c..639c80c16d 100644 --- a/libvips/arithmetic/deviate.c +++ b/libvips/arithmetic/deviate.c @@ -248,17 +248,18 @@ vips_deviate_init(VipsDeviate *deviate) /** * vips_deviate: (method) - * @in: input #VipsImage + * @in: input [class@Image] * @out: (out): output pixel standard deviation * @...: %NULL-terminated list of optional named arguments * * This operation finds the standard deviation of all pixels in @in. It - * operates on all bands of the input image: use vips_stats() if you need + * operates on all bands of the input image: use [method@Image.stats] if you need * to calculate an average for each band. * * Non-complex images only. * - * See also: vips_avg(), vips_stats().. + * ::: seealso + * [method@Image.avg], [method@Image.stats].. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/divide.c b/libvips/arithmetic/divide.c index c2231daa7c..89b73bbb4f 100644 --- a/libvips/arithmetic/divide.c +++ b/libvips/arithmetic/divide.c @@ -243,7 +243,7 @@ vips_divide_init(VipsDivide *divide) * following table is used to determine the output type: * * - * Codestin Search App + * Codestin Search App * * * @@ -299,7 +299,8 @@ vips_divide_init(VipsDivide *divide) * In other words, the output type is just large enough to hold the whole * range of possible values. * - * See also: vips_multiply(), vips_linear(), vips_pow(). + * ::: seealso + * [method@Image.multiply], [method@Image.linear], [method@Image.pow]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/find_trim.c b/libvips/arithmetic/find_trim.c index ba86869f41..af1723cdf9 100644 --- a/libvips/arithmetic/find_trim.c +++ b/libvips/arithmetic/find_trim.c @@ -256,11 +256,10 @@ vips_find_trim_init(VipsFindTrim *find_trim) * @height: (out): output height * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @threshold: %gdouble, background / object threshold - * * @background: #VipsArrayDouble, background colour - * * @line_art: %gboolean, enable line art mode + * ::: note "Optional arguments" + * * @threshold: %gdouble, background / object threshold + * * @background: [struct@ArrayDouble], background colour + * * @line_art: %gboolean, enable line art mode * * Search @in for the bounding box of the non-background area. * @@ -270,12 +269,12 @@ vips_find_trim_init(VipsFindTrim *find_trim) * the absolute difference are calculated from this binary image and searched * for the first row or column in each direction to obtain the bounding box. * - * If the image is entirely background, vips_find_trim() returns @width == 0 + * If the image is entirely background, [method@Image.find_trim] returns @width == 0 * and @height == 0. * * @background defaults to 255, or 65535 for 16-bit images. Set another value, - * or use vips_getpoint() to pick a value from an edge. You'll need to flatten - * before vips_getpoint() to get a correct background value. + * or use [method@Image.getpoint] to pick a value from an edge. You'll need to flatten + * before [method@Image.getpoint] to get a correct background value. * * @threshold defaults to 10. * @@ -286,7 +285,8 @@ vips_find_trim_init(VipsFindTrim *find_trim) * * The image needs to be at least 3x3 pixels in size. * - * See also: vips_getpoint(), vips_extract_area(), vips_smartcrop(). + * ::: seealso + * [method@Image.getpoint], [method@Image.extract_area], [method@Image.smartcrop]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/getpoint.c b/libvips/arithmetic/getpoint.c index 3af098d60a..73ed2b1094 100644 --- a/libvips/arithmetic/getpoint.c +++ b/libvips/arithmetic/getpoint.c @@ -201,13 +201,14 @@ vips_getpoint_init(VipsGetpoint *getpoint) * Reads a single pixel on an image. * * The pixel values are returned in @vector, the length of the - * array in @n. You must free the array with g_free() when you are done with + * array in @n. You must free the array with [func@GLib.free] when you are done with * it. * * The result array has an element for each band. If @unpack_complex is set, * pixels in complex images are returned as double-length arrays. * - * See also: vips_draw_point(). + * ::: seealso + * [method@Image.draw_point]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/arithmetic/hist_find.c b/libvips/arithmetic/hist_find.c index 29fdc420fc..fa1011795e 100644 --- a/libvips/arithmetic/hist_find.c +++ b/libvips/arithmetic/hist_find.c @@ -453,9 +453,8 @@ vips_hist_find_init(VipsHistFind *hist_find) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @band: band to equalise + * ::: note "Optional arguments" + * * @band: band to equalise * * Find the histogram of @in. Find the histogram for band @band (producing a * one-band histogram), or for all bands (producing an n-band histogram) if @@ -464,7 +463,8 @@ vips_hist_find_init(VipsHistFind *hist_find) * char and uchar images are cast to uchar before histogramming, all other * image types are cast to ushort. * - * See also: vips_hist_find_ndim(), vips_hist_find_indexed(). + * ::: seealso + * [method@Image.hist_find_ndim], [method@Image.hist_find_indexed]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/hist_find_indexed.c b/libvips/arithmetic/hist_find_indexed.c index e6436d7294..4d2ef38cb5 100644 --- a/libvips/arithmetic/hist_find_indexed.c +++ b/libvips/arithmetic/hist_find_indexed.c @@ -493,14 +493,13 @@ vips_hist_find_indexed_init(VipsHistFindIndexed *indexed) /** * vips_hist_find_indexed: (method) - * @in: input #VipsImage - * @index: input index #VipsImage + * @in: input [class@Image] + * @index: input index [class@Image] * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @combine: #VipsCombine, combine bins like this + * ::: note "Optional arguments" + * * @combine: #VipsCombine, combine bins like this * * Make a histogram of @in, but use image @index to pick the bins. In other * words, element zero in @out contains the combination of all the pixels in @in @@ -516,10 +515,11 @@ vips_hist_find_indexed_init(VipsHistFindIndexed *indexed) * Normally, bins are summed, but you can use @combine to set other combine * modes. * - * This operation is useful in conjunction with vips_labelregions(). You can + * This operation is useful in conjunction with [method@Image.labelregions]. You can * use it to find the centre of gravity of blobs in an image, for example. * - * See also: vips_hist_find(), vips_labelregions(). + * ::: seealso + * [method@Image.hist_find], [method@Image.labelregions]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/hist_find_ndim.c b/libvips/arithmetic/hist_find_ndim.c index 4e8838f9fc..d403477f23 100644 --- a/libvips/arithmetic/hist_find_ndim.c +++ b/libvips/arithmetic/hist_find_ndim.c @@ -335,9 +335,8 @@ vips_hist_find_ndim_init(VipsHistFindNDim *ndim) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @bins: number of bins to make on each axis + * ::: note "Optional arguments" + * * @bins: number of bins to make on each axis * * Make a one, two or three dimensional histogram of a 1, 2 or * 3 band image. Divide each axis into @bins bins .. ie. @@ -347,7 +346,8 @@ vips_hist_find_ndim_init(VipsHistFindNDim *ndim) * char and uchar images are cast to uchar before histogramming, all other * image types are cast to ushort. * - * See also: vips_hist_find(), vips_hist_find_indexed(). + * ::: seealso + * [method@Image.hist_find], [method@Image.hist_find_indexed]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/hough_circle.c b/libvips/arithmetic/hough_circle.c index 73032b355c..8287eebdbb 100644 --- a/libvips/arithmetic/hough_circle.c +++ b/libvips/arithmetic/hough_circle.c @@ -265,11 +265,10 @@ vips_hough_circle_init(VipsHoughCircle *hough_circle) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @scale: scale down dimensions by this much - * * @min_radius: smallest radius to search for - * * @max_radius: largest radius to search for + * ::: note "Optional arguments" + * * @scale: scale down dimensions by this much + * * @min_radius: smallest radius to search for + * * @max_radius: largest radius to search for * * Find the circular Hough transform of an image. @in must be one band, with * non-zero pixels for image edges. @out is three-band, with the third channel @@ -287,7 +286,8 @@ vips_hough_circle_init(VipsHoughCircle *hough_circle) * @in, and reduce the number of radii tested (and hence the number of bands * int @out) by a factor of three as well. * - * See also: vips_hough_line(). + * ::: seealso + * [method@Image.hough_line]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/hough_line.c b/libvips/arithmetic/hough_line.c index 01e82c20cd..ec14bfa251 100644 --- a/libvips/arithmetic/hough_line.c +++ b/libvips/arithmetic/hough_line.c @@ -171,10 +171,9 @@ vips_hough_line_init(VipsHoughLine *hough_line) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @width: horizontal size of parameter space - * * @height: vertical size of parameter space + * ::: note "Optional arguments" + * * @width: horizontal size of parameter space + * * @height: vertical size of parameter space * * Find the line Hough transform for @in. @in must have one band. @out has one * band, with pixels being the number of votes for that line. The X dimension @@ -184,7 +183,8 @@ vips_hough_line_init(VipsHoughLine *hough_line) * Use @width @height to set the size of the parameter space image (@out), * that is, how accurate the line determination should be. * - * See also: vips_hough_circle(). + * ::: seealso + * [method@Image.hough_circle]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/invert.c b/libvips/arithmetic/invert.c index 577c9200ba..8e12df6481 100644 --- a/libvips/arithmetic/invert.c +++ b/libvips/arithmetic/invert.c @@ -197,9 +197,10 @@ vips_invert_init(VipsInvert *invert) * @in) for uchar. For signed and float formats, this operation calculates (-1 * @in). * - * For complex images, only the real part is inverted. See also vips_conj(). + * For complex images, only the real part is inverted. See also [method@Image.conj]. * - * See also: vips_linear(). + * ::: seealso + * [method@Image.linear]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/linear.c b/libvips/arithmetic/linear.c index b438d62eae..33c4a7924e 100644 --- a/libvips/arithmetic/linear.c +++ b/libvips/arithmetic/linear.c @@ -505,9 +505,8 @@ vips_linearv(VipsImage *in, VipsImage **out, * @n: length of constant arrays * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @uchar: output uchar pixels + * ::: note "Optional arguments" + * * @uchar: output uchar pixels * * Pass an image through a linear transform, ie. (@out = @in * @a + @b). Output * is float for integer input, double for double input, complex for @@ -521,7 +520,8 @@ vips_linearv(VipsImage *in, VipsImage **out, * element and the image only has a single band, the result is a many-band * image where each band corresponds to one array element. * - * See also: vips_linear1(), vips_add(). + * ::: seealso + * [method@Image.linear1], [method@Image.add]. * * Returns: 0 on success, -1 on error */ @@ -551,9 +551,10 @@ vips_linear(VipsImage *in, VipsImage **out, * * * @uchar: output uchar pixels * - * Run vips_linear() with a single constant. + * Run [method@Image.linear] with a single constant. * - * See also: vips_linear(). + * ::: seealso + * [method@Image.linear]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/math.c b/libvips/arithmetic/math.c index 1ac0f7e6ac..8dcea0dda7 100644 --- a/libvips/arithmetic/math.c +++ b/libvips/arithmetic/math.c @@ -278,8 +278,8 @@ vips_mathv(VipsImage *in, VipsImage **out, VipsOperationMath math, va_list ap) /** * vips_math: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @math: math operation to perform * @...: %NULL-terminated list of optional named arguments * @@ -290,7 +290,8 @@ vips_mathv(VipsImage *in, VipsImage **out, VipsOperationMath math, va_list ap) * * Non-complex images only. * - * See also: vips_math2(). + * ::: seealso + * [method@Image.math2]. * * Returns: 0 on success, -1 on error */ @@ -309,11 +310,11 @@ vips_math(VipsImage *in, VipsImage **out, VipsOperationMath math, ...) /** * vips_sin: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_SIN on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.SIN] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -332,11 +333,11 @@ vips_sin(VipsImage *in, VipsImage **out, ...) /** * vips_cos: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_COS on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.COS] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -355,11 +356,11 @@ vips_cos(VipsImage *in, VipsImage **out, ...) /** * vips_tan: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_TAN on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.TAN] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -378,11 +379,11 @@ vips_tan(VipsImage *in, VipsImage **out, ...) /** * vips_asin: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_ASIN on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.ASIN] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -401,11 +402,11 @@ vips_asin(VipsImage *in, VipsImage **out, ...) /** * vips_acos: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_ACOS on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.ACOS] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -424,11 +425,11 @@ vips_acos(VipsImage *in, VipsImage **out, ...) /** * vips_atan: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_ATAN on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.ATAN] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -447,11 +448,11 @@ vips_atan(VipsImage *in, VipsImage **out, ...) /** * vips_sinh: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_SINH on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.SINH] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -470,11 +471,11 @@ vips_sinh(VipsImage *in, VipsImage **out, ...) /** * vips_cosh: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_COSH on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.COSH] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -493,11 +494,11 @@ vips_cosh(VipsImage *in, VipsImage **out, ...) /** * vips_tanh: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_TANH on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.TANH] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -516,11 +517,11 @@ vips_tanh(VipsImage *in, VipsImage **out, ...) /** * vips_asinh: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_ASINH on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.ASINH] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -539,11 +540,11 @@ vips_asinh(VipsImage *in, VipsImage **out, ...) /** * vips_acosh: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_ACOSH on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.ACOSH] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -562,11 +563,11 @@ vips_acosh(VipsImage *in, VipsImage **out, ...) /** * vips_atanh: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_ATANH on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.ATANH] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -585,11 +586,11 @@ vips_atanh(VipsImage *in, VipsImage **out, ...) /** * vips_log: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_LOG on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.LOG] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -608,11 +609,11 @@ vips_log(VipsImage *in, VipsImage **out, ...) /** * vips_log10: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_LOG10 on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.LOG10] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -631,11 +632,11 @@ vips_log10(VipsImage *in, VipsImage **out, ...) /** * vips_exp: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_EXP on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.EXP] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -654,11 +655,11 @@ vips_exp(VipsImage *in, VipsImage **out, ...) /** * vips_exp10: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH_EXP10 on an image. See vips_math(). + * Perform [enum@Vips.OperationMath.EXP10] on an image. See [method@Image.math]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/math2.c b/libvips/arithmetic/math2.c index 8b29138779..5aade17a97 100644 --- a/libvips/arithmetic/math2.c +++ b/libvips/arithmetic/math2.c @@ -259,9 +259,9 @@ vips_math2v(VipsImage *left, VipsImage *right, VipsImage **out, /** * vips_math2: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @math2: math operation to perform * @...: %NULL-terminated list of optional named arguments * @@ -286,7 +286,8 @@ vips_math2v(VipsImage *left, VipsImage *right, VipsImage **out, * arithmetic), and that format is the * result type. * - * See also: vips_math2_const(). + * ::: seealso + * [method@Image.math2_const]. * * Returns: 0 on success, -1 on error */ @@ -306,13 +307,13 @@ vips_math2(VipsImage *left, VipsImage *right, VipsImage **out, /** * vips_pow: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH2_POW on a pair of images. See - * vips_math2(). + * Perform [enum@Vips.OperationMath2.POW] on a pair of images. See + * [method@Image.math2]. * * Returns: 0 on success, -1 on error */ @@ -331,13 +332,13 @@ vips_pow(VipsImage *left, VipsImage *right, VipsImage **out, ...) /** * vips_wop: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH2_WOP on a pair of images. See - * vips_math2(). + * Perform [enum@Vips.OperationMath2.WOP] on a pair of images. See + * [method@Image.math2]. * * Returns: 0 on success, -1 on error */ @@ -356,13 +357,13 @@ vips_wop(VipsImage *left, VipsImage *right, VipsImage **out, ...) /** * vips_atan2: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH2_ATAN2 on a pair of images. See - * vips_math2(). + * Perform [enum@Vips.OperationMath2.ATAN2] on a pair of images. See + * [method@Image.math2]. * * Returns: 0 on success, -1 on error */ @@ -526,7 +527,8 @@ vips_math2_constv(VipsImage *in, VipsImage **out, * element and the image only has a single band, the result is a many-band * image where each band corresponds to one array element. * - * See also: vips_math2(), vips_math(). + * ::: seealso + * [method@Image.math2], [method@Image.math]. * * Returns: 0 on success, -1 on error */ @@ -546,14 +548,14 @@ vips_math2_const(VipsImage *in, VipsImage **out, /** * vips_pow_const: (method) - * @in: left-hand input #VipsImage - * @out: (out): output #VipsImage + * @in: left-hand input [class@Image] + * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH2_POW on an image and a constant. See - * vips_math2_const(). + * Perform [enum@Vips.OperationMath2.POW] on an image and a constant. See + * [method@Image.math2_const]. * * Returns: 0 on success, -1 on error */ @@ -573,14 +575,14 @@ vips_pow_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) /** * vips_wop_const: (method) - * @in: left-hand input #VipsImage - * @out: (out): output #VipsImage + * @in: left-hand input [class@Image] + * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH2_WOP on an image and a constant. See - * vips_math2_const(). + * Perform [enum@Vips.OperationMath2.WOP] on an image and a constant. See + * [method@Image.math2_const]. * * Returns: 0 on success, -1 on error */ @@ -600,14 +602,14 @@ vips_wop_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) /** * vips_atan2_const: (method) - * @in: left-hand input #VipsImage - * @out: (out): output #VipsImage + * @in: left-hand input [class@Image] + * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH2_ATAN2 on an image and a constant. See - * vips_math2_const(). + * Perform [enum@Vips.OperationMath2.ATAN2] on an image and a constant. See + * [method@Image.math2_const]. * * Returns: 0 on success, -1 on error */ @@ -634,7 +636,7 @@ vips_atan2_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @...: %NULL-terminated list of optional named arguments * * This operation calculates various 2-ary maths operations on an image and - * a constant. See vips_math2_const(). + * a constant. See [method@Image.math2_const]. * * Returns: 0 on success, -1 on error */ @@ -654,13 +656,13 @@ vips_math2_const1(VipsImage *in, VipsImage **out, /** * vips_pow_const1: (method) - * @in: left-hand input #VipsImage - * @out: (out): output #VipsImage + * @in: left-hand input [class@Image] + * @out: (out): output [class@Image] * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH2_POW on an image and a constant. See - * vips_math2_const(). + * Perform [enum@Vips.OperationMath2.POW] on an image and a constant. See + * [method@Image.math2_const]. * * Returns: 0 on success, -1 on error */ @@ -680,13 +682,13 @@ vips_pow_const1(VipsImage *in, VipsImage **out, double c, ...) /** * vips_wop_const1: (method) - * @in: left-hand input #VipsImage - * @out: (out): output #VipsImage + * @in: left-hand input [class@Image] + * @out: (out): output [class@Image] * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH2_WOP on an image and a constant. See - * vips_math2_const(). + * Perform [enum@Vips.OperationMath2.WOP] on an image and a constant. See + * [method@Image.math2_const]. * * Returns: 0 on success, -1 on error */ @@ -706,13 +708,13 @@ vips_wop_const1(VipsImage *in, VipsImage **out, double c, ...) /** * vips_atan2_const1: (method) - * @in: left-hand input #VipsImage - * @out: (out): output #VipsImage + * @in: left-hand input [class@Image] + * @out: (out): output [class@Image] * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_MATH2_ATAN2 on an image and a constant. See - * vips_math2_const(). + * Perform [enum@Vips.OperationMath2.ATAN2] on an image and a constant. See + * [method@Image.math2_const]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/max.c b/libvips/arithmetic/max.c index bebb749b98..c4c436c1c7 100644 --- a/libvips/arithmetic/max.c +++ b/libvips/arithmetic/max.c @@ -506,18 +506,17 @@ vips_max_init(VipsMax *max) /** * vips_max: (method) - * @in: input #VipsImage + * @in: input [class@Image] * @out: (out): output pixel maximum * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @x: horizontal position of maximum - * * @y: vertical position of maximum - * * @size: number of maxima to find - * * @out_array: return array of maximum values - * * @x_array: corresponding horizontal positions - * * @y_array: corresponding vertical positions + * ::: note "Optional arguments" + * * @x: horizontal position of maximum + * * @y: vertical position of maximum + * * @size: number of maxima to find + * * @out_array: return array of maximum values + * * @x_array: corresponding horizontal positions + * * @y_array: corresponding vertical positions * * This operation finds the maximum value in an image. * @@ -527,7 +526,7 @@ vips_max_init(VipsMax *max) * Equal values will be sorted by y then x. * * It operates on all - * bands of the input image: use vips_stats() if you need to find an + * bands of the input image: use [method@Image.stats] if you need to find an * maximum for each band. * * For complex images, this operation finds the maximum modulus. @@ -540,7 +539,8 @@ vips_max_init(VipsMax *max) * If there are more than @size maxima, the maxima returned will be a random * selection of the maxima in the image. * - * See also: vips_min(), vips_stats(). + * ::: seealso + * [method@Image.min], [method@Image.stats]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/maxpair.c b/libvips/arithmetic/maxpair.c index 26212b9904..e6492c7ed4 100644 --- a/libvips/arithmetic/maxpair.c +++ b/libvips/arithmetic/maxpair.c @@ -169,7 +169,8 @@ vips_maxpair_init(VipsMaxpair *maxpair) * * For each pixel, pick the maximum of a pair of images. * - * See also: vips_minpair(). + * ::: seealso + * [method@Image.minpair]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/measure.c b/libvips/arithmetic/measure.c index 886bd98de7..7d81687c2b 100644 --- a/libvips/arithmetic/measure.c +++ b/libvips/arithmetic/measure.c @@ -259,12 +259,11 @@ vips_measure_init(VipsMeasure *measure) * @v: patches down chart * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @left: area of image containing chart - * * @top: area of image containing chart - * * @width: area of image containing chart - * * @height: area of image containing chart + * ::: note "Optional arguments" + * * @left: area of image containing chart + * * @top: area of image containing chart + * * @width: area of image containing chart + * * @height: area of image containing chart * * Analyse a grid of colour patches, producing an array of patch averages. * The mask has a row for each measured patch and a column for each image @@ -276,7 +275,8 @@ vips_measure_init(VipsMeasure *measure) * @width, @height arguments to indicate the * position of the chart. * - * See also: vips_avg(), vips_deviate(). + * ::: seealso + * [method@Image.avg], [method@Image.deviate]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/min.c b/libvips/arithmetic/min.c index e6e3e7d95f..8aee643744 100644 --- a/libvips/arithmetic/min.c +++ b/libvips/arithmetic/min.c @@ -506,18 +506,17 @@ vips_min_init(VipsMin *min) /** * vips_min: (method) - * @in: input #VipsImage + * @in: input [class@Image] * @out: (out): output pixel minimum * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @x: horizontal position of minimum - * * @y: vertical position of minimum - * * @size: number of minima to find - * * @out_array: return array of minimum values - * * @x_array: corresponding horizontal positions - * * @y_array: corresponding vertical positions + * ::: note "Optional arguments" + * * @x: horizontal position of minimum + * * @y: vertical position of minimum + * * @size: number of minima to find + * * @out_array: return array of minimum values + * * @x_array: corresponding horizontal positions + * * @y_array: corresponding vertical positions * * This operation finds the minimum value in an image. * @@ -527,7 +526,7 @@ vips_min_init(VipsMin *min) * Equal values will be sorted by y then x. * * It operates on all - * bands of the input image: use vips_stats() if you need to find an + * bands of the input image: use [method@Image.stats] if you need to find an * minimum for each band. * * For complex images, this operation finds the minimum modulus. @@ -541,7 +540,8 @@ vips_min_init(VipsMin *min) * If there are more than @size minima, the minima returned will be a random * selection of the minima in the image. * - * See also: vips_min(), vips_stats(). + * ::: seealso + * [method@Image.min], [method@Image.stats]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/minpair.c b/libvips/arithmetic/minpair.c index ae5ff17e03..adaec5830b 100644 --- a/libvips/arithmetic/minpair.c +++ b/libvips/arithmetic/minpair.c @@ -169,7 +169,8 @@ vips_minpair_init(VipsMinpair *minpair) * * For each pixel, pick the minimum of a pair of images. * - * See also: vips_minpair(). + * ::: seealso + * [method@Image.minpair]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/multiply.c b/libvips/arithmetic/multiply.c index 4f0fe1967c..5a296661e0 100644 --- a/libvips/arithmetic/multiply.c +++ b/libvips/arithmetic/multiply.c @@ -283,7 +283,8 @@ vips_multiply_init(VipsMultiply *multiply) * In other words, the output type is just large enough to hold the whole * range of possible values. * - * See also: vips_add(), vips_linear(). + * ::: seealso + * [method@Image.add], [method@Image.linear]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/profile.c b/libvips/arithmetic/profile.c index 91d837708f..940f419a82 100644 --- a/libvips/arithmetic/profile.c +++ b/libvips/arithmetic/profile.c @@ -322,12 +322,13 @@ vips_profile_init(VipsProfile *profile) * @rows: (out): distances from left edge * @...: %NULL-terminated list of optional named arguments * - * vips_profile() searches inward from the edge of @in and finds the + * [method@Image.profile] searches inward from the edge of @in and finds the * first non-zero pixel. Pixels in @columns have the distance from the top edge * to the first non-zero pixel in that column, @rows has the distance from the * left edge to the first non-zero pixel in that row. * - * See also: vips_project(), vips_hist_find(). + * ::: seealso + * [method@Image.project], [method@Image.hist_find]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/project.c b/libvips/arithmetic/project.c index 9585cb0426..47f7f38cd7 100644 --- a/libvips/arithmetic/project.c +++ b/libvips/arithmetic/project.c @@ -6,7 +6,7 @@ * - gtkdoc * - small celanups * 11/9/13 - * - redo as a class, from vips_hist_find() + * - redo as a class, from [method@Image.hist_find] */ /* @@ -359,7 +359,8 @@ vips_project_init(VipsProject *project) * * Non-complex images only. * - * See also: vips_hist_find(), vips_profile(). + * ::: seealso + * [method@Image.hist_find], [method@Image.profile]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/relational.c b/libvips/arithmetic/relational.c index c7e4f76675..ac2eb46e91 100644 --- a/libvips/arithmetic/relational.c +++ b/libvips/arithmetic/relational.c @@ -266,9 +266,9 @@ vips_relationalv(VipsImage *left, VipsImage *right, VipsImage **out, /** * vips_relational: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @relational: relational operation to perform * @...: %NULL-terminated list of optional named arguments * @@ -291,10 +291,11 @@ vips_relationalv(VipsImage *left, VipsImage *right, VipsImage **out, * arithmetic). * * To decide if pixels match exactly, that is have the same value in every - * band, use vips_bandbool() after this operation to AND or OR image bands + * band, use [method@Image.bandbool] after this operation to AND or OR image bands * together. * - * See also: vips_boolean(), vips_bandbool(), vips_relational_const(). + * ::: seealso + * [method@Image.boolean], [method@Image.bandbool], [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -314,13 +315,13 @@ vips_relational(VipsImage *left, VipsImage *right, VipsImage **out, /** * vips_equal: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_EQUAL on a pair of images. See - * vips_relational(). + * Perform [enum@Vips.OperationRelational.EQUAL] on a pair of images. See + * [method@Image.relational]. * * Returns: 0 on success, -1 on error */ @@ -340,13 +341,13 @@ vips_equal(VipsImage *left, VipsImage *right, VipsImage **out, ...) /** * vips_notequal: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_NOTEQ on a pair of images. See - * vips_relational(). + * Perform [enum@Vips.OperationRelational.NOTEQ] on a pair of images. See + * [method@Image.relational]. * * Returns: 0 on success, -1 on error */ @@ -366,13 +367,13 @@ vips_notequal(VipsImage *left, VipsImage *right, VipsImage **out, ...) /** * vips_more: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_MORE on a pair of images. See - * vips_relational(). + * Perform [enum@Vips.OperationRelational.MORE] on a pair of images. See + * [method@Image.relational]. * * Returns: 0 on success, -1 on error */ @@ -392,13 +393,13 @@ vips_more(VipsImage *left, VipsImage *right, VipsImage **out, ...) /** * vips_moreeq: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_MOREEQ on a pair of images. See - * vips_relational(). + * Perform [enum@Vips.OperationRelational.MOREEQ] on a pair of images. See + * [method@Image.relational]. * * Returns: 0 on success, -1 on error */ @@ -418,13 +419,13 @@ vips_moreeq(VipsImage *left, VipsImage *right, VipsImage **out, ...) /** * vips_less: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_LESS on a pair of images. See - * vips_relational(). + * Perform [enum@Vips.OperationRelational.LESS] on a pair of images. See + * [method@Image.relational]. * * Returns: 0 on success, -1 on error */ @@ -444,13 +445,13 @@ vips_less(VipsImage *left, VipsImage *right, VipsImage **out, ...) /** * vips_lesseq: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_LESSEQ on a pair of images. See - * vips_relational(). + * Perform [enum@Vips.OperationRelational.LESSEQ] on a pair of images. See + * [method@Image.relational]. * * Returns: 0 on success, -1 on error */ @@ -664,7 +665,8 @@ vips_relational_constv(VipsImage *in, VipsImage **out, * element and the image only has a single band, the result is a many-band * image where each band corresponds to one array element. * - * See also: vips_boolean(), vips_relational(). + * ::: seealso + * [method@Image.boolean], [method@Image.relational]. * * Returns: 0 on success, -1 on error */ @@ -684,14 +686,14 @@ vips_relational_const(VipsImage *in, VipsImage **out, /** * vips_equal_const: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_EQUAL on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.EQUAL] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -711,14 +713,14 @@ vips_equal_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) /** * vips_notequal_const: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_NOTEQ on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.NOTEQ] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -739,14 +741,14 @@ vips_notequal_const(VipsImage *in, VipsImage **out, /** * vips_less_const: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_LESS on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.LESS] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -766,14 +768,14 @@ vips_less_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) /** * vips_lesseq_const: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_LESSEQ on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.LESSEQ] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -793,14 +795,14 @@ vips_lesseq_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) /** * vips_more_const: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_MORE on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.MORE] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -820,14 +822,14 @@ vips_more_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) /** * vips_moreeq_const: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_MOREEQ on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.MOREEQ] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -854,9 +856,10 @@ vips_moreeq_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @...: %NULL-terminated list of optional named arguments * * Perform various relational operations on an image and a constant. See - * vips_relational_const(). + * [method@Image.relational_const]. * - * See also: vips_boolean(), vips_relational(). + * ::: seealso + * [method@Image.boolean], [method@Image.relational]. * * Returns: 0 on success, -1 on error */ @@ -881,8 +884,8 @@ vips_relational_const1(VipsImage *in, VipsImage **out, * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_EQUAL on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.EQUAL] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -907,8 +910,8 @@ vips_equal_const1(VipsImage *in, VipsImage **out, double c, ...) * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_NOTEQ on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.NOTEQ] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -933,8 +936,8 @@ vips_notequal_const1(VipsImage *in, VipsImage **out, double c, ...) * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_LESS on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.LESS] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -959,8 +962,8 @@ vips_less_const1(VipsImage *in, VipsImage **out, double c, ...) * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_LESSEQ on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.LESSEQ] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -985,8 +988,8 @@ vips_lesseq_const1(VipsImage *in, VipsImage **out, double c, ...) * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_MORE on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.MORE] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ @@ -1011,8 +1014,8 @@ vips_more_const1(VipsImage *in, VipsImage **out, double c, ...) * @c: constant * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_RELATIONAL_MOREEQ on an image and a constant. See - * vips_relational_const(). + * Perform [enum@Vips.OperationRelational.MOREEQ] on an image and a constant. See + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/remainder.c b/libvips/arithmetic/remainder.c index 45f91d8f3d..3eed597b19 100644 --- a/libvips/arithmetic/remainder.c +++ b/libvips/arithmetic/remainder.c @@ -205,14 +205,14 @@ vips_remainder_init(VipsRemainder *remainder) /** * vips_remainder: (method) - * @left: left-hand input #VipsImage - * @right: right-hand input #VipsImage - * @out: (out): output #VipsImage + * @left: left-hand input [class@Image] + * @right: right-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * * This operation calculates @left % @right (remainder after integer division) * and writes the result to @out. The images may have any - * non-complex format. For float formats, vips_remainder() calculates @in1 - + * non-complex format. For float formats, [method@Image.remainder] calculates @in1 - * @in2 * floor (@in1 / @in2). * * If the images differ in size, the smaller image is enlarged to match the @@ -228,7 +228,8 @@ vips_remainder_init(VipsRemainder *remainder) * arithmetic), and that format is the * result type. * - * See also: vips_remainder_const(), vips_divide(), vips_round(). + * ::: seealso + * [method@Image.remainder_const], [method@Image.divide], [method@Image.round]. * * Returns: 0 on success, -1 on error */ @@ -396,7 +397,7 @@ vips_remainder_constv(VipsImage *in, VipsImage **out, * array of constants) * and writes the result to @out. * The image may have any - * non-complex format. For float formats, vips_remainder_const() calculates + * non-complex format. For float formats, [method@Image.remainder_const] calculates * @in - @c * floor (@in / @c). * * If the array of constants has just one element, that constant is used for @@ -406,7 +407,8 @@ vips_remainder_constv(VipsImage *in, VipsImage **out, * element and the image only has a single band, the result is a many-band * image where each band corresponds to one array element. * - * See also: vips_remainder(), vips_divide(), vips_round(). + * ::: seealso + * [method@Image.remainder], [method@Image.divide], [method@Image.round]. * * Returns: 0 on success, -1 on error */ @@ -435,7 +437,7 @@ vips_remainder_const(VipsImage *in, VipsImage **out, * constant) * and writes the result to @out. * The image may have any - * non-complex format. For float formats, vips_remainder_const() calculates + * non-complex format. For float formats, [method@Image.remainder_const] calculates * @in - @c * floor (@in / @c). * * If the array of constants has just one element, that constant is used for @@ -445,7 +447,8 @@ vips_remainder_const(VipsImage *in, VipsImage **out, * element and the image only has a single band, the result is a many-band * image where each band corresponds to one array element. * - * See also: vips_remainder(), vips_divide(), vips_round(). + * ::: seealso + * [method@Image.remainder], [method@Image.divide], [method@Image.round]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/round.c b/libvips/arithmetic/round.c index 4f8bf7adfe..8b05f06688 100644 --- a/libvips/arithmetic/round.c +++ b/libvips/arithmetic/round.c @@ -71,7 +71,7 @@ vips_round_build(VipsObject *object) { VipsUnary *unary = (VipsUnary *) object; - /* Is this one of the int types? Degenerate to vips_copy() if it + /* Is this one of the int types? Degenerate to [method@Image.copy] if it * is. */ if (unary->in && @@ -199,9 +199,9 @@ vips_roundv(VipsImage *in, VipsImage **out, /** * vips_round: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage - * @round: #VipsOperationRound rounding operation to perform + * @in: input [class@Image] + * @out: (out): output [class@Image] + * @round: [class@Operation]Round rounding operation to perform * @...: %NULL-terminated list of optional named arguments * * Round to an integral value. @@ -212,7 +212,8 @@ vips_roundv(VipsImage *in, VipsImage **out, * The format of @out is always the same as @in, so you may wish to cast to an * integer format afterwards. * - * See also: vips_cast() + * ::: seealso + * [method@Image.cast] * * Returns: 0 on success, -1 on error */ @@ -231,12 +232,12 @@ vips_round(VipsImage *in, VipsImage **out, VipsOperationRound round, ...) /** * vips_floor: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Round to an integral value with #VIPS_OPERATION_ROUND_FLOOR. See - * vips_round(). + * Round to an integral value with [enum@Vips.OperationRound.FLOOR]. See + * [method@Image.round]. * * Returns: 0 on success, -1 on error */ @@ -255,12 +256,12 @@ vips_floor(VipsImage *in, VipsImage **out, ...) /** * vips_ceil: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Round to an integral value with #VIPS_OPERATION_ROUND_CEIL. See - * vips_round(). + * Round to an integral value with [enum@Vips.OperationRound.CEIL]. See + * [method@Image.round]. * * Returns: 0 on success, -1 on error */ @@ -279,12 +280,12 @@ vips_ceil(VipsImage *in, VipsImage **out, ...) /** * vips_rint: (method) - * @in: input #VipsImage - * @out: (out): output #VipsImage + * @in: input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Round to an integral value with #VIPS_OPERATION_ROUND_RINT. See - * vips_round(). + * Round to an integral value with [enum@Vips.OperationRound.RINT]. See + * [method@Image.round]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/sign.c b/libvips/arithmetic/sign.c index 47de9d2d7b..564fde6f56 100644 --- a/libvips/arithmetic/sign.c +++ b/libvips/arithmetic/sign.c @@ -194,7 +194,8 @@ vips_sign_init(VipsSign *sign) * zero and positive pixels. For complex images, it returns a * complex normalised to length 1. * - * See also: vips_abs(). + * ::: seealso + * [method@Image.abs]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/stats.c b/libvips/arithmetic/stats.c index 0c8428c3a0..c45f609042 100644 --- a/libvips/arithmetic/stats.c +++ b/libvips/arithmetic/stats.c @@ -457,12 +457,12 @@ vips_stats_init(VipsStats *stats) * @...: %NULL-terminated list of optional named arguments * * Find many image statistics in a single pass through the data. @out is a - * one-band #VIPS_FORMAT_DOUBLE image of at least 10 columns by n + 1 + * one-band [enum@Vips.BandFormat.DOUBLE] image of at least 10 columns by n + 1 * (where n is number of bands in image @in) * rows. Columns are statistics, and are, in order: minimum, maximum, sum, * sum of squares, mean, standard deviation, x coordinate of minimum, y * coordinate of minimum, x coordinate of maximum, y coordinate of maximum. - * Later versions of vips_stats() may add more columns. + * Later versions of [method@Image.stats] may add more columns. * * Row 0 has statistics for all * bands together, row 1 has stats for band 1, and so on. @@ -470,7 +470,8 @@ vips_stats_init(VipsStats *stats) * If there is more than one maxima or minima, one of them will be chosen at * random. * - * See also: vips_avg(), vips_min(). + * ::: seealso + * [method@Image.avg], [method@Image.min]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/subtract.c b/libvips/arithmetic/subtract.c index 063f7d4468..20456d4941 100644 --- a/libvips/arithmetic/subtract.c +++ b/libvips/arithmetic/subtract.c @@ -157,7 +157,7 @@ vips_subtract_buffer(VipsArithmetic *arithmetic, #define DX VIPS_FORMAT_DPCOMPLEX /* Type promotion for subtraction. Sign and value preserving. Make sure these - * match the case statement in vips_subtract_buffer() above. + * match the case statement in [func@subtract_buffer] above. */ static const VipsBandFormat vips_subtract_format_table[10] = { /* Band format: UC C US S UI I F X D DX */ @@ -262,7 +262,8 @@ vips_subtract_init(VipsSubtract *subtract) * In other words, the output type is just large enough to hold the whole * range of possible values. * - * See also: vips_add(), vips_linear(). + * ::: seealso + * [method@Image.add], [method@Image.linear]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/arithmetic/sum.c b/libvips/arithmetic/sum.c index cb41e08297..be772af81a 100644 --- a/libvips/arithmetic/sum.c +++ b/libvips/arithmetic/sum.c @@ -250,7 +250,8 @@ vips_sumv(VipsImage **in, VipsImage **out, int n, va_list ap) * In other words, the output type is just large enough to hold the whole * range of possible values. * - * See also: vips_add(). + * ::: seealso + * [method@Image.add]. * * Returns: 0 on success, -1 on error */ From edc20cabf1475a0da235fd84b475399f29ae9669 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 6 Apr 2025 12:58:06 +0200 Subject: [PATCH 108/174] doc: move sections to separate files (batch 1/2) (#4449) * doc: fix links and code highlighting in developer-checklist.md * doc: revise H2 headers * doc: drop the video SECTION * doc: move the draw SECTION * doc: move the create SECTION * doc: move the colour SECTION * doc: fix formatting in libvips-colour.md * doc: move the basic and type SECTION * doc: move the vips SECTION * doc: move the morphology SECTION * doc: move the resample SECTION * CI: ensure docs option is tested on Linux * doc: add script to check if all symbols are listed * doc: add missing symbols caught by 27016bb --- .github/workflows/ci.yml | 9 +- doc/check-sections.py | 104 +++++++++++++++ doc/developer-checklist.md | 7 +- doc/how-it-opens-files.md | 2 +- doc/libvips-arithmetic.md | 6 +- doc/libvips-basic.md | 82 ++++++++++++ doc/libvips-colour.md | 190 ++++++++++++++++++++++++++++ doc/libvips-create.md | 44 +++++++ doc/libvips-draw.md | 50 ++++++++ doc/libvips-header.md | 8 +- doc/libvips-morphology.md | 62 +++++++++ doc/libvips-resample.md | 82 ++++++++++++ doc/libvips-vips.md | 46 +++++++ doc/meson.build | 36 ++++-- doc/vips.toml.in | 7 + libvips/colour/colour.c | 107 ---------------- libvips/create/create.c | 10 -- libvips/deprecated/video_dispatch.c | 10 -- libvips/draw/draw.c | 31 ----- libvips/iofuncs/type.c | 19 --- libvips/iofuncs/vips.c | 14 -- libvips/morphology/morphology.c | 50 -------- libvips/resample/resample.c | 37 ------ 23 files changed, 714 insertions(+), 299 deletions(-) create mode 100755 doc/check-sections.py create mode 100644 doc/libvips-basic.md create mode 100644 doc/libvips-colour.md create mode 100644 doc/libvips-create.md create mode 100644 doc/libvips-draw.md create mode 100644 doc/libvips-morphology.md create mode 100644 doc/libvips-resample.md create mode 100644 doc/libvips-vips.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f14750e40..e11a314a78 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: include: - name: "Linux x64 (Ubuntu 24.04) - GCC 14" os: ubuntu-24.04 - build: { cc: gcc-14, cxx: g++-14, linker: ld } + build: { cc: gcc-14, cxx: g++-14, linker: ld, docs: true } - name: "Linux x64 (Ubuntu 24.04) - Clang 18 with ASan and UBSan" os: ubuntu-24.04 @@ -39,7 +39,7 @@ jobs: run: | sudo apt-get update sudo apt-get install \ - meson pkg-config \ + meson gi-docgen pkg-config \ libarchive-dev libcfitsio-dev libcgif-dev \ libexif-dev libexpat1-dev libffi-dev \ libfftw3-dev libheif-dev libheif-plugin-aomenc \ @@ -100,6 +100,7 @@ jobs: run: meson setup build -Ddebug=true + -Ddocs=${{ matrix.build.docs && 'true' || 'false' }} -Ddeprecated=false -Dmagick=disabled || (cat build/meson-logs/meson-log.txt && exit 1) @@ -108,8 +109,8 @@ jobs: run: meson compile -C build - name: Check libvips - run: | - meson test -C build \ + run: + meson test -C build || (cat build/meson-logs/testlog.txt && exit 1) - name: Install libvips diff --git a/doc/check-sections.py b/doc/check-sections.py new file mode 100755 index 0000000000..8b0dfe1f4f --- /dev/null +++ b/doc/check-sections.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 + +import sys +import argparse +import xml.etree.ElementTree as ET +from pathlib import Path + + +def register_all_namespaces(filename): + namespaces = dict([node for _, node in ET.iterparse(filename, events=['start-ns'])]) + for ns in namespaces: + ET.register_namespace(ns, namespaces[ns]) + + +def check_sections(args): + tree = ET.parse(args.gir) + root = tree.getroot() + + register_all_namespaces(args.gir) + namespace = { + 'goi': 'http://www.gtk.org/introspection/core/1.0', + 'glib': 'http://www.gtk.org/introspection/glib/1.0', + } + + namespace_node = root.find('goi:namespace', namespace) + + file_dict = {} + for file in args.files: + content = Path(file).read_text() + comment_start_idx = content.find('', comment_start_idx) + section_covers = content[comment_start_idx + 5:comment_end_idx] + + file_dict[section_covers] = {'file': file, 'content': content} + + tag_parser_dict = { + f'{{{namespace['goi']}}}alias': lambda n, _ : f'[alias@{n.attrib['name']}]', + f'{{{namespace['goi']}}}bitfield': lambda n, _ : f'[flags@{n.attrib['name']}]', + f'{{{namespace['goi']}}}callback': lambda n, _ : f'[callback@{n.attrib['name']}]', + f'{{{namespace['goi']}}}class': lambda n, _ : f'[class@{n.attrib['name']}]', + f'{{{namespace['goi']}}}constructor': lambda n, p : f'[ctor@{p}{n.attrib['name']}]', + f'{{{namespace['goi']}}}method': lambda n, p : f'[method@{p}{n.attrib['name']}]', + f'{{{namespace['goi']}}}constant': lambda n, _ : f'[const@{n.attrib['name']}]', + f'{{{namespace['goi']}}}enumeration': lambda n, _ : f'[enum@{n.attrib['name']}]', + f'{{{namespace['goi']}}}function-macro': lambda n, _ : f'[func@{n.attrib['name']}]', + f'{{{namespace['goi']}}}function': lambda n, p : f'[func@{p}{n.attrib['name']}]', + # each struct has its own documentation + # f'{{{namespace['goi']}}}record': lambda n, _ : f'[struct@{n.attrib['name']}]', + # struct and enum members do not need to be listed + # f'{{{namespace['goi']}}}field': lambda n, p : f'[struct@Vips.{p}{n.attrib['name']}]', + # f'{{{namespace['goi']}}}member': lambda n, p : f'[enum@Vips.{p}{n.attrib['name']}]', + } + + exitcode = 0 + + parent_map = {c: p for p in namespace_node.iter() for c in p} + for node in parent_map: + if 'moved-to' in node.attrib: + continue + + child = node.find('goi:doc', namespace) + if child is None: + continue + + filename = child.attrib['filename'] + section = next((k for k in file_dict.keys() if filename.startswith(k)), None) + if section is None: + continue + + parser_method = tag_parser_dict.get(node.tag, None) + if parser_method is None: + continue + + parent_name = parent_map.get(node, {}).attrib.get('name') or '' + if parent_name == 'Vips': + parent_name = '' + if parent_name: + parent_name += '.' + + symbol = parser_method(node, parent_name) + if f'* {symbol}' not in file_dict[section]['content']: + print(f"ERROR: Symbol '{symbol}' is not listed in '{file_dict[section]['file']}'", + file=sys.stderr) + exitcode = 1 + + sys.exit(exitcode) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--gir', help='input GIR file', type=Path) + parser.add_argument('files', help='markdown files', type=Path, nargs=argparse.REMAINDER) + + args = parser.parse_args() + check_sections(args) + + +if __name__ == '__main__': + main() diff --git a/doc/developer-checklist.md b/doc/developer-checklist.md index ab2a80dd97..691a171e41 100644 --- a/doc/developer-checklist.md +++ b/doc/developer-checklist.md @@ -21,7 +21,8 @@ nina.jpg: 6048x4032 uchar, 3 bands, srgb, jpegload I see: -```bash/usr/bin/time -f %M:%e vips resize nina.jpg x.jpg 0.1 +```bash +$ /usr/bin/time -f %M:%e vips resize nina.jpg x.jpg 0.1 123648:0.23 ``` @@ -97,7 +98,7 @@ operations. libvips after version 8.13 has a system for enabling and disabling image load libraries at runtime, see: -https://www.libvips.org/2022/05/28/What's-new-in-8.13.html + You can usually improve security and avoid memory spikes by only enabling the image formats you really need. If you are handling untrusted data, @@ -116,7 +117,7 @@ There are two main checks that are very worthwhile: 1. Sanity check image dimensions to protect you from decompression bombs like those described at - https://www.bamsoftware.com/hacks/deflate.html + 2. Check for interlaced (also called progressive) images. diff --git a/doc/how-it-opens-files.md b/doc/how-it-opens-files.md index 2c7c402d64..967f0d71b3 100644 --- a/doc/how-it-opens-files.md +++ b/doc/how-it-opens-files.md @@ -36,7 +36,7 @@ array. libvips supports direct access for `.v`, 8-bit binary ppm/pbm/pnm, analyse and raw. libvips has a special direct write mode where pixels can be written directly -to the file image. This is used for the [draw operators](?q=draw). +to the file image. This is used for the [draw operations](libvips-draw.html). ## Random access via load library diff --git a/doc/libvips-arithmetic.md b/doc/libvips-arithmetic.md index 0034489f9a..192aaea758 100644 --- a/doc/libvips-arithmetic.md +++ b/doc/libvips-arithmetic.md @@ -1,5 +1,7 @@ Title: Pixel arithmetic + + # Pixel arithmetic These operations perform pixel arithmetic, that is, they perform an @@ -65,7 +67,7 @@ generally the principle is that the output type should be large enough to represent the whole range of possible values, except that int never becomes float. -## Arithmetic functions +## Functions * [method@Image.add] * [func@Image.sum] @@ -181,7 +183,7 @@ float. * [method@Image.project] * [method@Image.profile] -## Arithmetic enumerations +## Enumerations * [enum@OperationMath] * [enum@OperationMath2] diff --git a/doc/libvips-basic.md b/doc/libvips-basic.md new file mode 100644 index 0000000000..064382ce5f --- /dev/null +++ b/doc/libvips-basic.md @@ -0,0 +1,82 @@ +Title: Aliases, helpers and macros + + + +# Aliases, helpers and macros + +A selection of basic aliases, [alias@GObject.Type] helpers and macro +definitions used by libvips. + +## Structs + +* [struct@Area] +* [struct@ArrayDouble] +* [struct@ArrayImage] +* [struct@ArrayInt] +* [struct@Blob] +* [struct@RefString] +* [struct@SaveString] + +## Aliases + +* [alias@Pel] + +## Callbacks + +* [callback@CallbackFn] +* [callback@SListMap2Fn] +* [callback@SListMap4Fn] +* [callback@SListFold2Fn] + +## Functions + +* [method@Area.copy] +* [func@Area.free_cb] +* [method@Area.unref] +* [ctor@Area.new] +* [ctor@Area.new_array] +* [ctor@Area.new_array_object] +* [method@Area.get_data] +* [ctor@RefString.new] +* [method@RefString.get] +* [ctor@Blob.new] +* [func@Blob.copy] +* [method@Blob.get] +* [method@Blob.set] +* [ctor@ArrayDouble.new] +* [ctor@ArrayDouble.newv] +* [method@ArrayDouble.get] +* [ctor@ArrayInt.new] +* [ctor@ArrayInt.newv] +* [method@ArrayInt.get] +* [ctor@ArrayImage.new] +* [ctor@ArrayImage.newv] +* [ctor@ArrayImage.empty] +* [method@ArrayImage.append] +* [method@ArrayImage.get] +* [func@value_set_area] +* [func@value_get_area] +* [func@value_get_save_string] +* [func@value_set_save_string] +* [func@value_set_save_stringf] +* [func@value_get_ref_string] +* [func@value_set_ref_string] +* [func@value_get_blob] +* [func@value_set_blob] +* [func@value_set_blob_free] +* [func@value_set_array] +* [func@value_get_array] +* [func@value_get_array_double] +* [func@value_set_array_double] +* [func@value_get_array_image] +* [func@value_set_array_image] +* [func@value_get_array_int] +* [func@value_set_array_int] +* [func@value_get_array_object] +* [func@value_set_array_object] + +## Function macros + +* [func@DEPRECATED_FOR] +* [func@DEPRECATED_MACRO_FOR] +* [func@ARRAY_ADDR] diff --git a/doc/libvips-colour.md b/doc/libvips-colour.md new file mode 100644 index 0000000000..3ed084e4e1 --- /dev/null +++ b/doc/libvips-colour.md @@ -0,0 +1,190 @@ +Title: Colour operators + + + +# Colour operators + +These operators let you transform coordinates and images between colour +spaces, calculate colour differences, and move to and from device spaces. + +All operations process colour from the first few bands and pass other bands +through unaltered. This means you can operate on images with alpha channels +safely. If you move to or from 16-bit RGB, any alpha channels are rescaled +for you. + +Radiance images have four 8-bits bands and store 8 bits of R, G and B and +another 8 bits of exponent, common to all channels. They are widely used in +the HDR imaging community. + +The colour functions can be divided into three main groups. First, +functions to transform images between the different colour spaces supported +by libvips: +[enum@Vips.Interpretation.srgb], [enum@Vips.Interpretation.scrgb], +[enum@Vips.Interpretation.b_w], [enum@Vips.Interpretation.xyz], +[enum@Vips.Interpretation.yxy], [enum@Vips.Interpretation.lab], +[enum@Vips.Interpretation.lch], and [enum@Vips.Interpretation.cmc]. + +There are also a set of minor colourspaces which are one of the above in a +slightly different format: +[enum@Vips.Interpretation.lab], [enum@Vips.Interpretation.labq], +[enum@Vips.Interpretation.labs], [enum@Vips.Interpretation.lch], +[enum@Vips.Interpretation.rgb16], and [enum@Vips.Interpretation.grey16]. + +Use [method@Image.colourspace] to move an image to a target colourspace +using the best sequence of colour transform operations. + +Secondly, there are a set of operations for calculating colour difference +metrics. Finally, libvips wraps LittleCMS and uses it to provide a set of +operations for reading and writing images with ICC profiles. + +This figure shows how the libvips colour spaces interconvert: + +![Interconvert](interconvert.png) + +The colour spaces supported by libvips are: + +- [enum@Vips.Interpretation.lab]: CIELAB '76 colourspace with a D65 white. + This uses three floats for each band, and bands have the obvious range.

+ There are two variants, [enum@Vips.Interpretation.labq] and + [enum@Vips.Interpretation.labs], which use ints to store values. These are + less precise, but can be quicker to store and process.

+ [enum@Vips.Interpretation.lch] is the same, but with a\*b\* as polar + coordinates. Hue is expressed in degrees. + +- [enum@Vips.Interpretation.xyz]: CIE XYZ. This uses three floats. + See [const@D75_X0] and friends for values for the ranges under various + illuminants.

+ [enum@Vips.Interpretation.yxy] is the same, but with little x and y. + +- [enum@Vips.Interpretation.scrgb]: a linear colourspace with the sRGB + primaries. This is useful if you need linear light and don't care + much what the primaries are.

+ Linearization is performed with the usual sRGB equations, see below. + +- [enum@Vips.Interpretation.srgb]: the standard sRGB colourspace, see: + [wikipedia sRGB](http://en.wikipedia.org/wiki/SRGB).

+ This uses three 8-bit values for each of RGB.

+ [enum@Vips.Interpretation.rgb16] is the same, but using three 16-bit values + for RGB.

+ [enum@Vips.Interpretation.hsv] is sRGB, but in polar coordinates. + [enum@Vips.Interpretation.lch] is much better, only use HSV if you have to. + +- [enum@Vips.Interpretation.b_w]: a monochrome image, roughly G from sRGB. + The grey value is calculated in linear [enum@Vips.Interpretation.scrgb] + space with RGB ratios 0.2126, 0.7152, 0.0722 as defined by CIE 1931 linear + luminance.

+ [enum@Vips.Interpretation.grey16] is the same, but using 16 bits. + +- [enum@Vips.Interpretation.cmc]: a colour space based on the CMC(1:1) + colour difference measurement. This is a highly uniform colour space, + and much better than CIELAB for expressing small differences.

+ The CMC colourspace is described in “Uniform Colour Space Based on the + CMC(l:c) Colour-difference Formula”, M R Luo and B Rigg, Journal of the + Society of Dyers and Colourists, vol 102, 1986. Distances in this + colourspace approximate, within 10% or so, differences in the CMC(l:c) + colour difference formula.

+ You can calculate metrics like CMC(2:1) by scaling the spaces before + finding differences. + +## Functions + +* [method@Image.colourspace_issupported] +* [method@Image.colourspace] +* [method@Image.LabQ2sRGB] +* [method@Image.rad2float] +* [method@Image.float2rad] +* [method@Image.LabS2LabQ] +* [method@Image.LabQ2LabS] +* [method@Image.LabQ2Lab] +* [method@Image.Lab2LabQ] +* [method@Image.LCh2Lab] +* [method@Image.Lab2LCh] +* [method@Image.Lab2XYZ] +* [method@Image.XYZ2Lab] +* [method@Image.XYZ2scRGB] +* [method@Image.scRGB2sRGB] +* [method@Image.scRGB2BW] +* [method@Image.sRGB2scRGB] +* [method@Image.scRGB2XYZ] +* [method@Image.HSV2sRGB] +* [method@Image.sRGB2HSV] +* [method@Image.LCh2CMC] +* [method@Image.CMC2LCh] +* [method@Image.XYZ2Yxy] +* [method@Image.Yxy2XYZ] +* [method@Image.LabS2Lab] +* [method@Image.Lab2LabS] +* [method@Image.CMYK2XYZ] +* [method@Image.XYZ2CMYK] +* [ctor@Blob.profile_load] +* [func@icc_present] +* [method@Image.icc_transform] +* [method@Image.icc_import] +* [method@Image.icc_export] +* [method@Image.icc_ac2rc] +* [func@icc_is_compatible_profile] +* [method@Image.dE76] +* [method@Image.dE00] +* [method@Image.dECMC] +* [func@col_Lab2XYZ] +* [func@col_XYZ2Lab] +* [func@col_ab2h] +* [func@col_ab2Ch] +* [func@col_Ch2ab] +* [func@col_L2Lcmc] +* [func@col_C2Ccmc] +* [func@col_Ch2hcmc] +* [func@col_make_tables_CMC] +* [func@col_Lcmc2L] +* [func@col_Ccmc2C] +* [func@col_Chcmc2h] +* [func@col_sRGB2scRGB_8] +* [func@col_sRGB2scRGB_16] +* [func@col_sRGB2scRGB_8_noclip] +* [func@col_sRGB2scRGB_16_noclip] +* [func@col_scRGB2XYZ] +* [func@col_XYZ2scRGB] +* [func@col_scRGB2sRGB_8] +* [func@col_scRGB2sRGB_16] +* [func@col_scRGB2BW_16] +* [func@col_scRGB2BW_8] +* [func@pythagoras] +* [func@col_dE00] + +## Constants + +* [const@D93_X0] +* [const@D93_Y0] +* [const@D93_Z0] +* [const@D75_X0] +* [const@D75_Y0] +* [const@D75_Z0] +* [const@D65_X0] +* [const@D65_Y0] +* [const@D65_Z0] +* [const@D55_X0] +* [const@D55_Y0] +* [const@D55_Z0] +* [const@D50_X0] +* [const@D50_Y0] +* [const@D50_Z0] +* [const@A_X0] +* [const@A_Y0] +* [const@A_Z0] +* [const@B_X0] +* [const@B_Y0] +* [const@B_Z0] +* [const@C_X0] +* [const@C_Y0] +* [const@C_Z0] +* [const@E_X0] +* [const@E_Y0] +* [const@E_Z0] +* [const@D3250_X0] +* [const@D3250_Y0] +* [const@D3250_Z0] + +## Enumerations + +* [enum@Intent] +* [enum@PCS] diff --git a/doc/libvips-create.md b/doc/libvips-create.md new file mode 100644 index 0000000000..ac349fc6b7 --- /dev/null +++ b/doc/libvips-create.md @@ -0,0 +1,44 @@ +Title: Create images + + + +# Create images + +These functions generate various images. You can combine them with +the arithmetic and rotate functions to build more complicated images. + +## Functions + +* [ctor@Image.black] +* [ctor@Image.xyz] +* [ctor@Image.grey] +* [ctor@Image.gaussmat] +* [ctor@Image.logmat] +* [ctor@Image.text] +* [ctor@Image.gaussnoise] +* [ctor@Image.eye] +* [ctor@Image.sines] +* [ctor@Image.zone] +* [ctor@Image.sdf] +* [ctor@Image.identity] +* [method@Image.buildlut] +* [method@Image.invertlut] +* [ctor@Image.tonelut] +* [ctor@Image.mask_ideal] +* [ctor@Image.mask_ideal_ring] +* [ctor@Image.mask_ideal_band] +* [ctor@Image.mask_butterworth] +* [ctor@Image.mask_butterworth_ring] +* [ctor@Image.mask_butterworth_band] +* [ctor@Image.mask_gaussian] +* [ctor@Image.mask_gaussian_ring] +* [ctor@Image.mask_gaussian_band] +* [ctor@Image.mask_fractal] +* [ctor@Image.fractsurf] +* [ctor@Image.worley] +* [ctor@Image.perlin] + +## Enumerations + +* [enum@TextWrap] +* [enum@SdfShape] diff --git a/doc/libvips-draw.md b/doc/libvips-draw.md new file mode 100644 index 0000000000..89e0104f2c --- /dev/null +++ b/doc/libvips-draw.md @@ -0,0 +1,50 @@ +Title: Drawing operations + + + +# Drawing operations + +These operations directly modify the image. They do not thread, on 32-bit +machines they will be limited to 2GB images, and a little care needs to be +taken if you use them as part of an image pipeline. They are mostly supposed +to be useful for paintbox-style programs. + +libvips operations are all functional: they take zero or more existing input +images and generate zero or more new output images. Images are never altered, +you always create new images. This means libvips can cache and thread very +aggressively. + +The downside is that creating entirely fresh images each time can be very +slow. libvips has a range of tricks to avoid these problems, but there are +still times when you really have to be able to modify an image. An example +might be drawing a curved line from a set of straight line segments: if you +need to draw 1,000 straight lines, a 1,000 operation-deep pipeline is going +to be a slow way to do it. This is where the draw operations come in. + +To use these operations, use [method@Image.copy_memory] to make a private +memory copy of the image you want to modify, then call a series of draw +operations. + +Once you are done drawing, return to normal use of vips operations. Any time +you want to start drawing again, you'll need to copy again. + +## Functions + +* [method@Image.draw_rect] +* [method@Image.draw_rect1] +* [method@Image.draw_point] +* [method@Image.draw_point1] +* [method@Image.draw_image] +* [method@Image.draw_mask] +* [method@Image.draw_mask1] +* [method@Image.draw_line] +* [method@Image.draw_line1] +* [method@Image.draw_circle] +* [method@Image.draw_circle1] +* [method@Image.draw_flood] +* [method@Image.draw_flood1] +* [method@Image.draw_smudge] + +## Enumerations + +* [enum@CombineMode] diff --git a/doc/libvips-header.md b/doc/libvips-header.md index f0be088dcb..1dd003d417 100644 --- a/doc/libvips-header.md +++ b/doc/libvips-header.md @@ -1,5 +1,7 @@ Title: Image headers + + # Image headers libvips supports getting and setting image header data (including metadata) @@ -39,7 +41,7 @@ libvips provides a couple of base classes which implement reference-counted areas of memory. If you base your metadata on one of these types, it can be copied between images efficiently. -## Header functions +## Functions * [func@format_sizeof] * [func@format_sizeof_unsafe] @@ -98,11 +100,11 @@ copied between images efficiently. * [method@Image.history_args] * [method@Image.get_history] -## Header callbacks +## Callbacks * [callback@ImageMapFn] -## Header constants +## Constants * [const@META_EXIF_NAME] * [const@META_XMP_NAME] diff --git a/doc/libvips-morphology.md b/doc/libvips-morphology.md new file mode 100644 index 0000000000..a95fdb086b --- /dev/null +++ b/doc/libvips-morphology.md @@ -0,0 +1,62 @@ +Title: Morphological operators + + + +# Morphological operators + +The morphological functions search images for particular patterns of pixels, +specified with the mask argument, either adding or removing pixels when they +find a match. They are useful for cleaning up images --- for example, you +might threshold an image, and then use one of the morphological functions +to remove all single isolated pixels from the result. + +If you combine the morphological operators with the mask rotators +([method@Image.rot45], for example) and apply them repeatedly, you can +achieve very complicated effects: you can thin, prune, fill, open edges, +close gaps, and many others. For example, see “Fundamentals of Digital +Image Processing” by A. Jain, pp 384-388, Prentice-Hall, 1989 for more +ideas. + +Beware that libvips reverses the usual image processing convention, by +assuming white objects (non-zero pixels) on a black background (zero +pixels). + +The mask you give to the morphological functions should contain only the +values 0 (for background), 128 (for don't care) and 255 (for object). The +mask must have odd length sides --- the origin of the mask is taken to be +the centre value. For example, the mask: + +```c +VipsImage *mask = vips_image_new_matrixv(3, 3, + 128.0, 255.0, 128.0, + 255.0, 255.0, 255.0, + 128.0, 255.0, 128.0); +``` + +applied to an image with [method@Image.morph] +[enum@Vips.OperationMorphology.dilate] will do a 4-connected dilation. + +Dilate sets pixels in the output if any part of the mask matches, whereas +erode sets pixels only if all the mask matches. + +See [method@Image.andimage], [method@Image.orimage] and +[method@Image.eorimage] for analogues of the usual set difference and set +union operations. + +Use [ctor@Image.new_matrixv] to create a mask in source, +[ctor@Image.matrixload] to load a mask from a simple text file, and +[ctor@Image.mask_ideal] and friends to create square, circular and ring +masks of specific sizes. + +## Functions + +* [method@Image.morph] +* [method@Image.rank] +* [method@Image.median] +* [method@Image.countlines] +* [method@Image.labelregions] +* [method@Image.fill_nearest] + +## Enumerations + +* [enum@OperationMorphology] diff --git a/doc/libvips-resample.md b/doc/libvips-resample.md new file mode 100644 index 0000000000..d248400c1e --- /dev/null +++ b/doc/libvips-resample.md @@ -0,0 +1,82 @@ +Title: Resample operations + + + +# Resample operations + +These operations build on each other in a set of layers. + +First, [method@Image.affine] applies an affine transform to an image. This +is any sort of 2D transform which preserves straight lines; so any combination +of stretch, sheer, rotate and translate. You supply an interpolator for it to +use to generate pixels, see [ctor@Interpolate.new]. It will not produce good +results for very large shrinks: you'll see aliasing. + +[method@Image.reduce] is like [method@Image.affine], but it can only shrink +images, it can't enlarge, rotate, or skew. It's very fast and uses an adaptive +kernel for interpolation. + +[method@Image.shrink] is a fast block shrinker. It can quickly reduce images +by large integer factors. It will give poor results for small size reductions: +again, you'll see aliasing. + +Next, [method@Image.resize] specialises in the common task of image reduce and +enlarge. It strings together combinations of [method@Image.shrink], +[method@Image.reduce], [method@Image.affine] and others to implement a general, +high-quality image resizer. + +Finally, [ctor@Image.thumbnail] combines load and resize in one operation, and +adds colour management and correct handling of alpha transparency. Because +load and resize happen together, it can exploit tricks like JPEG and TIFF +shrink-on-load, giving a (potentially) huge speedup. +[method@Image.thumbnail_image] is only there for emergencies, don't use it +unless you really have to. + +As a separate thing, [method@Image.mapim] can apply arbitrary 2D image +transforms to an image. + +## Classes + +* [class@Interpolate] + +## Functions + +* [method@Image.shrink] +* [method@Image.shrinkh] +* [method@Image.shrinkv] +* [method@Image.reduce] +* [method@Image.reduceh] +* [method@Image.reducev] +* [ctor@Image.thumbnail] +* [ctor@Image.thumbnail_buffer] +* [method@Image.thumbnail_image] +* [ctor@Image.thumbnail_source] +* [method@Image.similarity] +* [method@Image.rotate] +* [method@Image.affine] +* [method@Image.resize] +* [method@Image.mapim] +* [method@Image.quadratic] +* [func@interpolate] +* [ctor@Interpolate.new] +* [func@Interpolate.bilinear_static] +* [func@Interpolate.nearest_static] +* [method@Interpolate.get_method] +* [method@Interpolate.get_window_offset] +* [method@Interpolate.get_window_size] + +## Callbacks + +* [callback@InterpolateMethod] + +## Constants + +* [const@INTERPOLATE_SCALE] +* [const@INTERPOLATE_SHIFT] +* [const@TRANSFORM_SCALE] +* [const@TRANSFORM_SHIFT] + +## Enumerations + +* [enum@Kernel] +* [enum@Size] diff --git a/doc/libvips-vips.md b/doc/libvips-vips.md new file mode 100644 index 0000000000..d8c52f897c --- /dev/null +++ b/doc/libvips-vips.md @@ -0,0 +1,46 @@ +Title: Initialize, finalize and version information + + + +# Initialize, finalize and version information + +These functions handle the initialization, finalization, version retrieval, +and relocation for libvips. + +libvips is a relocatable package, meaning you can move the directory tree you +compiled it to at runtime and it will still be able to find all data files. +This is required for macOS and Windows, but slightly unusual in the Unix +world. See [func@init] and [func@guess_prefix]. + +## Functions + +* [func@max_coord_get] +* [func@init] +* [func@get_argv0] +* [func@get_prgname] +* [func@shutdown] +* [func@thread_shutdown] +* [func@add_option_entries] +* [func@leak_set] +* [func@block_untrusted_set] +* [func@version_string] +* [func@version] +* [func@guess_prefix] +* [func@guess_libdir] + +## Function macros + +* [func@INIT] + +## Constants + +* [const@DEFAULT_MAX_COORD] +* [const@ENABLE_DEPRECATED] +* [const@LIBRARY_AGE] +* [const@LIBRARY_CURRENT] +* [const@LIBRARY_REVISION] +* [const@MAJOR_VERSION] +* [const@MICRO_VERSION] +* [const@MINOR_VERSION] +* [const@VERSION] +* [const@VERSION_STRING] diff --git a/doc/meson.build b/doc/meson.build index fda1c26c9d..cd5113b81a 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -16,8 +16,6 @@ vips_content_files = files( 'function-list.md', 'how-it-opens-files.md', 'how-it-works.md', - 'libvips-arithmetic.md', - 'libvips-header.md', 'making-image-pyramids.md', 'multipage-and-animated-images.md', 'using-from-c.md', @@ -27,6 +25,18 @@ vips_content_files = files( 'using-vipsthumbnail.md', ) +vips_section_files = files( + 'libvips-arithmetic.md', + 'libvips-basic.md', + 'libvips-colour.md', + 'libvips-create.md', + 'libvips-draw.md', + 'libvips-header.md', + 'libvips-resample.md', + 'libvips-morphology.md', + 'libvips-vips.md', +) + vips_include_dir = meson.current_build_dir() / 'libvips' / 'include' doc_conf = configuration_data() doc_conf.set('VIPS_VERSION', '@0@.@1@'.format(version_major, version_minor)) @@ -45,6 +55,7 @@ vips_gir_doc = custom_target( input: vips_gir[0], output: 'Vips-@0@.0-doc.gir'.format(version_major), command: [fixup_gir_for_doc, '@INPUT@', '@OUTPUT@'], + depends: vips_gir[0], ) custom_target('libvips-doc', @@ -61,24 +72,33 @@ custom_target('libvips-doc', '--content-dir=@0@'.format(meson.current_source_dir()), '@INPUT1@', ], - depends: vips_gir[0], - depend_files: vips_content_files, + depends: vips_gir_doc, + depend_files: [vips_content_files, vips_section_files], build_by_default: true, install: true, - install_dir: docs_dir + install_dir: docs_dir, ) -test('doc-check-vips', +test('doc-check-gir', gidocgen, args: [ 'check', '--config', vips_toml, '--add-include-path=@0@'.format(vips_include_dir), - vips_gir[0], + vips_gir_doc, ], - depends: vips_gir[0], + depends: vips_gir_doc, # FIXME: Remove once we have documented all public-facing symbols, # parameters and return values. should_fail: true, suite: ['docs'], ) + +check_sections = find_program('check-sections.py') + +test('doc-check-sections', + check_sections, + args: ['--gir', vips_gir_doc] + vips_section_files, + depends: vips_gir_doc, + suite: ['docs'], +) diff --git a/doc/vips.toml.in b/doc/vips.toml.in index 7e608eff18..57e8933cbd 100644 --- a/doc/vips.toml.in +++ b/doc/vips.toml.in @@ -55,7 +55,14 @@ content_files = [ "cite.md", "libvips-arithmetic.md", + "libvips-basic.md", + "libvips-draw.md", + "libvips-colour.md", + "libvips-create.md", "libvips-header.md", + "libvips-resample.md", + "libvips-morphology.md", + "libvips-vips.md", ] content_images = [ "images/Combine.png", diff --git a/libvips/colour/colour.c b/libvips/colour/colour.c index b9e0fa92c0..d917c1558d 100644 --- a/libvips/colour/colour.c +++ b/libvips/colour/colour.c @@ -46,113 +46,6 @@ #include "pcolour.h" -/** - * SECTION: colour - * @short_description: colour operators - * @stability: Stable - * @see_also: arithmetic - * @include: vips/vips.h - * - * These operators let you transform coordinates and images between colour - * spaces, calculate colour differences, and move - * to and from device spaces. - * - * All operations process colour from the first few bands and pass other bands - * through unaltered. This means you can operate on images with alpha channels - * safely. If you move to or from 16-bit RGB, any alpha channels are rescaled - * for you. - * - * Radiance images have four 8-bits bands and store 8 bits of R, G and B and - * another 8 bits of exponent, common to all channels. They are widely used in - * the HDR imaging community. - * - * The colour functions can be divided into three main groups. First, - * functions to transform images between the different colour spaces supported - * by VIPS: #VIPS_INTERPRETATION_sRGB, #VIPS_INTERPRETATION_scRGB, - * #VIPS_INTERPRETATION_B_W, - * #VIPS_INTERPRETATION_XYZ, #VIPS_INTERPRETATION_YXY, - * #VIPS_INTERPRETATION_LAB, - * #VIPS_INTERPRETATION_LCH, and - * #VIPS_INTERPRETATION_CMC. - * - * There are also a set of minor colourspaces which are one of the above in a - * slightly different format: - * #VIPS_INTERPRETATION_LAB, #VIPS_INTERPRETATION_LABQ, - * #VIPS_INTERPRETATION_LABS, #VIPS_INTERPRETATION_LCH, - * #VIPS_INTERPRETATION_RGB16, and #VIPS_INTERPRETATION_GREY16. - * - * Use vips_colourspace() to move an image to a - * target colourspace using the best sequence of colour transform operations. - * - * Secondly, there are a set of operations for - * calculating colour difference metrics. Finally, VIPS wraps LittleCMS and - * uses it to provide a set of operations for reading and writing images with - * ICC profiles. - * - * This figure shows how the VIPS colour spaces interconvert: - * - * - * - * - * - * The colour spaces supported by VIPS are: - * - * * #VIPS_INTERPRETATION_LAB -- CIELAB '76 colourspace with a D65 white. This - * uses three floats for each band, and bands have the obvious range. - * - * There are two - * variants, #VIPS_INTERPRETATION_LABQ and #VIPS_INTERPRETATION_LABS, which - * use ints to store values. These are less precise, but can be quicker to - * store and process. - * - * #VIPS_INTERPRETATION_LCH is the same, but with a*b* as polar coordinates. - * Hue is expressed in degrees. - * - * * #VIPS_INTERPRETATION_XYZ -- CIE XYZ. This uses three floats. - * See #VIPS_D75_X0 and friends for values for the ranges - * under various illuminants. - * - * #VIPS_INTERPRETATION_YXY is the same, but with little x and y. - * - * * #VIPS_INTERPRETATION_scRGB -- a linear colourspace with the sRGB - * primaries. This is useful if you need linear light and don't care - * much what the primaries are. - * - * Linearization is performed with the usual sRGB equations, see below. - * - * * #VIPS_INTERPRETATION_sRGB -- the standard sRGB colourspace, see: - * [wikipedia sRGB](http://en.wikipedia.org/wiki/SRGB). - * - * This uses three 8-bit values for each of RGB. - * - * #VIPS_INTERPRETATION_RGB16 is the same, but using three 16-bit values for - * RGB. - * - * #VIPS_INTERPRETATION_HSV is sRGB, but in polar coordinates. - * #VIPS_INTERPRETATION_LCH is much better, only use HSV if you have to. - * - * * #VIPS_INTERPRETATION_B_W -- a monochrome image, roughly G from sRGB. - * The grey value is - * calculated in linear #VIPS_INTERPRETATION_scRGB space with RGB ratios - * 0.2126, 0.7152, 0.0722 as defined by CIE 1931 linear luminance. - * - * #VIPS_INTERPRETATION_GREY16 is the same, but using 16 bits. - * - * * #VIPS_INTERPRETATION_CMC -- a colour space based on the CMC(1:1) - * colour difference measurement. This is a highly uniform colour space, - * and much better than CIELAB for expressing small differences. - * - * The CMC colourspace is described in "Uniform Colour Space Based on the - * CMC(l:c) Colour-difference Formula", M R Luo and B Rigg, Journal of the - * Society of Dyers and Colourists, vol 102, 1986. Distances in this - * colourspace approximate, within 10% or so, differences in the CMC(l:c) - * colour difference formula. - * - * You can calculate metrics like CMC(2:1) by scaling the spaces before - * finding differences. - * - */ - /* Areas under curves for Dxx. 2 degree observer. */ diff --git a/libvips/create/create.c b/libvips/create/create.c index 2178555a8b..427a1199ad 100644 --- a/libvips/create/create.c +++ b/libvips/create/create.c @@ -51,16 +51,6 @@ #include "point.h" #include "pmask.h" -/** - * SECTION: create - * @short_description: create images in various ways - * @stability: Stable - * @include: vips/vips.h - * - * These functions generate various images. You can combine them with - * the arithmetic and rotate functions to build more complicated images. - */ - /** * VipsTextWrap: * @VIPS_TEXT_WRAP_WORD: wrap at word boundaries diff --git a/libvips/deprecated/video_dispatch.c b/libvips/deprecated/video_dispatch.c index 18dd57af42..1a22d3529a 100644 --- a/libvips/deprecated/video_dispatch.c +++ b/libvips/deprecated/video_dispatch.c @@ -37,16 +37,6 @@ #include -/** - * SECTION: video - * @short_description: various video grabbers - * @see_also: image - * @stability: Stable - * @include: vips/vips.h - * - * Read an image from a video source. - */ - static int video_v4l1_vec(im_object *argv) { diff --git a/libvips/draw/draw.c b/libvips/draw/draw.c index 40f9c8ffc8..201e34ce56 100644 --- a/libvips/draw/draw.c +++ b/libvips/draw/draw.c @@ -45,37 +45,6 @@ #include "pdraw.h" -/** - * SECTION: draw - * @short_description: drawing operations: flood, paste, line, circle - * @stability: Stable - * @include: vips/vips.h - * - * These operations directly modify the image. They do not thread, on 32-bit - * machines they will be limited to 2GB images, and a little care needs to be - * taken if you use them as part of an image pipeline. - * They are mostly supposed to be useful for paintbox-style programs. - * - * libvips operations are all functional: they take zero or more existing input - * images and generate zero or more new output images. Images are - * never altered, you always create new images. This means libvips can cache - * and thread very aggressively. - * - * The downside is that creating entirely fresh images each time can be very - * slow. libvips has a range of tricks to avoid these problems, but there are - * still times when you really have to be able to modify an image. An example - * might be drawing a curved line from a set of straight line segments: if you - * need to draw 1,000 straight lines, a 1,000 operation-deep pipeline is going - * to be a slow way to do it. This is where the draw operations come in. - * - * To use these operations, use vips_image_copy_memory() to make a private - * memory copy of the image you want to modify, then call a - * series of draw operations. - * - * Once you are done drawing, return to normal use of vips operations. Any time - * you want to start drawing again, you'll need to copy again. - */ - /** * VipsCombineMode: * @VIPS_COMBINE_MODE_SET: set pixels to the new value diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index 692e62ed29..155cf837df 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -57,25 +57,6 @@ #include #include -/** - * SECTION: basic - * @short_description: a few typedefs used everywhere - * @stability: Stable - * @include: vips/vips.h - * - * A few simple typedefs used by VIPS. - */ - -/** - * SECTION: type - * @short_description: basic types - * @stability: Stable - * @see_also: header - * @include: vips/vips.h - * - * A selection of %GType definitions used by VIPS. - */ - /* A very simple boxed type for testing. Just an int. * * You can manipulate this thing from Python (for example) with: diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index 4ae74fc03c..db892bb59c 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -103,20 +103,6 @@ #include #include -/** - * SECTION: vips - * @short_description: startup, shutdown, version - * @stability: Stable - * @see_also: VipsOperation - * @include: vips/vips.h - * - * Start VIPS up, shut VIPS down, get version information, relocation. - * - * VIPS is a relocatable package, meaning you can move the directory tree you - * compiled it to at runtime and it will still be able to find all data files. - * This is required for OS X and Windows, but slightly unusual in the Unix - * world. See [func@init] and [func@guess_prefix]. - */ /* Open mode for image write. * diff --git a/libvips/morphology/morphology.c b/libvips/morphology/morphology.c index bb655fa6f0..7704cd5e18 100644 --- a/libvips/morphology/morphology.c +++ b/libvips/morphology/morphology.c @@ -49,56 +49,6 @@ #include "pmorphology.h" -/** - * SECTION: morphology - * @short_description: morphological operators, rank filters and related image - * analysis - * @see_also: arithmetic - * @stability: Stable - * @include: vips/vips.h - * - * The morphological functions search images - * for particular patterns of pixels, specified with the mask argument, - * either adding or removing pixels when they find a match. They are useful - * for cleaning up images --- for example, you might threshold an image, and - * then use one of the morphological functions to remove all single isolated - * pixels from the result. - * - * If you combine the morphological operators with the mask rotators - * (vips_rot45(), for example) and apply them repeatedly, you - * can achieve very complicated effects: you can thin, prune, fill, open edges, - * close gaps, and many others. For example, see `Fundamentals of Digital - * Image Processing' by A. Jain, pp 384-388, Prentice-Hall, 1989 for more - * ideas. - * - * Beware that VIPS reverses the usual image processing convention, by - * assuming white objects (non-zero pixels) on a black background (zero - * pixels). - * - * The mask you give to the morphological functions should contain only the - * values 0 (for background), 128 (for don't care) and 255 (for object). The - * mask must have odd length sides --- the origin of the mask is taken to be - * the centre value. For example, the mask: - * - * VipsImage *mask = vips_image_new_matrixv(3, 3, - * 128.0, 255.0, 128.0, - * 255.0, 255.0, 255.0, - * 128.0, 255.0, 128.0); - * - * applied to an image with vips_morph() #VIPS_OPERATION_MORPHOLOGY_DILATE will - * do a 4-connected dilation. - * - * Dilate sets pixels in the output if any part of the mask matches, whereas - * erode sets pixels only if all of the mask matches. - * - * See vips_andimage(), vips_orimage() and vips_eorimage() - * for analogues of the usual set difference and set union operations. - * - * Use vips_image_new_matrixv() to create a mask in source, vips_matrixload() - * to load a mask from a simple text file, and vips_mask_ideal() and friends to - * create square, circular and ring masks of specific sizes. - */ - G_DEFINE_ABSTRACT_TYPE(VipsMorphology, vips_morphology, VIPS_TYPE_OPERATION); diff --git a/libvips/resample/resample.c b/libvips/resample/resample.c index 8393b27523..1b4155dc5b 100644 --- a/libvips/resample/resample.c +++ b/libvips/resample/resample.c @@ -52,43 +52,6 @@ #include "presample.h" -/** - * SECTION: resample - * @short_description: resample images in various ways - * @stability: Stable - * @include: vips/vips.h - * - * These operations build on each other in a set of layers. - * - * First, vips_affine() applies an affine transform to an image. This is any - * sort of 2D transform which preserves straight lines; so any combination of - * stretch, sheer, rotate and translate. You supply an interpolator for it to - * use to generate pixels, see vips_interpolate_new(). It will not produce - * good results for very large shrinks: you'll see aliasing. - * - * vips_reduce() is like vips_affine(), but it can only shrink images, it can't - * enlarge, rotate, or skew. It's very fast and uses an adaptive kernel for - * interpolation. - * - * vips_shrink() is a fast block shrinker. It can quickly reduce images by - * large integer factors. It will give poor results for small size reductions: - * again, you'll see aliasing. - * - * Next, vips_resize() specialises in the common task of image reduce and - * enlarge. It strings together combinations of vips_shrink(), vips_reduce(), - * vips_affine() and others to implement a general, high-quality image - * resizer. - * - * Finally, vips_thumbnail() combines load and resize in one operation, and adds - * colour management and correct handling of alpha transparency. Because load - * and resize happen together, it can exploit tricks like JPEG and TIFF - * shrink-on-load, giving a (potentially) huge speedup. vips_thumbnail_image() - * is only there for emergencies, don't use it unless you really have to. - * - * As a separate thing, `vips_mapim() can apply arbitrary 2D image transforms - * to an image. - */ - /** * VipsSize: * @VIPS_SIZE_BOTH: size both up and down From 6f144cc346dc0e729428587466636b67fb81727b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 6 Apr 2025 16:42:00 +0100 Subject: [PATCH 109/174] share and reuse openslide connections (#4448) * share and reuse openslide connections openslide_open() can take many seconds for some slide formats. This PR adds a cache to let these connections be reused between openslideload calls, and across threads. * incorporate review comments - test for openslide_cache_create() and share a 32mb tile cache between all openslide connections - support revalidate a bit more: we reopen from file if we open an unreffed connection - don't cache openslide connections in an error state * unref on failed open --- ChangeLog | 1 + libvips/foreign/meson.build | 1 + libvips/foreign/openslideconnection.c | 309 ++++++++++++++++++++++++++ libvips/foreign/openslideload.c | 112 +++++----- meson.build | 1 + 5 files changed, 365 insertions(+), 59 deletions(-) create mode 100644 libvips/foreign/openslideconnection.c diff --git a/ChangeLog b/ChangeLog index 63b8c3c355..79db190457 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,7 @@ master - improve vips_sink_screen() thumbnail rendering - heifload: improve detection of seek beyond EOF [lovell] - add "oneshot" option to jp2kload [mbklein] +- share and reuse openslide connections 8.16.1 diff --git a/libvips/foreign/meson.build b/libvips/foreign/meson.build index 1a280acbae..71d55c882d 100644 --- a/libvips/foreign/meson.build +++ b/libvips/foreign/meson.build @@ -116,6 +116,7 @@ endif openslide_module_sources = files( 'openslideload.c', + 'openslideconnection.c', ) if not openslide_module diff --git a/libvips/foreign/openslideconnection.c b/libvips/foreign/openslideconnection.c new file mode 100644 index 0000000000..1ba420df62 --- /dev/null +++ b/libvips/foreign/openslideconnection.c @@ -0,0 +1,309 @@ +/* Share and reuse openslide_t between many openslideload operations. + * + * 1/4/25 + * - first version! + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + */ + +/* +#define VIPS_DEBUG + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#ifdef HAVE_OPENSLIDE + +#include +#include + +#include "pforeign.h" + +#include + +// we keep this many connections around after they are closed, ready for reuse +#define OPENSLIDECONNECTION (3) + +// a tile cache shared between all active openslide connections ... 32mb +#define OPENSLIDECONNECTION_CACHE_SIZE (32 * 1024 * 1024) + +typedef struct _VipsOpenslideConnection { + // lock access to these vars here + GMutex lock; + + int ref_count; + int time; + char *filename; + openslide_t *osr; + +} VipsOpenslideConnection; + +static GHashTable *vips_openslideconnection_cache = NULL; +static GMutex vips_openslideconnection_lock; + +/* Added in 4.0 ... this is a tile cache that's shared between all active + * openslide connections. + */ +#ifdef HAVE_OPENSLIDE_CACHE_CREATE +openslide_cache_t *vips_openslideconnection_openslide_cache; +#endif /*HAVE_OPENSLIDE_CACHE_CREATE*/ + +static void +vips_openslideconnection_free(VipsOpenslideConnection *connection) +{ + VipsOpenslideConnection *cached = + g_hash_table_lookup(vips_openslideconnection_cache, + connection->filename); + g_assert(cached); + g_assert(cached == connection); + g_hash_table_remove(vips_openslideconnection_cache, connection->filename); + + g_mutex_clear(&connection->lock); + VIPS_FREE(connection->filename); + VIPS_FREEF(openslide_close, connection->osr); + g_free(connection); +} + +static void +vips_openslideconnection_unused_cb(gpointer key, gpointer value, gpointer data) +{ + VipsOpenslideConnection *connection = (VipsOpenslideConnection *) value; + int *count = (int *) data; + + g_mutex_lock(&connection->lock); + + if (connection->ref_count == 0) + *count += 1; + + g_mutex_unlock(&connection->lock); +} + +static int +vips_openslideconnection_unused(void) +{ + int unused; + + unused = 0; + g_hash_table_foreach(vips_openslideconnection_cache, + vips_openslideconnection_unused_cb, &unused); + + return unused; +} + +static void +vips_openslideconnection_oldest_cb(gpointer key, gpointer value, gpointer data) +{ + VipsOpenslideConnection *connection = (VipsOpenslideConnection *) value; + VipsOpenslideConnection **oldest = (VipsOpenslideConnection **) data; + + g_mutex_lock(&connection->lock); + + if (!*oldest || + connection->time < (*oldest)->time) + *oldest = connection; + + g_mutex_unlock(&connection->lock); +} + +static VipsOpenslideConnection * +vips_openslideconnection_oldest(void) +{ + VipsOpenslideConnection *oldest; + + oldest = NULL; + g_hash_table_foreach(vips_openslideconnection_cache, + vips_openslideconnection_oldest_cb, &oldest); + + return oldest; +} + +static void +vips_openslideconnection_trim(void) +{ + VipsOpenslideConnection *oldest; + + while (vips_openslideconnection_unused() > OPENSLIDECONNECTION && + (oldest = vips_openslideconnection_oldest())) + vips_openslideconnection_free(oldest); +} + +static void +vips_openslideconnection_unref(VipsOpenslideConnection *connection) +{ + gboolean trim; + gboolean free; + + g_mutex_lock(&connection->lock); + + g_assert(connection->ref_count > 0); + + trim = FALSE; + free = FALSE; + + connection->ref_count -= 1; + + if (connection->ref_count == 0) { + /* If the openslide_t is in an error state, don't leave it in the + * cache. + */ + if (connection->osr && + openslide_get_error(connection->osr)) + free = TRUE; + else + trim = TRUE; + } + + g_mutex_unlock(&connection->lock); + + if (free) + vips_openslideconnection_free(connection); + else if (trim) + vips_openslideconnection_trim(); +} + +static void +vips_openslideconnection_ref(VipsOpenslideConnection *connection) +{ + g_mutex_lock(&connection->lock); + + g_assert(connection->ref_count >= 0); + + connection->ref_count += 1; + + g_mutex_unlock(&connection->lock); +} + +static VipsOpenslideConnection * +vips_openslideconnection_new(const char *filename) +{ + VipsOpenslideConnection *connection; + + connection = g_new0(VipsOpenslideConnection, 1); + connection->filename = g_strdup(filename); + + g_assert(!g_hash_table_lookup(vips_openslideconnection_cache, filename)); + + g_hash_table_insert(vips_openslideconnection_cache, + connection->filename, connection); + + return connection; +} + +static void +vips_openslideconnection_touch(VipsOpenslideConnection *connection) +{ + static int time = 0; + + g_mutex_lock(&connection->lock); + + connection->time = time++; + + g_mutex_unlock(&connection->lock); +} + +openslide_t * +vips__openslideconnection_open(const char *filename, gboolean revalidate) +{ + g_mutex_lock(&vips_openslideconnection_lock); + + if (!vips_openslideconnection_cache) { + vips_openslideconnection_cache = + g_hash_table_new(g_str_hash, g_str_equal); + +#ifdef HAVE_OPENSLIDE_CACHE_CREATE + vips_openslideconnection_openslide_cache = + openslide_cache_create(OPENSLIDECONNECTION_CACHE_SIZE); +#endif /*HAVE_OPENSLIDE_CACHE_CREATE*/ + } + + VipsOpenslideConnection *connection; + + connection = g_hash_table_lookup(vips_openslideconnection_cache, filename); + + // discard any cached connection on revalidate + if (connection && + connection->ref_count == 0 && + revalidate) + VIPS_FREEF(vips_openslideconnection_free, connection); + + if (!connection) + connection = vips_openslideconnection_new(filename); + + vips_openslideconnection_ref(connection); + vips_openslideconnection_touch(connection); + + g_mutex_unlock(&vips_openslideconnection_lock); + + g_mutex_lock(&connection->lock); + + gboolean unref; + + /* We do the open outside the main lock (just in the connection lock) + * since it can take many seconds for some slides. + */ + unref = FALSE; + if (!connection->osr) { + connection->osr = openslide_open(connection->filename); + + /* If open fails, we must unref the connection since we'll return NULL. + */ + if (!connection->osr) + unref = TRUE; + } + +#ifdef HAVE_OPENSLIDE_CACHE_CREATE + if (connection->osr) + openslide_set_cache(connection->osr, + vips_openslideconnection_openslide_cache); +#endif /*HAVE_OPENSLIDE_CACHE_CREATE*/ + + openslide_t *osr = connection->osr; + + g_mutex_unlock(&connection->lock); + + if (unref) + vips_openslideconnection_unref(connection); + + return osr; +} + +void +vips__openslideconnection_close(const char *filename) +{ + g_mutex_lock(&vips_openslideconnection_lock); + + VipsOpenslideConnection *connection; + connection = g_hash_table_lookup(vips_openslideconnection_cache, filename); + + /* We unref in the main lock since openslide_close() is always relatively + * quick. + */ + if (connection) + vips_openslideconnection_unref(connection); + + g_mutex_unlock(&vips_openslideconnection_lock); +} + +#endif /*HAVE_OPENSLIDE*/ diff --git a/libvips/foreign/openslideload.c b/libvips/foreign/openslideload.c index 368cde1fea..427c80cee6 100644 --- a/libvips/foreign/openslideload.c +++ b/libvips/foreign/openslideload.c @@ -105,6 +105,12 @@ #include +/* From openslideconnection.c + */ +openslide_t *vips__openslideconnection_open(const char *filename, + gboolean revalidate); +void vips__openslideconnection_close(const char *filename); + typedef struct { /* Params. */ @@ -115,6 +121,7 @@ typedef struct { char *associated; gboolean attach_associated; gboolean rgb; + gboolean revalidate; openslide_t *osr; @@ -146,8 +153,8 @@ vips__openslide_isslide(const char *filename) * Only offer to load this file if it's not a generic tiff since * we want vips_tiffload() to handle these. */ - ok = (vendor && - strcmp(vendor, "generic-tiff") != 0); + ok = vendor && + strcmp(vendor, "generic-tiff") != 0; VIPS_DEBUG_MSG("vips__openslide_isslide: %s - %d\n", filename, ok); @@ -157,7 +164,7 @@ vips__openslide_isslide(const char *filename) int ok; ok = 0; - osr = openslide_open(filename); + osr = vips__openslideconnection_open(filename, FALSE); if (osr) { const char *vendor; @@ -175,7 +182,7 @@ vips__openslide_isslide(const char *filename) strcmp(vendor, "generic-tiff") != 0) ok = 1; - openslide_close(osr); + vips__openslideconnection_close(filename); } VIPS_DEBUG_MSG("vips__openslide_isslide: %s - %d\n", filename, ok); @@ -187,7 +194,10 @@ vips__openslide_isslide(const char *filename) static void readslide_destroy_cb(VipsImage *image, ReadSlide *rslide) { - VIPS_FREEF(openslide_close, rslide->osr); + if (rslide->osr) { + vips__openslideconnection_close(rslide->filename); + rslide->osr = NULL; + } VIPS_FREE(rslide->associated); VIPS_FREE(rslide->filename); VIPS_FREE(rslide); @@ -229,20 +239,18 @@ get_bounds(openslide_t *osr, VipsRect *rect) int i; for (i = 0; i < 4; i++) { - if (!(value = openslide_get_property_value(osr, - openslide_names[i]))) + if (!(value = openslide_get_property_value(osr, openslide_names[i]))) return FALSE; - G_STRUCT_MEMBER(int, rect, vips_offsets[i]) = - atoi(value); + G_STRUCT_MEMBER(int, rect, vips_offsets[i]) = atoi(value); } return TRUE; } static ReadSlide * -readslide_new(const char *filename, VipsImage *out, - int level, gboolean autocrop, - const char *associated, gboolean attach_associated, gboolean rgb) +readslide_new(const char *filename, VipsImage *out, int level, + gboolean autocrop, const char *associated, gboolean attach_associated, + gboolean rgb, gboolean revalidate) { ReadSlide *rslide; @@ -262,8 +270,7 @@ readslide_new(const char *filename, VipsImage *out, rslide = VIPS_NEW(NULL, ReadSlide); memset(rslide, 0, sizeof(*rslide)); - g_signal_connect(out, "close", G_CALLBACK(readslide_destroy_cb), - rslide); + g_signal_connect(out, "close", G_CALLBACK(readslide_destroy_cb), rslide); rslide->filename = g_strdup(filename); rslide->out = out; @@ -272,6 +279,7 @@ readslide_new(const char *filename, VipsImage *out, rslide->associated = g_strdup(associated); rslide->attach_associated = attach_associated; rslide->rgb = rgb; + rslide->revalidate = revalidate; /* Non-crazy defaults, override in _parse() if we can. */ @@ -382,8 +390,7 @@ vips__openslide_get_associated(ReadSlide *rslide, const char *associated_name) } #endif /*HAVE_OPENSLIDE_ICC*/ - if (vips_image_pipelinev(associated, - VIPS_DEMAND_STYLE_THINSTRIP, NULL) || + if (vips_image_pipelinev(associated, VIPS_DEMAND_STYLE_THINSTRIP, NULL) || vips_image_write_prepare(associated)) { g_object_unref(associated); return NULL; @@ -394,8 +401,7 @@ vips__openslide_get_associated(ReadSlide *rslide, const char *associated_name) (uint32_t *) VIPS_IMAGE_ADDR(associated, 0, 0)); error = openslide_get_error(rslide->osr); if (error) { - vips_error("openslide2vips", - _("reading associated image: %s"), error); + vips_error("openslide2vips", _("reading associated image: %s"), error); g_object_unref(associated); return NULL; } @@ -411,8 +417,7 @@ vips__openslide_get_associated(ReadSlide *rslide, const char *associated_name) vips_image_init_fields(rgb, w, h, 3, VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, VIPS_INTERPRETATION_sRGB, 1.0, 1.0); - if (vips_image_pipelinev(rgb, - VIPS_DEMAND_STYLE_THINSTRIP, NULL) || + if (vips_image_pipelinev(rgb, VIPS_DEMAND_STYLE_THINSTRIP, NULL) || vips_image_write_prepare(rgb)) { g_object_unref(rgb); return NULL; @@ -437,8 +442,7 @@ readslide_attach_associated(ReadSlide *rslide, VipsImage *image) { const char *const *associated_name; - for (associated_name = - openslide_get_associated_image_names(rslide->osr); + for (associated_name = openslide_get_associated_image_names(rslide->osr); *associated_name != NULL; associated_name++) { VipsImage *associated; char buf[256]; @@ -478,7 +482,8 @@ readslide_parse(ReadSlide *rslide, VipsImage *image) double xres; double yres; - rslide->osr = openslide_open(rslide->filename); + rslide->osr = vips__openslideconnection_open(rslide->filename, + rslide->revalidate); if (!rslide->osr) { vips_error("openslide2vips", "%s", _("unsupported slide format")); return -1; @@ -521,12 +526,10 @@ readslide_parse(ReadSlide *rslide, VipsImage *image) /* Try to get tile width/height. An undocumented, experimental * feature. */ - g_snprintf(buf, 256, - "openslide.level[%d].tile-width", rslide->level); + g_snprintf(buf, 256, "openslide.level[%d].tile-width", rslide->level); if ((value = openslide_get_property_value(rslide->osr, buf))) rslide->tile_width = atoi(value); - g_snprintf(buf, 256, - "openslide.level[%d].tile-height", rslide->level); + g_snprintf(buf, 256, "openslide.level[%d].tile-height", rslide->level); if ((value = openslide_get_property_value(rslide->osr, buf))) rslide->tile_height = atoi(value); if (value) @@ -552,8 +555,7 @@ readslide_parse(ReadSlide *rslide, VipsImage *image) whole.top = 0; whole.width = w; whole.height = h; - vips_rect_intersectrect(&rslide->bounds, &whole, - &rslide->bounds); + vips_rect_intersectrect(&rslide->bounds, &whole, &rslide->bounds); /* If we've clipped to nothing, ignore bounds. */ @@ -654,12 +656,14 @@ readslide_parse(ReadSlide *rslide, VipsImage *image) static int vips__openslide_read_header(const char *filename, VipsImage *out, int level, gboolean autocrop, - char *associated, gboolean attach_associated, gboolean rgb) + char *associated, gboolean attach_associated, gboolean rgb, + gboolean revalidate) { ReadSlide *rslide; if (!(rslide = readslide_new(filename, - out, level, autocrop, associated, attach_associated, rgb)) || + out, level, autocrop, associated, attach_associated, rgb, + revalidate)) || readslide_parse(rslide, out)) return -1; @@ -763,7 +767,7 @@ vips__openslide_stop(void *_seq, void *a, void *b) static int vips__openslide_read(const char *filename, VipsImage *out, int level, gboolean autocrop, gboolean attach_associated, - gboolean rgb) + gboolean rgb, gboolean revalidate) { ReadSlide *rslide; VipsImage *raw; @@ -773,7 +777,7 @@ vips__openslide_read(const char *filename, VipsImage *out, filename, level); if (!(rslide = readslide_new(filename, out, level, autocrop, - NULL, attach_associated, rgb))) + NULL, attach_associated, rgb, revalidate))) return -1; raw = vips_image_new(); @@ -808,7 +812,7 @@ vips__openslide_read(const char *filename, VipsImage *out, static int vips__openslide_read_associated(const char *filename, VipsImage *out, - const char *associated_name, gboolean rgb) + const char *associated_name, gboolean rgb, gboolean revalidate) { ReadSlide *rslide; VipsImage *associated; @@ -817,9 +821,9 @@ vips__openslide_read_associated(const char *filename, VipsImage *out, filename, associated_name); if (!(rslide = readslide_new(filename, - out, 0, FALSE, associated_name, FALSE, rgb))) + out, 0, FALSE, associated_name, FALSE, rgb, revalidate))) return -1; - rslide->osr = openslide_open(rslide->filename); + rslide->osr = vips__openslideconnection_open(rslide->filename, revalidate); if (!(associated = vips__openslide_get_associated(rslide, associated_name))) return -1; @@ -892,15 +896,13 @@ vips_foreign_load_openslide_build(VipsObject *object) * the openslide library works in terms of filenames. */ if (openslide->source) { - VipsConnection *connection = - VIPS_CONNECTION(openslide->source); + VipsConnection *connection = VIPS_CONNECTION(openslide->source); const char *filename; if (!vips_source_is_file(openslide->source) || !(filename = vips_connection_filename(connection))) { - vips_error(class->nickname, "%s", - _("no filename available")); + vips_error(class->nickname, "%s", _("no filename available")); return -1; } @@ -958,7 +960,7 @@ vips_foreign_load_openslide_header(VipsForeignLoad *load) if (vips__openslide_read_header(openslide->filename, load->out, openslide->level, openslide->autocrop, openslide->associated, openslide->attach_associated, - openslide->rgb)) + openslide->rgb, load->revalidate)) return -1; VIPS_SETSTR(load->out->filename, openslide->filename); @@ -975,12 +977,13 @@ vips_foreign_load_openslide_load(VipsForeignLoad *load) if (vips__openslide_read(openslide->filename, load->real, openslide->level, openslide->autocrop, openslide->attach_associated, - openslide->rgb)) + openslide->rgb, load->revalidate)) return -1; } else { if (vips__openslide_read_associated(openslide->filename, - load->real, openslide->associated, openslide->rgb)) + load->real, openslide->associated, openslide->rgb, + load->revalidate)) return -1; } @@ -1081,21 +1084,16 @@ G_DEFINE_TYPE(VipsForeignLoadOpenslideFile, vips_foreign_load_openslide_file, static int vips_foreign_load_openslide_file_build(VipsObject *object) { - VipsForeignLoadOpenslide *openslide = - (VipsForeignLoadOpenslide *) object; + VipsForeignLoadOpenslide *openslide = (VipsForeignLoadOpenslide *) object; VipsForeignLoadOpenslideFile *file = (VipsForeignLoadOpenslideFile *) object; if (file->filename && - !(openslide->source = - vips_source_new_from_file(file->filename))) + !(openslide->source = vips_source_new_from_file(file->filename))) return -1; - if (VIPS_OBJECT_CLASS(vips_foreign_load_openslide_file_parent_class) - ->build(object)) - return -1; - - return 0; + return VIPS_OBJECT_CLASS(vips_foreign_load_openslide_file_parent_class) + ->build(object); } static const char *vips_foreign_openslide_suffs[] = { @@ -1160,8 +1158,7 @@ G_DEFINE_TYPE(VipsForeignLoadOpenslideSource, static int vips_foreign_load_openslide_source_build(VipsObject *object) { - VipsForeignLoadOpenslide *openslide = - (VipsForeignLoadOpenslide *) object; + VipsForeignLoadOpenslide *openslide = (VipsForeignLoadOpenslide *) object; VipsForeignLoadOpenslideSource *source = (VipsForeignLoadOpenslideSource *) object; @@ -1170,11 +1167,8 @@ vips_foreign_load_openslide_source_build(VipsObject *object) g_object_ref(openslide->source); } - if (VIPS_OBJECT_CLASS(vips_foreign_load_openslide_source_parent_class) - ->build(object)) - return -1; - - return 0; + return VIPS_OBJECT_CLASS(vips_foreign_load_openslide_source_parent_class) + ->build(object); } static gboolean diff --git a/meson.build b/meson.build index 92a2690bc6..e48dfd6c6d 100644 --- a/meson.build +++ b/meson.build @@ -405,6 +405,7 @@ if openslide_dep.found() cfg_var.set('HAVE_OPENSLIDE', true) cfg_var.set('HAVE_OPENSLIDE_3_4', openslide_dep.version().version_compare('>=3.4.0')) cfg_var.set('HAVE_OPENSLIDE_ICC', cc.has_function('openslide_get_icc_profile_size', dependencies: openslide_dep)) + cfg_var.set('HAVE_OPENSLIDE_CACHE_CREATE', cc.has_function('openslide_cache_create', dependencies: openslide_dep)) endif matio_dep = dependency('matio', required: get_option('matio')) From b782ebc9aee2a675a7ff119e01651c7a85098e00 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 6 Apr 2025 17:45:17 +0200 Subject: [PATCH 110/174] doc: move sections to separate files (batch 2/2) (#4452) * doc: re-order section files * doc: re-order H2 headers * doc: remove redundant spaces * doc: move the generate SECTION * doc: move the memory SECTION * doc: move the error SECTION * doc: move the histogram SECTION * doc: move the mosaicing SECTION * doc: move the freqfilt SECTION * doc: move the conversion SECTION * doc: move the convolution SECTION --- doc/binding.md | 2 +- doc/cite.md | 2 +- doc/developer-checklist.md | 2 +- doc/examples.md | 2 +- doc/extending.md | 2 +- doc/file-format.md | 2 +- doc/function-list.md | 2 +- doc/gen-function-list.py | 2 +- doc/how-it-works.md | 2 +- doc/libvips-basic.md | 2 +- doc/libvips-conversion.md | 95 ++++++++++++++++++++++++++++ doc/libvips-convolution.md | 31 +++++++++ doc/libvips-error.md | 101 ++++++++++++++++++++++++++++++ doc/libvips-freqfilt.md | 16 +++++ doc/libvips-generate.md | 32 ++++++++++ doc/libvips-header.md | 8 +-- doc/libvips-histogram.md | 38 +++++++++++ doc/libvips-memory.md | 43 +++++++++++++ doc/libvips-morphology.md | 2 +- doc/libvips-mosaicing.md | 41 ++++++++++++ doc/libvips-resample.md | 10 +-- doc/meson.build | 10 ++- doc/using-from-c.md | 6 +- doc/using-the-cli.md | 2 +- doc/vips.toml.in | 12 +++- libvips/conversion/conversion.c | 20 ------ libvips/conversion/rot.c | 2 +- libvips/convolution/convolution.c | 10 --- libvips/freqfilt/freqfilt.c | 11 ---- libvips/histogram/histogram.c | 28 --------- libvips/iofuncs/error.c | 58 ----------------- libvips/iofuncs/generate.c | 12 ---- libvips/iofuncs/memory.c | 22 ------- libvips/mosaicing/mosaicing.c | 40 ------------ 34 files changed, 441 insertions(+), 229 deletions(-) create mode 100644 doc/libvips-conversion.md create mode 100644 doc/libvips-convolution.md create mode 100644 doc/libvips-error.md create mode 100644 doc/libvips-freqfilt.md create mode 100644 doc/libvips-generate.md create mode 100644 doc/libvips-histogram.md create mode 100644 doc/libvips-memory.md create mode 100644 doc/libvips-mosaicing.md diff --git a/doc/binding.md b/doc/binding.md index 84337c299d..db087e07d5 100644 --- a/doc/binding.md +++ b/doc/binding.md @@ -22,7 +22,7 @@ It's much better to use the layer below. This lower layer is structured as: [class@Operation] object from an operator nickname, like `"add"`. - Set parameters. You can use [method@Object.get_args] to - get the name and type of all arguments. For each argument, you need to + get the name and type of all arguments. For each argument, you need to get the value from your language, convert to a [struct@GObject.Value], then use [method@GObject.Object.set_property] to set that value on the operator. diff --git a/doc/cite.md b/doc/cite.md index 2759aa6132..d87032e1d5 100644 --- a/doc/cite.md +++ b/doc/cite.md @@ -14,4 +14,4 @@ International Conference on Image Processing 2, pp. 574-577, Genova. Cupitt, J. and Martinez, K. (1996) [VIPS: An image processing system for large images]( -http://eprints.soton.ac.uk/252227), Proc. SPIE, vol. 2663, pp. 19--28. +http://eprints.soton.ac.uk/252227), Proc. SPIE, vol. 2663, pp. 19--28. diff --git a/doc/developer-checklist.md b/doc/developer-checklist.md index 691a171e41..5ebd552c6a 100644 --- a/doc/developer-checklist.md +++ b/doc/developer-checklist.md @@ -101,7 +101,7 @@ libraries at runtime, see: You can usually improve security and avoid memory spikes by only enabling -the image formats you really need. If you are handling untrusted data, +the image formats you really need. If you are handling untrusted data, I would set the `VIPS_BLOCK_UNTRUSTED` env var and only use the loaders we have tested for security. diff --git a/doc/examples.md b/doc/examples.md index bd5535c7e2..cf66b56a79 100644 --- a/doc/examples.md +++ b/doc/examples.md @@ -6,7 +6,7 @@ This page shows a few libvips examples using Python. They will work with small syntax changes in any language with a libvips binding. The libvips test suite is written in Python and exercises every operation -in the API. It's also a useful source of examples. +in the API. It's also a useful source of examples. ## Average a region of interest box on an image diff --git a/doc/extending.md b/doc/extending.md index c1d9a614f2..c9146dc958 100644 --- a/doc/extending.md +++ b/doc/extending.md @@ -189,7 +189,7 @@ can put a cache in the pipeline after your operation, see [method@Image.linecache] and [method@Image.tilecache]. You can also make requests to your operation ordered, see [method@Image.sequential]. -Finally, [method@Image.generate] attaches a set of callbacks to the output +Finally, [method@Image.generate] attaches a set of callbacks to the output image to generate chunks of it on request. [func@start_one] and [func@stop_one] are convenience functions that make the input region for you, see below. diff --git a/doc/file-format.md b/doc/file-format.md index 4a7691c463..bf152a3393 100644 --- a/doc/file-format.md +++ b/doc/file-format.md @@ -23,7 +23,7 @@ can be used to extract any metadata. libvips files come in three parts. First, there is a 64-byte header, containing an identifying magic number and a set of very basic fields, such as image width in pixels. Next, the image data is stored as a set of band-interleaved -scanlines, from the top of the image to the bottom. Finally, after the +scanlines, from the top of the image to the bottom. Finally, after the pixel data comes an optional block of XML containing any extra metadata, such as an ICC profile or the EXIF data. diff --git a/doc/function-list.md b/doc/function-list.md index 2fd29146da..3a68f74c66 100644 --- a/doc/function-list.md +++ b/doc/function-list.md @@ -4,7 +4,7 @@ Title: All libvips functions and operators libvips has a set of operators, each of which computes some useful image processing operation. Each operator is implemented as a [class@GObject.Object] -class, for example `VipsGamma`. Classes are identified by their unique +class, for example `VipsGamma`. Classes are identified by their unique [property@VipsObject:nickname], in this case `gamma`. From the command-line, C++ and most language bindings, you use the nickname diff --git a/doc/gen-function-list.py b/doc/gen-function-list.py index 46fb55f8f4..2e87802e90 100755 --- a/doc/gen-function-list.py +++ b/doc/gen-function-list.py @@ -117,7 +117,7 @@ def add_nickname(gtype, a, b): libvips has a set of operators, each of which computes some useful image processing operation. Each operator is implemented as a [class@GObject.Object] -class, for example `VipsGamma`. Classes are identified by their unique +class, for example `VipsGamma`. Classes are identified by their unique [property@VipsObject:nickname], in this case `gamma`. From the command-line, C++ and most language bindings, you use the nickname diff --git a/doc/how-it-works.md b/doc/how-it-works.md index 1f344fc674..b10e1f4039 100644 --- a/doc/how-it-works.md +++ b/doc/how-it-works.md @@ -3,7 +3,7 @@ Title: A high-level technical overview of libvips's evaluation system # A high-level technical overview of libvips's evaluation system Compared to most image processing libraries, libvips needs little RAM and runs -quickly, especially on machines with more than one CPU. libvips achieves this +quickly, especially on machines with more than one CPU. libvips achieves this improvement by only keeping the pixels currently being processed in RAM and by having an efficient, threaded image IO system. This page explains how these features are implemented. diff --git a/doc/libvips-basic.md b/doc/libvips-basic.md index 064382ce5f..a5cea0705b 100644 --- a/doc/libvips-basic.md +++ b/doc/libvips-basic.md @@ -14,7 +14,7 @@ definitions used by libvips. * [struct@ArrayImage] * [struct@ArrayInt] * [struct@Blob] -* [struct@RefString] +* [struct@RefString] * [struct@SaveString] ## Aliases diff --git a/doc/libvips-conversion.md b/doc/libvips-conversion.md new file mode 100644 index 0000000000..405d51cd0e --- /dev/null +++ b/doc/libvips-conversion.md @@ -0,0 +1,95 @@ +Title: Convert images in some way + + + +# Convert images in some way + +These operations convert an image in some way. They can be split into two +main groups. + +The first set of operations change an image's format in some way. You can +change the band format (for example, cast to 32-bit unsigned int), form +complex images from real images, convert images to matrices and back, change +header fields, and a few others. + +The second group move pixels about in some way. You can flip, rotate, +extract, insert and join pairs of images in various ways. + +## Functions + +* [method@Image.copy] +* [method@Image.tilecache] +* [method@Image.linecache] +* [method@Image.sequential] +* [method@Image.copy_file] +* [method@Image.embed] +* [method@Image.gravity] +* [method@Image.flip] +* [method@Image.insert] +* [method@Image.join] +* [func@Image.arrayjoin] +* [method@Image.extract_area] +* [method@Image.crop] +* [method@Image.smartcrop] +* [method@Image.extract_band] +* [method@Image.replicate] +* [method@Image.grid] +* [method@Image.transpose3d] +* [method@Image.wrap] +* [method@Image.rot] +* [method@Image.rot90] +* [method@Image.rot180] +* [method@Image.rot270] +* [method@Image.rot45] +* [method@Image.autorot_remove_angle] +* [method@Image.autorot] +* [method@Image.zoom] +* [method@Image.subsample] +* [method@Image.cast] +* [method@Image.cast_uchar] +* [method@Image.cast_char] +* [method@Image.cast_ushort] +* [method@Image.cast_short] +* [method@Image.cast_uint] +* [method@Image.cast_int] +* [method@Image.cast_float] +* [method@Image.cast_double] +* [method@Image.cast_complex] +* [method@Image.cast_dpcomplex] +* [method@Image.scale] +* [method@Image.msb] +* [method@Image.byteswap] +* [func@Image.bandjoin] +* [method@Image.bandjoin2] +* [method@Image.bandjoin_const] +* [method@Image.bandjoin_const1] +* [func@Image.bandrank] +* [method@Image.bandfold] +* [method@Image.bandunfold] +* [method@Image.bandbool] +* [method@Image.bandand] +* [method@Image.bandor] +* [method@Image.bandeor] +* [method@Image.bandmean] +* [method@Image.recomb] +* [method@Image.ifthenelse] +* [func@Image.switch] +* [method@Image.flatten] +* [method@Image.addalpha] +* [method@Image.premultiply] +* [method@Image.unpremultiply] +* [func@Image.composite] +* [method@Image.composite2] +* [method@Image.falsecolour] +* [method@Image.gamma] + +## Enumerations + +* [enum@Extend] +* [enum@CompassDirection] +* [enum@Direction] +* [enum@Align] +* [enum@Angle] +* [enum@Angle45] +* [enum@Interesting] +* [enum@BlendMode] diff --git a/doc/libvips-convolution.md b/doc/libvips-convolution.md new file mode 100644 index 0000000000..64fe02d2b4 --- /dev/null +++ b/doc/libvips-convolution.md @@ -0,0 +1,31 @@ +Title: Convolve and correlate images + + + +# Convolve and correlate images + +These operations convolve an image in some way, or are operations based on +simple convolution, or are useful with convolution. + +## Functions + +* [method@Image.conv] +* [method@Image.convf] +* [method@Image.convi] +* [method@Image.conva] +* [method@Image.convsep] +* [method@Image.convasep] +* [method@Image.compass] +* [method@Image.gaussblur] +* [method@Image.sharpen] +* [method@Image.spcor] +* [method@Image.fastcor] +* [method@Image.sobel] +* [method@Image.scharr] +* [method@Image.prewitt] +* [method@Image.canny] + +## Enumerations + +* [enum@Combine] +* [enum@Precision] diff --git a/doc/libvips-error.md b/doc/libvips-error.md new file mode 100644 index 0000000000..0593f53ea2 --- /dev/null +++ b/doc/libvips-error.md @@ -0,0 +1,101 @@ +Title: Error messages and error handling + + + +# Error messages and error handling + +libvips maintains an error buffer (a log of localised text messages), a set +of functions for adding messages, and a way to access and clear the buffer. + +The error buffer is global, that is, it is shared between all threads. You +can add to the buffer from any thread (there is a lock to prevent +corruption), but it's sensible to only read and clear the buffer from the +main thread of execution. + +The general principle is: if you detect an error, log a message for the +user. If a function you call detects an error, just propagate it and don't +add another message. + +```c +VipsImage *im; + +if (!(im = vips_image_new_from_file(filename, NULL))) + // vips_image_new_from_file() will set a message, we don't need to + return -1; + +if (vips_image_get_width(im) < 100) { + // we have detected an error, we must set a message + vips_error("myprogram", "%s", _("width too small")); + return -1; +} +``` + +The domain argument most of these functions take is not localised and is +supposed to indicate the component which failed. + +libvips uses [func@GLib.warning] and [func@GLib.info] to send warning and +information messages to the user. You can use the usual GLib mechanisms to +display or divert these messages. For example, info messages are hidden by +default, but you can see them with: + +```bash +$ G_MESSAGES_DEBUG=VIPS vipsthumbnail k2.jpg +VIPS-INFO: thumbnailing k2.jpg +VIPS-INFO: selected loader is VipsForeignLoadJpegFile +VIPS-INFO: input size is 1450 x 2048 +VIPS-INFO: loading jpeg with factor 8 pre-shrink +VIPS-INFO: converting to processing space srgb +VIPS-INFO: residual reducev by 0.5 +VIPS-INFO: 13 point mask +VIPS-INFO: using vector path +VIPS-INFO: residual reduceh by 0.5 +VIPS-INFO: 13 point mask +VIPS-INFO: thumbnailing k2.jpg as ./tn_k2.jpg +``` + +## Functions + +* [func@error_buffer] +* [func@error_buffer_copy] +* [func@error_clear] +* [func@error_freeze] +* [func@error_thaw] +* [func@error] +* [func@verror] +* [func@error_system] +* [func@verror_system] +* [func@error_g] +* [func@g_error] +* [func@error_exit] +* [func@check_uncoded] +* [func@check_coding] +* [func@check_coding_known] +* [func@check_coding_noneorlabq] +* [func@check_coding_same] +* [func@check_mono] +* [func@check_bands] +* [func@check_bands_1or3] +* [func@check_bands_atleast] +* [func@check_bands_1orn] +* [func@check_bands_1orn_unary] +* [func@check_bands_same] +* [func@check_bandno] +* [func@check_int] +* [func@check_uint] +* [func@check_uintorf] +* [func@check_noncomplex] +* [func@check_complex] +* [func@check_twocomponents] +* [func@check_format] +* [func@check_u8or16] +* [func@check_8or16] +* [func@check_u8or16orf] +* [func@check_format_same] +* [func@check_size_same] +* [func@check_oddsquare] +* [func@check_vector_length] +* [func@check_vector] +* [func@check_hist] +* [func@check_matrix] +* [func@check_separable] +* [func@check_precision_intfloat] diff --git a/doc/libvips-freqfilt.md b/doc/libvips-freqfilt.md new file mode 100644 index 0000000000..6acff1a471 --- /dev/null +++ b/doc/libvips-freqfilt.md @@ -0,0 +1,16 @@ +Title: Fourier transforms and frequency-domain filters + + + +# Fourier transforms and frequency-domain filters + +To and from Fourier space, filter in Fourier space, convert Fourier-space +images to a displayable form. + +## Functions + +* [method@Image.fwfft] +* [method@Image.invfft] +* [method@Image.freqmult] +* [method@Image.spectrum] +* [method@Image.phasecor] diff --git a/doc/libvips-generate.md b/doc/libvips-generate.md new file mode 100644 index 0000000000..2929562bc0 --- /dev/null +++ b/doc/libvips-generate.md @@ -0,0 +1,32 @@ +Title: Calculate pixels and pixel buffers + + + +# Calculate pixels and pixel buffers + +These functions let you attach generate functions to images and ask for +regions of images to be calculated. + +## Callbacks + +* [callback@GenerateFn] +* [callback@RegionWrite] +* [callback@SinkNotify] +* [callback@StartFn] +* [callback@StopFn] + +## Functions + +* [method@Image.sink_disc] +* [method@Image.sink] +* [method@Image.sink_tile] +* [method@Image.sink_screen] +* [func@sink_memory] +* [func@start_one] +* [func@stop_one] +* [func@start_many] +* [func@stop_many] +* [func@allocate_input_array] +* [method@Image.generate] +* [func@Image.pipeline_array] +* [method@Image.pipelinev] diff --git a/doc/libvips-header.md b/doc/libvips-header.md index 1dd003d417..de22907493 100644 --- a/doc/libvips-header.md +++ b/doc/libvips-header.md @@ -41,6 +41,10 @@ libvips provides a couple of base classes which implement reference-counted areas of memory. If you base your metadata on one of these types, it can be copied between images efficiently. +## Callbacks + +* [callback@ImageMapFn] + ## Functions * [func@format_sizeof] @@ -100,10 +104,6 @@ copied between images efficiently. * [method@Image.history_args] * [method@Image.get_history] -## Callbacks - -* [callback@ImageMapFn] - ## Constants * [const@META_EXIF_NAME] diff --git a/doc/libvips-histogram.md b/doc/libvips-histogram.md new file mode 100644 index 0000000000..980e6e0242 --- /dev/null +++ b/doc/libvips-histogram.md @@ -0,0 +1,38 @@ +Title: Find, manipulate and apply histograms and lookup tables + + + +# Find, manipulate and apply histograms and lookup tables + +Histograms and look-up tables are 1xn or nx1 images, where n is less than +256 or less than 65536, corresponding to 8- and 16-bit unsigned int images. +They are tagged with a [enum@Interpretation] of +[enum@Vips.Interpretation.histogram] and usually displayed by user-interfaces +such as nip2 as plots rather than images. + +These functions can be broadly grouped as things to find or build +histograms ([method@Image.hist_find], [method@Image.hist_find_indexed], +[method@Image.hist_find_ndim], [method@Image.buildlut], +[ctor@Image.identity]), operations that manipulate histograms in some way +([method@Image.hist_cum], [method@Image.hist_norm]), +operations to apply histograms ([method@Image.maplut]), and a variety of +utility operations. + +A final group of operations build tone curves. These are useful in pre-press +work for adjusting the appearance of images. They are designed for +CIELAB images, but might be useful elsewhere. + +## Functions + +* [method@Image.maplut] +* [method@Image.percent] +* [method@Image.stdif] +* [method@Image.hist_cum] +* [method@Image.hist_norm] +* [method@Image.hist_equal] +* [method@Image.hist_plot] +* [method@Image.hist_match] +* [method@Image.hist_local] +* [method@Image.hist_ismonotonic] +* [method@Image.hist_entropy] +* [method@Image.case] diff --git a/doc/libvips-memory.md b/doc/libvips-memory.md new file mode 100644 index 0000000000..ffa4dd455f --- /dev/null +++ b/doc/libvips-memory.md @@ -0,0 +1,43 @@ +Title: Memory utilities + + + +# Memory utilities + +These functions cover two main areas. + +First, some simple utility functions over the underlying [func@GLib.malloc] / +[func@GLib.free] functions. Memory that is allocated and freed using these +functions is interchangeable with any other GLib library. + +Second, a pair of functions, [func@tracked_malloc] and [func@tracked_free], +which are NOT compatible. If you [func@GLib.free] memory that has been +allocated with [func@tracked_malloc] you will see crashes. + +The tracked functions are only suitable for large allocations internal to the +library, for example pixel buffers. libvips watches the total amount of live +tracked memory and uses this information to decide when to trim caches. + +## Functions + +* [func@malloc] +* [func@strdup] +* [func@tracked_free] +* [func@tracked_aligned_free] +* [func@tracked_malloc] +* [func@tracked_aligned_alloc] +* [func@tracked_get_mem] +* [func@tracked_get_mem_highwater] +* [func@tracked_get_allocs] +* [func@tracked_open] +* [func@tracked_close] +* [func@tracked_get_files] + +## Function macros + +* [func@FREEF] +* [func@FREE] +* [func@SETSTR] +* [func@MALLOC] +* [func@NEW] +* [func@ARRAY] diff --git a/doc/libvips-morphology.md b/doc/libvips-morphology.md index a95fdb086b..0abe037b07 100644 --- a/doc/libvips-morphology.md +++ b/doc/libvips-morphology.md @@ -39,7 +39,7 @@ applied to an image with [method@Image.morph] Dilate sets pixels in the output if any part of the mask matches, whereas erode sets pixels only if all the mask matches. -See [method@Image.andimage], [method@Image.orimage] and +See [method@Image.andimage], [method@Image.orimage] and [method@Image.eorimage] for analogues of the usual set difference and set union operations. diff --git a/doc/libvips-mosaicing.md b/doc/libvips-mosaicing.md new file mode 100644 index 0000000000..5058e6f707 --- /dev/null +++ b/doc/libvips-mosaicing.md @@ -0,0 +1,41 @@ +Title: Build image mosaics + + + +# Build image mosaics + +These functions are useful for joining many small images together to make one +large image. They can cope with unstable contrast and arbitrary sub-image +layout, but will not do any geometric correction. Geometric errors should be +removed before using these functions. + +The mosaicing functions can be grouped into layers: + +The lowest level operation is [method@Image.merge] which joins two images +together left-right or up-down with a smooth seam. + +Next, [method@Image.mosaic] uses search functions plus the two low-level merge +operations to join two images given just an approximate overlap as a start +point. + +[method@Image.mosaic1] is a first-order analogue of the basic mosaic +functions: it takes two approximate tie-points and uses them to rotate and +scale the right-hand or bottom image before starting to join. + +Finally, [method@Image.globalbalance] can be used to remove contrast +differences in a mosaic which has been assembled with these functions. It +takes the mosaic apart, measures image contrast differences along the seams, +finds a set of correction factors which will minimise these differences, and +reassembles the mosaic. [method@Image.remosaic] uses the same techniques, but +will reassemble the image from a different set of source images. + +## Functions + +* [method@Image.merge] +* [method@Image.mosaic] +* [method@Image.mosaic1] +* [method@Image.match] +* [method@Image.globalbalance] +* [method@Image.remosaic] +* [method@Image.matrixinvert] +* [method@Image.matrixmultiply] diff --git a/doc/libvips-resample.md b/doc/libvips-resample.md index d248400c1e..78b1da781f 100644 --- a/doc/libvips-resample.md +++ b/doc/libvips-resample.md @@ -28,7 +28,7 @@ high-quality image resizer. Finally, [ctor@Image.thumbnail] combines load and resize in one operation, and adds colour management and correct handling of alpha transparency. Because load and resize happen together, it can exploit tricks like JPEG and TIFF -shrink-on-load, giving a (potentially) huge speedup. +shrink-on-load, giving a (potentially) huge speedup. [method@Image.thumbnail_image] is only there for emergencies, don't use it unless you really have to. @@ -39,6 +39,10 @@ transforms to an image. * [class@Interpolate] +## Callbacks + +* [callback@InterpolateMethod] + ## Functions * [method@Image.shrink] @@ -65,10 +69,6 @@ transforms to an image. * [method@Interpolate.get_window_offset] * [method@Interpolate.get_window_size] -## Callbacks - -* [callback@InterpolateMethod] - ## Constants * [const@INTERPOLATE_SCALE] diff --git a/doc/meson.build b/doc/meson.build index cd5113b81a..98ee454e63 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -29,11 +29,19 @@ vips_section_files = files( 'libvips-arithmetic.md', 'libvips-basic.md', 'libvips-colour.md', + 'libvips-conversion.md', + 'libvips-convolution.md', 'libvips-create.md', 'libvips-draw.md', + 'libvips-error.md', + 'libvips-freqfilt.md', + 'libvips-generate.md', 'libvips-header.md', - 'libvips-resample.md', + 'libvips-histogram.md', + 'libvips-memory.md', 'libvips-morphology.md', + 'libvips-mosaicing.md', + 'libvips-resample.md', 'libvips-vips.md', ) diff --git a/doc/using-from-c.md b/doc/using-from-c.md index 8621937f52..6def1f0fad 100644 --- a/doc/using-from-c.md +++ b/doc/using-from-c.md @@ -28,7 +28,7 @@ to get the various properties, such as width, but no decoding occurs until pixel values are really needed. Once you have an image, you can get properties from it in the usual -way. You can use projection functions, like [method@Image.get_width] or +way. You can use projection functions, like [method@Image.get_width] or [method@GObject.Object.get], to get [class@GObject.Object] properties. All libvips objects are immutable, meaning you can only get properties, you can't set them. See [libvips Header](file-format.html) to read about image @@ -38,8 +38,8 @@ properties. libvips is based on the [class@GObject.Object] library and is therefore reference counted. [ctor@Image.new_from_file] returns an object with a count -of 1. When you are done with an image, use [method@GObject.Object.unref] to -dispose of it. If you pass an image to an operation and that operation needs +of 1. When you are done with an image, use [method@GObject.Object.unref] to +dispose of it. If you pass an image to an operation and that operation needs to keep a copy of the image, it will ref it. So you can unref an image as soon as you no longer need it, you don't need to hang on to it in case anyone else is still using it. diff --git a/doc/using-the-cli.md b/doc/using-the-cli.md index ae845a2b57..82799c7aaf 100644 --- a/doc/using-the-cli.md +++ b/doc/using-the-cli.md @@ -10,7 +10,7 @@ $ vips rot k2.jpg x.jpg d90 ``` Will rotate the image `k2.jpg` by 90 degrees anticlockwise and write the -result to the file `x.jpg`. If you don't give any arguments to an operation, +result to the file `x.jpg`. If you don't give any arguments to an operation, `vips` will give a short description, for example: ```bash diff --git a/doc/vips.toml.in b/doc/vips.toml.in index 57e8933cbd..9be7de92f1 100644 --- a/doc/vips.toml.in +++ b/doc/vips.toml.in @@ -56,12 +56,20 @@ content_files = [ "libvips-arithmetic.md", "libvips-basic.md", - "libvips-draw.md", "libvips-colour.md", + "libvips-conversion.md", + "libvips-convolution.md", "libvips-create.md", + "libvips-draw.md", + "libvips-error.md", + "libvips-freqfilt.md", + "libvips-generate.md", "libvips-header.md", - "libvips-resample.md", + "libvips-histogram.md", + "libvips-memory.md", "libvips-morphology.md", + "libvips-mosaicing.md", + "libvips-resample.md", "libvips-vips.md", ] content_images = [ diff --git a/libvips/conversion/conversion.c b/libvips/conversion/conversion.c index 628624a271..89cd2fc563 100644 --- a/libvips/conversion/conversion.c +++ b/libvips/conversion/conversion.c @@ -49,26 +49,6 @@ #include "pconversion.h" -/** - * SECTION: conversion - * @short_description: convert images in some way: change band format, change header, insert, extract, join - * @see_also: resample - * @stability: Stable - * @include: vips/vips.h - * - * These operations convert an image in some way. They can be split into a two - * main groups. - * - * The first set of operations change an image's format in some way. You - * can change the band format (for example, cast to 32-bit unsigned - * int), form complex images from real images, convert images to - * matrices and back, change header fields, and a few others. - * - * The second group move pixels about in some way. You can flip, rotate, - * extract, insert and join pairs of images in various ways. - * - */ - /** * vips_composite: * @in: (array length=n) (transfer none): array of input images diff --git a/libvips/conversion/rot.c b/libvips/conversion/rot.c index 9e9bab811e..938287ef95 100644 --- a/libvips/conversion/rot.c +++ b/libvips/conversion/rot.c @@ -416,7 +416,7 @@ vips_rot(VipsImage *in, VipsImage **out, VipsAngle angle, ...) } /** - * vips_rot90: + * vips_rot90: (method) * @in: input image * @out: output image * @...: %NULL-terminated list of optional named arguments diff --git a/libvips/convolution/convolution.c b/libvips/convolution/convolution.c index 12478400ac..70a60a2546 100644 --- a/libvips/convolution/convolution.c +++ b/libvips/convolution/convolution.c @@ -51,16 +51,6 @@ #include "pconvolution.h" -/** - * SECTION: convolution - * @short_description: convolve and correlate images - * @stability: Stable - * @include: vips/vips.h - * - * These operations convolve an image in some way, or are operations based on - * simple convolution, or are useful with convolution. - */ - /** * VipsPrecision: * @VIPS_PRECISION_INTEGER: int everywhere diff --git a/libvips/freqfilt/freqfilt.c b/libvips/freqfilt/freqfilt.c index 41bc90dc71..463a342e76 100644 --- a/libvips/freqfilt/freqfilt.c +++ b/libvips/freqfilt/freqfilt.c @@ -49,17 +49,6 @@ #include "pfreqfilt.h" -/** - * SECTION: freqfilt - * @short_description: fourier transforms and frequency-domin filters - * @stability: Stable - * @see_also: image - * @include: vips/vips.h - * - * To and from Fourier space, filter in Fourier space, convert Fourier-space - * images to a displayable form. - */ - G_DEFINE_ABSTRACT_TYPE(VipsFreqfilt, vips_freqfilt, VIPS_TYPE_OPERATION); static int diff --git a/libvips/histogram/histogram.c b/libvips/histogram/histogram.c index f5be1c18fc..d54d20fc90 100644 --- a/libvips/histogram/histogram.c +++ b/libvips/histogram/histogram.c @@ -46,34 +46,6 @@ #include "phistogram.h" -/** - * SECTION: histogram - * @short_description: find, manipulate and apply histograms and lookup tables - * @stability: Stable - * @see_also: image - * arithmetic - * create - * @include: vips/vips.h - * - * Histograms and look-up tables are 1xn or nx1 images, where n is less than - * 256 or less than 65536, corresponding to 8- and 16-bit unsigned int images. - * They are tagged with a #VipsInterpretation of - * #VIPS_INTERPRETATION_HISTOGRAM and usually displayed by user-interfaces - * such as nip2 as plots rather than images. - * - * These functions can be broadly grouped as things to find or build - * histograms (vips_hist_find(), vips_hist_find_indexed(), - * vips_hist_find_ndim(), vips_buildlut(), vips_identity()), - * operations that - * manipulate histograms in some way (vips_hist_cum(), vips_hist_norm()), - * operations to apply histograms (vips_maplut()), and a variety of utility - * operations. - * - * A final group of operations build tone curves. These are useful in - * pre-press work for adjusting the appearance of images. They are designed - * for CIELAB images, but might be useful elsewhere. - */ - G_DEFINE_ABSTRACT_TYPE(VipsHistogram, vips_histogram, VIPS_TYPE_OPERATION); /* sizealike by expanding in just one dimension and copying the final element. diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index c2725ac9e9..17e972e702 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -69,64 +69,6 @@ #include #endif /*G_OS_WIN32*/ -/** - * SECTION: errors - * @short_description: error messages and error handling - * @stability: Stable - * @include: vips/vips.h - * - * VIPS maintains an error buffer (a log of localised text messages), - * a set of functions - * for adding messages, and a way to access and clear the buffer. - * - * The error buffer is global, that is, it is shared between all threads. You - * can add to the buffer from any thread (there is a lock to prevent - * corruption), but it's sensible to only read and clear the buffer from the - * main thread of execution. - * - * The general principle is: if you detect an error, log a message for the - * user. If a function you call detects an error, just propagate it and don't - * add another message. - * - * ```c - * VipsImage *im; - * - * if (!(im = vips_image_new_from_file(filename, NULL))) - * // [ctor@Image.new_from_file] will set a message, we don't need to - * return -1; - * - * if (vips_image_get_width(im) < 100) { - * // we have detected an error, we must set a message - * vips_error("myprogram", "%s", _("width too small")); - * return -1; - * } - * ``` - * - * The domain argument most of these functions take is not localised and is - * supposed to indicate the component which failed. - * - * libvips uses [func@GLib.warning] and [func@GLib.info] to send warning and information - * messages to the user. You can use the usual glib mechanisms to display or - * divert these messages. For example, info messages are hidden by default, but - * you can see them with: - * - * ```c - * $ G_MESSAGES_DEBUG=VIPS vipsthumbnail k2.jpg - * VIPS-INFO: thumbnailing k2.jpg - * VIPS-INFO: selected loader is VipsForeignLoadJpegFile - * VIPS-INFO: input size is 1450 x 2048 - * VIPS-INFO: loading jpeg with factor 8 pre-shrink - * VIPS-INFO: converting to processing space srgb - * VIPS-INFO: residual reducev by 0.5 - * VIPS-INFO: 13 point mask - * VIPS-INFO: using vector path - * VIPS-INFO: residual reduceh by 0.5 - * VIPS-INFO: 13 point mask - * VIPS-INFO: thumbnailing k2.jpg as ./tn_k2.jpg - * ``` - * - */ - /* Make global array to keep the error message buffer. */ #define VIPS_MAX_ERROR (10240) diff --git a/libvips/iofuncs/generate.c b/libvips/iofuncs/generate.c index 614619b9d3..5fd702e92b 100644 --- a/libvips/iofuncs/generate.c +++ b/libvips/iofuncs/generate.c @@ -110,18 +110,6 @@ #include #include -/** - * SECTION: generate - * @short_description: calculate pixels and pixel buffers - * @stability: Stable - * @see_also: VipsImage, - * VipsRegion - * @include: vips/vips.h - * - * These functions let you attach generate functions to images - * and ask for regions of images to be calculated. - */ - /* Max number of images we can handle. */ #define MAX_IMAGES (1000) diff --git a/libvips/iofuncs/memory.c b/libvips/iofuncs/memory.c index 9c3862f8ce..efd70c59e0 100644 --- a/libvips/iofuncs/memory.c +++ b/libvips/iofuncs/memory.c @@ -75,28 +75,6 @@ #include -/** - * SECTION: memory - * @short_description: memory utilities - * @stability: Stable - * @include: vips/vips.h - * - * These functions cover two main areas. - * - * First, some simple utility functions over the underlying - * [func@GLib.malloc]/[func@GLib.free] functions. Memory allocated and freeded using these - * functions is interchangeable with any other glib library. - * - * Second, a pair of functions, [func@tracked_malloc] and [func@tracked_free], - * which are NOT compatible. If you [func@GLib.free] memory that has been allocated - * with [func@tracked_malloc] you will see crashes. - * - * The tracked functions are - * only suitable for large allocations internal to the library, for example - * pixel buffers. libvips watches the total amount of live tracked memory and - * uses this information to decide when to trim caches. - */ - /* g_assert_not_reached() on memory errors. #define DEBUG */ diff --git a/libvips/mosaicing/mosaicing.c b/libvips/mosaicing/mosaicing.c index eabbbba42e..b214b9112f 100644 --- a/libvips/mosaicing/mosaicing.c +++ b/libvips/mosaicing/mosaicing.c @@ -45,46 +45,6 @@ #include #include -/** - * SECTION: mosaicing - * @short_description: build image mosaics - * @stability: Stable - * @include: vips/vips.h - * - * These functions are useful for joining many small images together to make - * one large image. They can cope with unstable contrast and arbitrary sub-image - * layout, but will not do any geometric correction. Geometric errors should - * be removed before using these functions. - * - * The mosaicing functions can be grouped into layers: - * - * The lowest level operation is vips_merge() which - * joins two images together - * left-right or up-down with a smooth seam. - * - * Next, vips_mosaic() uses - * search functions plus the two low-level merge operations to join two images - * given just an approximate overlap as a start point. - * - * vips_mosaic1() is a first-order - * analogue of the basic mosaic functions: it takes two approximate - * tie-points and uses - * them to rotate and scale the right-hand or bottom image before starting to - * join. - * - * Finally, vips_globalbalance() can be used to remove contrast differences in - * a mosaic - * which has been assembled with these functions. It takes the mosaic apart, - * measures image contrast differences along the seams, finds a set of - * correction factors which will minimise these differences, and reassembles - * the mosaic. - * vips_remosaic() uses the - * same - * techniques, but will reassemble the image from a different set of source - * images. - * - */ - /* Called from iofuncs to init all operations in this dir. Use a plugin system * instead? */ From 594199b0d8d97f877f224e0b56bb5791dba3dd26 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Mon, 7 Apr 2025 05:09:35 -0400 Subject: [PATCH 111/174] openslideconnection: fixes and some cleanups (#4455) * openslideconnection: fix unused-variable warning with assertions disabled * openslideconnection: only openslide_set_cache() right after openslide_open() There's no need to do it when reusing an existing openslide_t, and doing so invalidates all the existing cache entries for the handle. * openslideconnection: remember to take global lock around unref _unref can call _free, which needs the lock. * openslideconnection: use a GQueue to track unused connections Eliminate some code, and potentially improve trim performance with a large number of active connections. * openslideconnection: simplify locking _ref and _unref already need to happen inside the global lock, so we can protect the refcount with the global lock and use a per-connection lock only to protect the slow initialization of connection->osr. That does mean that _free needs to openslide_close() inside the osr lock, since otherwise there's a codepath (the _open revalidate case) where the current thread might not have received an up-to-date ->osr. --- libvips/foreign/openslideconnection.c | 126 +++++++------------------- 1 file changed, 34 insertions(+), 92 deletions(-) diff --git a/libvips/foreign/openslideconnection.c b/libvips/foreign/openslideconnection.c index 1ba420df62..e6e99b0bb3 100644 --- a/libvips/foreign/openslideconnection.c +++ b/libvips/foreign/openslideconnection.c @@ -50,17 +50,20 @@ #define OPENSLIDECONNECTION_CACHE_SIZE (32 * 1024 * 1024) typedef struct _VipsOpenslideConnection { - // lock access to these vars here - GMutex lock; + char *filename; + // protected by vips_openslideconnection_lock int ref_count; - int time; - char *filename; + + // first access protected by separate lock, since initialization + // is slow openslide_t *osr; + GMutex osr_lock; } VipsOpenslideConnection; static GHashTable *vips_openslideconnection_cache = NULL; +static GQueue *vips_openslideconnection_unused = NULL; static GMutex vips_openslideconnection_lock; /* Added in 4.0 ... this is a tile cache that's shared between all active @@ -73,80 +76,31 @@ openslide_cache_t *vips_openslideconnection_openslide_cache; static void vips_openslideconnection_free(VipsOpenslideConnection *connection) { - VipsOpenslideConnection *cached = + VipsOpenslideConnection *cached G_GNUC_UNUSED = g_hash_table_lookup(vips_openslideconnection_cache, connection->filename); g_assert(cached); g_assert(cached == connection); g_hash_table_remove(vips_openslideconnection_cache, connection->filename); + g_queue_remove(vips_openslideconnection_unused, connection); - g_mutex_clear(&connection->lock); - VIPS_FREE(connection->filename); + g_mutex_lock(&connection->osr_lock); VIPS_FREEF(openslide_close, connection->osr); + g_mutex_unlock(&connection->osr_lock); + g_mutex_clear(&connection->osr_lock); + VIPS_FREE(connection->filename); g_free(connection); } -static void -vips_openslideconnection_unused_cb(gpointer key, gpointer value, gpointer data) -{ - VipsOpenslideConnection *connection = (VipsOpenslideConnection *) value; - int *count = (int *) data; - - g_mutex_lock(&connection->lock); - - if (connection->ref_count == 0) - *count += 1; - - g_mutex_unlock(&connection->lock); -} - -static int -vips_openslideconnection_unused(void) -{ - int unused; - - unused = 0; - g_hash_table_foreach(vips_openslideconnection_cache, - vips_openslideconnection_unused_cb, &unused); - - return unused; -} - -static void -vips_openslideconnection_oldest_cb(gpointer key, gpointer value, gpointer data) -{ - VipsOpenslideConnection *connection = (VipsOpenslideConnection *) value; - VipsOpenslideConnection **oldest = (VipsOpenslideConnection **) data; - - g_mutex_lock(&connection->lock); - - if (!*oldest || - connection->time < (*oldest)->time) - *oldest = connection; - - g_mutex_unlock(&connection->lock); -} - -static VipsOpenslideConnection * -vips_openslideconnection_oldest(void) -{ - VipsOpenslideConnection *oldest; - - oldest = NULL; - g_hash_table_foreach(vips_openslideconnection_cache, - vips_openslideconnection_oldest_cb, &oldest); - - return oldest; -} - static void vips_openslideconnection_trim(void) { VipsOpenslideConnection *oldest; - while (vips_openslideconnection_unused() > OPENSLIDECONNECTION && - (oldest = vips_openslideconnection_oldest())) + while (vips_openslideconnection_unused->length > OPENSLIDECONNECTION) { + oldest = g_queue_pop_head(vips_openslideconnection_unused); vips_openslideconnection_free(oldest); + } } static void @@ -155,8 +109,6 @@ vips_openslideconnection_unref(VipsOpenslideConnection *connection) gboolean trim; gboolean free; - g_mutex_lock(&connection->lock); - g_assert(connection->ref_count > 0); trim = FALSE; @@ -175,24 +127,23 @@ vips_openslideconnection_unref(VipsOpenslideConnection *connection) trim = TRUE; } - g_mutex_unlock(&connection->lock); - if (free) vips_openslideconnection_free(connection); - else if (trim) + else if (trim) { + g_queue_push_tail(vips_openslideconnection_unused, connection); vips_openslideconnection_trim(); + } } static void vips_openslideconnection_ref(VipsOpenslideConnection *connection) { - g_mutex_lock(&connection->lock); - g_assert(connection->ref_count >= 0); - connection->ref_count += 1; + if (connection->ref_count == 0) + g_queue_remove(vips_openslideconnection_unused, connection); - g_mutex_unlock(&connection->lock); + connection->ref_count += 1; } static VipsOpenslideConnection * @@ -211,18 +162,6 @@ vips_openslideconnection_new(const char *filename) return connection; } -static void -vips_openslideconnection_touch(VipsOpenslideConnection *connection) -{ - static int time = 0; - - g_mutex_lock(&connection->lock); - - connection->time = time++; - - g_mutex_unlock(&connection->lock); -} - openslide_t * vips__openslideconnection_open(const char *filename, gboolean revalidate) { @@ -231,6 +170,8 @@ vips__openslideconnection_open(const char *filename, gboolean revalidate) if (!vips_openslideconnection_cache) { vips_openslideconnection_cache = g_hash_table_new(g_str_hash, g_str_equal); + vips_openslideconnection_unused = + g_queue_new(); #ifdef HAVE_OPENSLIDE_CACHE_CREATE vips_openslideconnection_openslide_cache = @@ -252,11 +193,10 @@ vips__openslideconnection_open(const char *filename, gboolean revalidate) connection = vips_openslideconnection_new(filename); vips_openslideconnection_ref(connection); - vips_openslideconnection_touch(connection); g_mutex_unlock(&vips_openslideconnection_lock); - g_mutex_lock(&connection->lock); + g_mutex_lock(&connection->osr_lock); gboolean unref; @@ -271,20 +211,22 @@ vips__openslideconnection_open(const char *filename, gboolean revalidate) */ if (!connection->osr) unref = TRUE; - } - #ifdef HAVE_OPENSLIDE_CACHE_CREATE - if (connection->osr) - openslide_set_cache(connection->osr, - vips_openslideconnection_openslide_cache); + else + openslide_set_cache(connection->osr, + vips_openslideconnection_openslide_cache); #endif /*HAVE_OPENSLIDE_CACHE_CREATE*/ + } openslide_t *osr = connection->osr; - g_mutex_unlock(&connection->lock); + g_mutex_unlock(&connection->osr_lock); - if (unref) + if (unref) { + g_mutex_lock(&vips_openslideconnection_lock); vips_openslideconnection_unref(connection); + g_mutex_unlock(&vips_openslideconnection_lock); + } return osr; } From 6db4a71ff971190395d8897dd264331e490c8025 Mon Sep 17 00:00:00 2001 From: Benjamin Gilbert Date: Mon, 7 Apr 2025 06:12:42 -0400 Subject: [PATCH 112/174] openslideload: drop support for OpenSlide 3.3.x (#4454) OpenSlide 3.4.0 was released in January 2014. --- libvips/foreign/openslideload.c | 31 ------------------------------- meson.build | 3 +-- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/libvips/foreign/openslideload.c b/libvips/foreign/openslideload.c index 427c80cee6..2314fc4b60 100644 --- a/libvips/foreign/openslideload.c +++ b/libvips/foreign/openslideload.c @@ -143,7 +143,6 @@ typedef struct { static int vips__openslide_isslide(const char *filename) { -#ifdef HAVE_OPENSLIDE_3_4 const char *vendor; int ok; @@ -159,36 +158,6 @@ vips__openslide_isslide(const char *filename) VIPS_DEBUG_MSG("vips__openslide_isslide: %s - %d\n", filename, ok); return ok; -#else - openslide_t *osr; - int ok; - - ok = 0; - osr = vips__openslideconnection_open(filename, FALSE); - - if (osr) { - const char *vendor; - - /* Generic tiled tiff images can be opened by openslide as - * well. Only offer to load this file if it's not a generic - * tiff since we want vips_tiffload() to handle these. - */ - vendor = openslide_get_property_value(osr, - OPENSLIDE_PROPERTY_NAME_VENDOR); - - /* vendor will be NULL if osr is in error state. - */ - if (vendor && - strcmp(vendor, "generic-tiff") != 0) - ok = 1; - - vips__openslideconnection_close(filename); - } - - VIPS_DEBUG_MSG("vips__openslide_isslide: %s - %d\n", filename, ok); - - return ok; -#endif } static void diff --git a/meson.build b/meson.build index e48dfd6c6d..2b0e993970 100644 --- a/meson.build +++ b/meson.build @@ -392,7 +392,7 @@ if librsvg_found cfg_var.set('HAVE_RSVG_HANDLE_SET_STYLESHEET', cc.has_function('rsvg_handle_set_stylesheet', dependencies: librsvg_dep)) endif -openslide_dep = dependency('openslide', version: '>=3.3.0', required: get_option('openslide')) +openslide_dep = dependency('openslide', version: '>=3.4.0', required: get_option('openslide')) openslide_module = false if openslide_dep.found() openslide_module = modules_enabled and not get_option('openslide-module').disabled() @@ -403,7 +403,6 @@ if openslide_dep.found() external_deps += openslide_dep endif cfg_var.set('HAVE_OPENSLIDE', true) - cfg_var.set('HAVE_OPENSLIDE_3_4', openslide_dep.version().version_compare('>=3.4.0')) cfg_var.set('HAVE_OPENSLIDE_ICC', cc.has_function('openslide_get_icc_profile_size', dependencies: openslide_dep)) cfg_var.set('HAVE_OPENSLIDE_CACHE_CREATE', cc.has_function('openslide_cache_create', dependencies: openslide_dep)) endif From 0c12e29b5c7b236125e3d25e1283158e00bc2ea5 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 7 Apr 2025 11:53:21 +0100 Subject: [PATCH 113/174] revise and test openslideconnection --- ChangeLog | 1 + libvips/foreign/openslideconnection.c | 90 ++++++++++++++++++--------- libvips/iofuncs/init.c | 7 +++ 3 files changed, 68 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79db190457..38ef28f5d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,7 @@ master - heifload: improve detection of seek beyond EOF [lovell] - add "oneshot" option to jp2kload [mbklein] - share and reuse openslide connections +- drop support for openslide 3.3 8.16.1 diff --git a/libvips/foreign/openslideconnection.c b/libvips/foreign/openslideconnection.c index e6e99b0bb3..9ddf5bba67 100644 --- a/libvips/foreign/openslideconnection.c +++ b/libvips/foreign/openslideconnection.c @@ -27,6 +27,7 @@ /* #define VIPS_DEBUG +#define DEBUG */ #ifdef HAVE_CONFIG_H @@ -47,7 +48,7 @@ #define OPENSLIDECONNECTION (3) // a tile cache shared between all active openslide connections ... 32mb -#define OPENSLIDECONNECTION_CACHE_SIZE (32 * 1024 * 1024) +#define OPENSLIDECONNECTION_CACHE_SIZE (64 * 1024 * 1024) typedef struct _VipsOpenslideConnection { char *filename; @@ -76,6 +77,10 @@ openslide_cache_t *vips_openslideconnection_openslide_cache; static void vips_openslideconnection_free(VipsOpenslideConnection *connection) { +#ifdef DEBUG + printf("vips_openslideconnection_free: %s\n", connection->filename); +#endif /*DEBUG*/ + VipsOpenslideConnection *cached G_GNUC_UNUSED = g_hash_table_lookup(vips_openslideconnection_cache, connection->filename); @@ -95,10 +100,9 @@ vips_openslideconnection_free(VipsOpenslideConnection *connection) static void vips_openslideconnection_trim(void) { - VipsOpenslideConnection *oldest; - while (vips_openslideconnection_unused->length > OPENSLIDECONNECTION) { - oldest = g_queue_pop_head(vips_openslideconnection_unused); + VipsOpenslideConnection *oldest = + g_queue_pop_head(vips_openslideconnection_unused); vips_openslideconnection_free(oldest); } } @@ -106,38 +110,35 @@ vips_openslideconnection_trim(void) static void vips_openslideconnection_unref(VipsOpenslideConnection *connection) { - gboolean trim; - gboolean free; +#ifdef DEBUG + printf("vips_openslideconnection_unref: %s\n", connection->filename); +#endif /*DEBUG*/ g_assert(connection->ref_count > 0); - trim = FALSE; - free = FALSE; - connection->ref_count -= 1; if (connection->ref_count == 0) { - /* If the openslide_t is in an error state, don't leave it in the - * cache. + /* If the openslide_t is in an error state, or we've no connection, + * don't leave it in the cache. */ - if (connection->osr && + if (!connection->osr || openslide_get_error(connection->osr)) - free = TRUE; - else - trim = TRUE; - } - - if (free) - vips_openslideconnection_free(connection); - else if (trim) { - g_queue_push_tail(vips_openslideconnection_unused, connection); - vips_openslideconnection_trim(); + vips_openslideconnection_free(connection); + else { + g_queue_push_tail(vips_openslideconnection_unused, connection); + vips_openslideconnection_trim(); + } } } static void vips_openslideconnection_ref(VipsOpenslideConnection *connection) { +#ifdef DEBUG + printf("vips_openslideconnection_ref: %s\n", connection->filename); +#endif /*DEBUG*/ + g_assert(connection->ref_count >= 0); if (connection->ref_count == 0) @@ -149,6 +150,10 @@ vips_openslideconnection_ref(VipsOpenslideConnection *connection) static VipsOpenslideConnection * vips_openslideconnection_new(const char *filename) { +#ifdef DEBUG + printf("vips_openslideconnection_new: %s\n", filename); +#endif /*DEBUG*/ + VipsOpenslideConnection *connection; connection = g_new0(VipsOpenslideConnection, 1); @@ -165,13 +170,17 @@ vips_openslideconnection_new(const char *filename) openslide_t * vips__openslideconnection_open(const char *filename, gboolean revalidate) { +#ifdef DEBUG + printf("vips_openslideconnection_open: %s, revalidate = %d\n", + filename, revalidate); +#endif /*DEBUG*/ + g_mutex_lock(&vips_openslideconnection_lock); if (!vips_openslideconnection_cache) { vips_openslideconnection_cache = g_hash_table_new(g_str_hash, g_str_equal); - vips_openslideconnection_unused = - g_queue_new(); + vips_openslideconnection_unused = g_queue_new(); #ifdef HAVE_OPENSLIDE_CACHE_CREATE vips_openslideconnection_openslide_cache = @@ -207,12 +216,14 @@ vips__openslideconnection_open(const char *filename, gboolean revalidate) if (!connection->osr) { connection->osr = openslide_open(connection->filename); - /* If open fails, we must unref the connection since we'll return NULL. + /* If open fails, we must unref the connection, since we'll return + * NULL. */ if (!connection->osr) unref = TRUE; + #ifdef HAVE_OPENSLIDE_CACHE_CREATE - else + if (connection->osr) openslide_set_cache(connection->osr, vips_openslideconnection_openslide_cache); #endif /*HAVE_OPENSLIDE_CACHE_CREATE*/ @@ -234,18 +245,37 @@ vips__openslideconnection_open(const char *filename, gboolean revalidate) void vips__openslideconnection_close(const char *filename) { +#ifdef DEBUG + printf("vips_openslideconnection_close: %s\n", filename); +#endif /*DEBUG*/ + g_mutex_lock(&vips_openslideconnection_lock); VipsOpenslideConnection *connection; connection = g_hash_table_lookup(vips_openslideconnection_cache, filename); - - /* We unref in the main lock since openslide_close() is always relatively - * quick. - */ if (connection) vips_openslideconnection_unref(connection); g_mutex_unlock(&vips_openslideconnection_lock); } +int +vips__openslideconnection_leak(void) +{ + int n_leaks; + + g_mutex_lock(&vips_openslideconnection_lock); + + n_leaks = g_hash_table_size(vips_openslideconnection_cache) - + vips_openslideconnection_unused->length; + + g_mutex_unlock(&vips_openslideconnection_lock); + + if (n_leaks > 0) + printf("vips__openslideconnection_leak: %d leaked connections\n", + n_leaks); + + return n_leaks; +} + #endif /*HAVE_OPENSLIDE*/ diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index d80cef7689..81b483a39f 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -136,6 +136,10 @@ GQuark vips__image_pixels_quark = 0; */ static char *vips__max_coord_arg = NULL; +#ifdef HAVE_OPENSLIDE +int vips__openslideconnection_leak(void); +#endif /*HAVE_OPENSLIDE*/ + /** * vips_max_coord_get: * @@ -391,6 +395,9 @@ vips_leak(void) n_leaks += vips_tracked_get_allocs(); n_leaks += vips_tracked_get_mem(); n_leaks += vips_tracked_get_files(); +#ifdef HAVE_OPENSLIDE + n_leaks += vips__openslideconnection_leak(); +#endif /*HAVE_OPENSLIDE*/ if (vips_tracked_get_allocs() || vips_tracked_get_mem() || From dbc3b86054208b2d9915e5ebdf7a0c3d022013e0 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 7 Apr 2025 12:47:06 +0100 Subject: [PATCH 114/174] try renaming some sections (#4453) maybe we can make the extra docs section a little easier to read --- doc/binding.md | 2 -- doc/cite.md | 2 -- doc/developer-checklist.md | 2 -- doc/examples.md | 2 -- doc/extending.md | 2 -- doc/file-format.md | 2 -- doc/function-list.md | 4 +--- doc/how-it-opens-files.md | 2 -- doc/how-it-works.md | 2 -- doc/libvips-arithmetic.md | 4 +--- doc/libvips-basic.md | 4 +--- doc/libvips-colour.md | 4 +--- doc/libvips-conversion.md | 4 +--- doc/libvips-convolution.md | 4 +--- doc/libvips-create.md | 4 +--- doc/libvips-draw.md | 4 +--- doc/libvips-error.md | 4 +--- doc/libvips-freqfilt.md | 4 +--- doc/libvips-generate.md | 4 +--- doc/libvips-header.md | 4 +--- doc/libvips-histogram.md | 4 +--- doc/libvips-memory.md | 4 +--- doc/libvips-morphology.md | 4 +--- doc/libvips-mosaicing.md | 4 +--- doc/libvips-resample.md | 4 +--- doc/libvips-vips.md | 4 +--- doc/making-image-pyramids.md | 2 -- doc/multipage-and-animated-images.md | 2 -- doc/using-from-c.md | 2 -- doc/using-from-cplusplus.md | 2 -- doc/using-the-cli.md | 2 -- doc/using-threads.md | 2 -- doc/using-vipsthumbnail.md | 2 -- doc/vips.toml.in | 22 +++++++++++++--------- 34 files changed, 31 insertions(+), 93 deletions(-) diff --git a/doc/binding.md b/doc/binding.md index db087e07d5..053a4e1f1e 100644 --- a/doc/binding.md +++ b/doc/binding.md @@ -1,7 +1,5 @@ Title: Writing bindings for libvips -# Writing bindings for libvips - There are full libvips bindings for quite a few environments now, including C, C++, command-line, Ruby, PHP, Lua, Python, Crystal, Elixir, and JavaScript (Node.js). diff --git a/doc/cite.md b/doc/cite.md index d87032e1d5..a8e9daa51d 100644 --- a/doc/cite.md +++ b/doc/cite.md @@ -1,7 +1,5 @@ Title: References to cite for libvips -# libvips References - Cupitt, J., Martinez, K., Fuller, L. and Wolthuizen, K. A. (2025) [The libvips image processing library]( https://www.southampton.ac.uk/~km2/papers/2025/vips-ist-preprint.pdf). In Proceedings of Electronic diff --git a/doc/developer-checklist.md b/doc/developer-checklist.md index 5ebd552c6a..bf0313ca7e 100644 --- a/doc/developer-checklist.md +++ b/doc/developer-checklist.md @@ -1,7 +1,5 @@ Title: Checklist for libvips users -## Checklist for libvips users - libvips is a slightly unusual library and you may need to take some of its stranger features into account when you design software that uses it. diff --git a/doc/examples.md b/doc/examples.md index cf66b56a79..4a98d7beea 100644 --- a/doc/examples.md +++ b/doc/examples.md @@ -1,7 +1,5 @@ Title: A few example Python programs using libvips -# A few example Python programs using libvips - This page shows a few libvips examples using Python. They will work with small syntax changes in any language with a libvips binding. diff --git a/doc/extending.md b/doc/extending.md index c9146dc958..f1d37136af 100644 --- a/doc/extending.md +++ b/doc/extending.md @@ -1,7 +1,5 @@ Title: How to add operations to libvips -# How to add operations to libvips - This section runs quickly through adding a simple operator to libvips. For more information, see [class@Operation] and [class@Region]. A good starting point for a new operation is a similar one in libvips. diff --git a/doc/file-format.md b/doc/file-format.md index bf152a3393..1f94626cfb 100644 --- a/doc/file-format.md +++ b/doc/file-format.md @@ -1,7 +1,5 @@ Title: The libvips file format -# The libvips file format - libvips has a simple, native file format. It's very fast, there is no image size limit, and it supports arbitrary metadata. Although few other programs can read these images (though recent versions of ImageMagick do have basic diff --git a/doc/function-list.md b/doc/function-list.md index 3a68f74c66..b2b447485a 100644 --- a/doc/function-list.md +++ b/doc/function-list.md @@ -1,6 +1,4 @@ -Title: All libvips functions and operators - -# Introduction +Title: Index -- all operators in alphabetical order libvips has a set of operators, each of which computes some useful image processing operation. Each operator is implemented as a [class@GObject.Object] diff --git a/doc/how-it-opens-files.md b/doc/how-it-opens-files.md index 967f0d71b3..8297412496 100644 --- a/doc/how-it-opens-files.md +++ b/doc/how-it-opens-files.md @@ -1,7 +1,5 @@ Title: How libvips opens files -# How libvips opens files - libvips has at least four different ways of opening image files, each best for different file types, file sizes and image use cases. libvips tries hard to pick the best strategy in each case and mostly you don't need to diff --git a/doc/how-it-works.md b/doc/how-it-works.md index b10e1f4039..8e7da5e498 100644 --- a/doc/how-it-works.md +++ b/doc/how-it-works.md @@ -1,7 +1,5 @@ Title: A high-level technical overview of libvips's evaluation system -# A high-level technical overview of libvips's evaluation system - Compared to most image processing libraries, libvips needs little RAM and runs quickly, especially on machines with more than one CPU. libvips achieves this improvement by only keeping the pixels currently being processed in RAM diff --git a/doc/libvips-arithmetic.md b/doc/libvips-arithmetic.md index 192aaea758..ad29c52506 100644 --- a/doc/libvips-arithmetic.md +++ b/doc/libvips-arithmetic.md @@ -1,9 +1,7 @@ -Title: Pixel arithmetic +Title: Operators by section -- Pixel arithmetic -# Pixel arithmetic - These operations perform pixel arithmetic, that is, they perform an arithmetic operation, such as addition, on every pixel in an image or a pair of images. All (except in a few cases noted below) will work with diff --git a/doc/libvips-basic.md b/doc/libvips-basic.md index a5cea0705b..943bd565c1 100644 --- a/doc/libvips-basic.md +++ b/doc/libvips-basic.md @@ -1,9 +1,7 @@ -Title: Aliases, helpers and macros +Title: Operators by section -- Aliases, helpers and macros -# Aliases, helpers and macros - A selection of basic aliases, [alias@GObject.Type] helpers and macro definitions used by libvips. diff --git a/doc/libvips-colour.md b/doc/libvips-colour.md index 3ed084e4e1..13823c6abb 100644 --- a/doc/libvips-colour.md +++ b/doc/libvips-colour.md @@ -1,9 +1,7 @@ -Title: Colour operators +Title: Operators by section -- Colour operators -# Colour operators - These operators let you transform coordinates and images between colour spaces, calculate colour differences, and move to and from device spaces. diff --git a/doc/libvips-conversion.md b/doc/libvips-conversion.md index 405d51cd0e..d91638c18b 100644 --- a/doc/libvips-conversion.md +++ b/doc/libvips-conversion.md @@ -1,9 +1,7 @@ -Title: Convert images in some way +Title: Operators by section -- Convert images in some way -# Convert images in some way - These operations convert an image in some way. They can be split into two main groups. diff --git a/doc/libvips-convolution.md b/doc/libvips-convolution.md index 64fe02d2b4..155a05ae49 100644 --- a/doc/libvips-convolution.md +++ b/doc/libvips-convolution.md @@ -1,9 +1,7 @@ -Title: Convolve and correlate images +Title: Operators by section -- Convolve and correlate images -# Convolve and correlate images - These operations convolve an image in some way, or are operations based on simple convolution, or are useful with convolution. diff --git a/doc/libvips-create.md b/doc/libvips-create.md index ac349fc6b7..0a352868ac 100644 --- a/doc/libvips-create.md +++ b/doc/libvips-create.md @@ -1,9 +1,7 @@ -Title: Create images +Title: Operators by section -- Create images -# Create images - These functions generate various images. You can combine them with the arithmetic and rotate functions to build more complicated images. diff --git a/doc/libvips-draw.md b/doc/libvips-draw.md index 89e0104f2c..3fd5354c25 100644 --- a/doc/libvips-draw.md +++ b/doc/libvips-draw.md @@ -1,9 +1,7 @@ -Title: Drawing operations +Title: Operators by section -- Drawing operations -# Drawing operations - These operations directly modify the image. They do not thread, on 32-bit machines they will be limited to 2GB images, and a little care needs to be taken if you use them as part of an image pipeline. They are mostly supposed diff --git a/doc/libvips-error.md b/doc/libvips-error.md index 0593f53ea2..2de07de1d1 100644 --- a/doc/libvips-error.md +++ b/doc/libvips-error.md @@ -1,9 +1,7 @@ -Title: Error messages and error handling +Title: Operators by section -- Error messages and error handling -# Error messages and error handling - libvips maintains an error buffer (a log of localised text messages), a set of functions for adding messages, and a way to access and clear the buffer. diff --git a/doc/libvips-freqfilt.md b/doc/libvips-freqfilt.md index 6acff1a471..af4672222c 100644 --- a/doc/libvips-freqfilt.md +++ b/doc/libvips-freqfilt.md @@ -1,9 +1,7 @@ -Title: Fourier transforms and frequency-domain filters +Title: Operators by section -- Fourier transforms and frequency-domain filters -# Fourier transforms and frequency-domain filters - To and from Fourier space, filter in Fourier space, convert Fourier-space images to a displayable form. diff --git a/doc/libvips-generate.md b/doc/libvips-generate.md index 2929562bc0..ee445f6051 100644 --- a/doc/libvips-generate.md +++ b/doc/libvips-generate.md @@ -1,9 +1,7 @@ -Title: Calculate pixels and pixel buffers +Title: Operators by section -- Calculate pixels and pixel buffers -# Calculate pixels and pixel buffers - These functions let you attach generate functions to images and ask for regions of images to be calculated. diff --git a/doc/libvips-header.md b/doc/libvips-header.md index de22907493..083ca2b4a7 100644 --- a/doc/libvips-header.md +++ b/doc/libvips-header.md @@ -1,9 +1,7 @@ -Title: Image headers +Title: Operators by section -- Image headers -# Image headers - libvips supports getting and setting image header data (including metadata) in a uniform way. diff --git a/doc/libvips-histogram.md b/doc/libvips-histogram.md index 980e6e0242..1e382244df 100644 --- a/doc/libvips-histogram.md +++ b/doc/libvips-histogram.md @@ -1,9 +1,7 @@ -Title: Find, manipulate and apply histograms and lookup tables +Title: Operators by section -- Find, manipulate and apply histograms and lookup tables -# Find, manipulate and apply histograms and lookup tables - Histograms and look-up tables are 1xn or nx1 images, where n is less than 256 or less than 65536, corresponding to 8- and 16-bit unsigned int images. They are tagged with a [enum@Interpretation] of diff --git a/doc/libvips-memory.md b/doc/libvips-memory.md index ffa4dd455f..0f3c7d35ea 100644 --- a/doc/libvips-memory.md +++ b/doc/libvips-memory.md @@ -1,9 +1,7 @@ -Title: Memory utilities +Title: Operators by section -- Memory utilities -# Memory utilities - These functions cover two main areas. First, some simple utility functions over the underlying [func@GLib.malloc] / diff --git a/doc/libvips-morphology.md b/doc/libvips-morphology.md index 0abe037b07..8c8929e58c 100644 --- a/doc/libvips-morphology.md +++ b/doc/libvips-morphology.md @@ -1,9 +1,7 @@ -Title: Morphological operators +Title: Operators by section -- Morphological operators -# Morphological operators - The morphological functions search images for particular patterns of pixels, specified with the mask argument, either adding or removing pixels when they find a match. They are useful for cleaning up images --- for example, you diff --git a/doc/libvips-mosaicing.md b/doc/libvips-mosaicing.md index 5058e6f707..ada51504e3 100644 --- a/doc/libvips-mosaicing.md +++ b/doc/libvips-mosaicing.md @@ -1,9 +1,7 @@ -Title: Build image mosaics +Title: Operators by section -- Build image mosaics -# Build image mosaics - These functions are useful for joining many small images together to make one large image. They can cope with unstable contrast and arbitrary sub-image layout, but will not do any geometric correction. Geometric errors should be diff --git a/doc/libvips-resample.md b/doc/libvips-resample.md index 78b1da781f..c3007528dc 100644 --- a/doc/libvips-resample.md +++ b/doc/libvips-resample.md @@ -1,9 +1,7 @@ -Title: Resample operations +Title: Operators by section -- Resample operations -# Resample operations - These operations build on each other in a set of layers. First, [method@Image.affine] applies an affine transform to an image. This diff --git a/doc/libvips-vips.md b/doc/libvips-vips.md index d8c52f897c..16d9324414 100644 --- a/doc/libvips-vips.md +++ b/doc/libvips-vips.md @@ -1,9 +1,7 @@ -Title: Initialize, finalize and version information +Title: Operators by section -- Initialize, finalize and version information -# Initialize, finalize and version information - These functions handle the initialization, finalization, version retrieval, and relocation for libvips. diff --git a/doc/making-image-pyramids.md b/doc/making-image-pyramids.md index 9bf627921b..03a3003afd 100644 --- a/doc/making-image-pyramids.md +++ b/doc/making-image-pyramids.md @@ -1,7 +1,5 @@ Title: How to use libvips to make image pyramids -# How to use libvips to make image pyramids - libvips includes [method@Image.dzsave], an operation that can build image pyramids compatible with [DeepZoom](http://en.wikipedia.org/wiki/Deep_Zoom), Zoomify and [Google Maps](https://developers.google.com/maps) image viewers. diff --git a/doc/multipage-and-animated-images.md b/doc/multipage-and-animated-images.md index feec8cb95b..2cae0e7527 100644 --- a/doc/multipage-and-animated-images.md +++ b/doc/multipage-and-animated-images.md @@ -1,7 +1,5 @@ Title: Processing multipage and animated images -# Processing multipage and animated images - libvips represents animated and multipage images as tall, thin strips of frames, like a strip of movie film (or a roll of toilet paper). Special image metadata items are used to hold the page height, the number of frames, and any diff --git a/doc/using-from-c.md b/doc/using-from-c.md index 6def1f0fad..ee658fb7f9 100644 --- a/doc/using-from-c.md +++ b/doc/using-from-c.md @@ -1,7 +1,5 @@ Title: Using libvips from C -# Using libvips from C - libvips comes with a convenient, high-level C API. You should read the API docs for full details, but this section will try to give a brief overview. diff --git a/doc/using-from-cplusplus.md b/doc/using-from-cplusplus.md index 11671eb155..8e4cb9e72b 100644 --- a/doc/using-from-cplusplus.md +++ b/doc/using-from-cplusplus.md @@ -1,7 +1,5 @@ Title: Using libvips from C++ -# Using libvips from C++ - libvips comes with a convenient C++ API. It is a very thin wrapper over the C API and adds automatic reference counting, exceptions, operator overloads, and automatic constant expansion. diff --git a/doc/using-the-cli.md b/doc/using-the-cli.md index 82799c7aaf..11ea4ef59e 100644 --- a/doc/using-the-cli.md +++ b/doc/using-the-cli.md @@ -1,7 +1,5 @@ Title: Using libvips at the command-line -# Using libvips at the command-line - Use the `vips` command to execute libvips operations from the command-line. For example: diff --git a/doc/using-threads.md b/doc/using-threads.md index 74e0bc45e1..a5ce996c4c 100644 --- a/doc/using-threads.md +++ b/doc/using-threads.md @@ -1,7 +1,5 @@ Title: Using threads -# Using threads - This section tries to summarise the rules for threaded programs using libvips. Generally, libvips is threaded and thread-safe, with a few exceptions. diff --git a/doc/using-vipsthumbnail.md b/doc/using-vipsthumbnail.md index e624dc1a6d..5a7eb2150e 100644 --- a/doc/using-vipsthumbnail.md +++ b/doc/using-vipsthumbnail.md @@ -1,7 +1,5 @@ Title: Using vipsthumbnail -# Using vipsthumbnail - libvips ships with a handy command-line image thumbnailer, `vipsthumbnail`. This page introduces it, with some examples. diff --git a/doc/vips.toml.in b/doc/vips.toml.in index 9be7de92f1..a77de08da6 100644 --- a/doc/vips.toml.in +++ b/doc/vips.toml.in @@ -40,20 +40,12 @@ content_files = [ "using-the-cli.md", "using-from-c.md", "using-from-cplusplus.md", - "developer-checklist.md", - "using-threads.md", - "function-list.md", "making-image-pyramids.md", "multipage-and-animated-images.md", "using-vipsthumbnail.md", - "how-it-works.md", - "how-it-opens-files.md", - "file-format.md", - "extending.md", - "binding.md", "examples.md", - "cite.md", + "function-list.md", "libvips-arithmetic.md", "libvips-basic.md", "libvips-colour.md", @@ -71,6 +63,18 @@ content_files = [ "libvips-mosaicing.md", "libvips-resample.md", "libvips-vips.md", + + "using-threads.md", + "how-it-works.md", + "how-it-opens-files.md", + "developer-checklist.md", + "file-format.md", + + "extending.md", + "binding.md", + + "cite.md", + ] content_images = [ "images/Combine.png", From a39ba73675cc403bbed7f76a5e404cc32cfb7d50 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 7 Apr 2025 14:29:49 +0200 Subject: [PATCH 115/174] openslideconnection: fix link failure with modules enabled (#4456) --- libvips/include/vips/internal.h | 4 ++++ libvips/iofuncs/init.c | 8 ++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 88f0dbfec3..6b1ec3ed93 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -171,6 +171,10 @@ int vips__print_renders(void); int vips__type_leak(void); int vips__object_leak(void); +#ifdef HAVE_OPENSLIDE +int vips__openslideconnection_leak(void); +#endif /*HAVE_OPENSLIDE*/ + /* iofuncs */ int vips__open_image_read(const char *filename); diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 81b483a39f..5ccabd89ff 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -136,10 +136,6 @@ GQuark vips__image_pixels_quark = 0; */ static char *vips__max_coord_arg = NULL; -#ifdef HAVE_OPENSLIDE -int vips__openslideconnection_leak(void); -#endif /*HAVE_OPENSLIDE*/ - /** * vips_max_coord_get: * @@ -395,9 +391,9 @@ vips_leak(void) n_leaks += vips_tracked_get_allocs(); n_leaks += vips_tracked_get_mem(); n_leaks += vips_tracked_get_files(); -#ifdef HAVE_OPENSLIDE +#if defined(HAVE_OPENSLIDE) && !defined(OPENSLIDE_MODULE) n_leaks += vips__openslideconnection_leak(); -#endif /*HAVE_OPENSLIDE*/ +#endif /*defined(HAVE_OPENSLIDE) && !defined(OPENSLIDE_MODULE)*/ if (vips_tracked_get_allocs() || vips_tracked_get_mem() || From fd8e9f323428afef3a653f6ac287184db5018e03 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 7 Apr 2025 20:35:53 +0200 Subject: [PATCH 116/174] Regenerate POTFILES.in and C++ binding (#4458) --- cplusplus/include/vips/VImage8.h | 25 +++++++++++++++++++++---- cplusplus/vips-operators.cpp | 13 +++++++++++++ po/POTFILES.in | 5 ++++- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h index 2e00951f6e..c132a240d1 100644 --- a/cplusplus/include/vips/VImage8.h +++ b/cplusplus/include/vips/VImage8.h @@ -3765,6 +3765,7 @@ class VImage : public VObject { * * **Optional parameters** * - **page** -- Load this page from the image, int. + * - **oneshot** -- Load images a frame at a time, bool. * - **memory** -- Force open via memory, bool. * - **access** -- Required access pattern for this file, VipsAccess. * - **fail_on** -- Error level to fail on, VipsFailOn. @@ -3781,6 +3782,7 @@ class VImage : public VObject { * * **Optional parameters** * - **page** -- Load this page from the image, int. + * - **oneshot** -- Load images a frame at a time, bool. * - **memory** -- Force open via memory, bool. * - **access** -- Required access pattern for this file, VipsAccess. * - **fail_on** -- Error level to fail on, VipsFailOn. @@ -3797,6 +3799,7 @@ class VImage : public VObject { * * **Optional parameters** * - **page** -- Load this page from the image, int. + * - **oneshot** -- Load images a frame at a time, bool. * - **memory** -- Force open via memory, bool. * - **access** -- Required access pattern for this file, VipsAccess. * - **fail_on** -- Error level to fail on, VipsFailOn. @@ -4520,7 +4523,7 @@ class VImage : public VObject { static VImage matload(const char *filename, VOption *options = nullptr); /** - * Invert an matrix. + * Invert a matrix. * @param options Set of options. * @return Output matrix. */ @@ -4556,6 +4559,14 @@ class VImage : public VObject { */ static VImage matrixload_source(VSource source, VOption *options = nullptr); + /** + * Multiply two matrices. + * @param right Second matrix to multiply. + * @param options Set of options. + * @return Output matrix. + */ + VImage matrixmultiply(VImage right, VOption *options = nullptr) const; + /** * Print matrix. * @@ -5758,6 +5769,7 @@ class VImage : public VObject { * - **dpi** -- Render at this DPI, double. * - **scale** -- Scale output by this factor, double. * - **unlimited** -- Allow SVG of any size, bool. + * - **stylesheet** -- Custom CSS, const char *. * - **memory** -- Force open via memory, bool. * - **access** -- Required access pattern for this file, VipsAccess. * - **fail_on** -- Error level to fail on, VipsFailOn. @@ -5776,6 +5788,7 @@ class VImage : public VObject { * - **dpi** -- Render at this DPI, double. * - **scale** -- Scale output by this factor, double. * - **unlimited** -- Allow SVG of any size, bool. + * - **stylesheet** -- Custom CSS, const char *. * - **memory** -- Force open via memory, bool. * - **access** -- Required access pattern for this file, VipsAccess. * - **fail_on** -- Error level to fail on, VipsFailOn. @@ -5794,6 +5807,7 @@ class VImage : public VObject { * - **dpi** -- Render at this DPI, double. * - **scale** -- Scale output by this factor, double. * - **unlimited** -- Allow SVG of any size, bool. + * - **stylesheet** -- Custom CSS, const char *. * - **memory** -- Force open via memory, bool. * - **access** -- Required access pattern for this file, VipsAccess. * - **fail_on** -- Error level to fail on, VipsFailOn. @@ -5937,9 +5951,10 @@ class VImage : public VObject { * * **Optional parameters** * - **page** -- First page to load, int. - * - **subifd** -- Subifd index, int. * - **n** -- Number of pages to load, -1 for all, int. * - **autorotate** -- Rotate image using orientation tag, bool. + * - **subifd** -- Subifd index, int. + * - **unlimited** -- Remove all denial of service limits, bool. * - **memory** -- Force open via memory, bool. * - **access** -- Required access pattern for this file, VipsAccess. * - **fail_on** -- Error level to fail on, VipsFailOn. @@ -5956,9 +5971,10 @@ class VImage : public VObject { * * **Optional parameters** * - **page** -- First page to load, int. - * - **subifd** -- Subifd index, int. * - **n** -- Number of pages to load, -1 for all, int. * - **autorotate** -- Rotate image using orientation tag, bool. + * - **subifd** -- Subifd index, int. + * - **unlimited** -- Remove all denial of service limits, bool. * - **memory** -- Force open via memory, bool. * - **access** -- Required access pattern for this file, VipsAccess. * - **fail_on** -- Error level to fail on, VipsFailOn. @@ -5975,9 +5991,10 @@ class VImage : public VObject { * * **Optional parameters** * - **page** -- First page to load, int. - * - **subifd** -- Subifd index, int. * - **n** -- Number of pages to load, -1 for all, int. * - **autorotate** -- Rotate image using orientation tag, bool. + * - **subifd** -- Subifd index, int. + * - **unlimited** -- Remove all denial of service limits, bool. * - **memory** -- Force open via memory, bool. * - **access** -- Required access pattern for this file, VipsAccess. * - **fail_on** -- Error level to fail on, VipsFailOn. diff --git a/cplusplus/vips-operators.cpp b/cplusplus/vips-operators.cpp index d503bfe01c..4a60f95ecf 100644 --- a/cplusplus/vips-operators.cpp +++ b/cplusplus/vips-operators.cpp @@ -2316,6 +2316,19 @@ VImage::matrixload_source(VSource source, VOption *options) return out; } +VImage +VImage::matrixmultiply(VImage right, VOption *options) const +{ + VImage out; + + call("matrixmultiply", (options ? options : VImage::option()) + ->set("left", *this) + ->set("out", &out) + ->set("right", right)); + + return out; +} + void VImage::matrixprint(VOption *options) const { diff --git a/po/POTFILES.in b/po/POTFILES.in index 56edc92bb2..b6e0bbd415 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -249,7 +249,6 @@ libvips/foreign/jpegload.c libvips/foreign/jpegsave.c libvips/foreign/jxlload.c libvips/foreign/jxlsave.c -libvips/foreign/magick2vips.c libvips/foreign/magick6load.c libvips/foreign/magick7load.c libvips/foreign/magick.c @@ -264,6 +263,7 @@ libvips/foreign/niftisave.c libvips/foreign/nsgifload.c libvips/foreign/openexr2vips.c libvips/foreign/openexrload.c +libvips/foreign/openslideconnection.c libvips/foreign/openslideload.c libvips/foreign/pdf.c libvips/foreign/pdfiumload.c @@ -377,6 +377,7 @@ libvips/mosaicing/lrmerge.c libvips/mosaicing/lrmosaic.c libvips/mosaicing/match.c libvips/mosaicing/matrixinvert.c +libvips/mosaicing/matrixmultiply.c libvips/mosaicing/merge.c libvips/mosaicing/mosaic1.c libvips/mosaicing/mosaic.c @@ -400,7 +401,9 @@ libvips/resample/resample.c libvips/resample/resize.c libvips/resample/shrink.c libvips/resample/shrinkh.c +libvips/resample/shrinkh_hwy.cpp libvips/resample/shrinkv.c +libvips/resample/shrinkv_hwy.cpp libvips/resample/similarity.c libvips/resample/thumbnail.c libvips/resample/transform.c From 5c3fe4c2f986acf7e4410c6f88c9228865bab986 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 8 Apr 2025 11:28:13 +0100 Subject: [PATCH 117/174] fix vips_quadratic --- ChangeLog | 1 + libvips/resample/quadratic.c | 42 +++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 38ef28f5d9..9bc530f7aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,7 @@ master - add "oneshot" option to jp2kload [mbklein] - share and reuse openslide connections - drop support for openslide 3.3 +- fix vips_quadratic() 8.16.1 diff --git a/libvips/resample/quadratic.c b/libvips/resample/quadratic.c index faf6472792..807a640cd4 100644 --- a/libvips/resample/quadratic.c +++ b/libvips/resample/quadratic.c @@ -55,12 +55,12 @@ /* The transform we compute: -x',y' = coordinates of srcim -x,y = coordinates of dstim +x', y' = coordinates of srcim +x, y = coordinates of dstim a .. l = coefficients x = x' + a : order 0 image shift only - + b x' + c y' : order 1 + affine transf. + + b x' + c y' : order 1 + affine transf. + d x' y' : order 2 + bilinear transf. + e x' x' + f y' y' : order 3 + quadratic transf. @@ -159,21 +159,19 @@ vips_quadratic_gen(VipsRegion *out_region, return -1; for (yo = ylow; yo < yhigh; yo++) { - fxi = 0.0; - fyi = 0.0; + fxi = xlow + vec[0]; /* order 0 */ + fyi = yo + vec[1]; dx = 0.0; dy = 0.0; - ddx = 0.0; - ddy = 0.0; switch (quadratic->order) { case 3: fxi += vec[10] * yo * yo + vec[8] * xlow * xlow; fyi += vec[11] * yo * yo + vec[9] * xlow * xlow; dx += vec[8]; - ddx += vec[8] * 2.0; + ddx = vec[8] * 2.0; dy += vec[9]; - ddy += vec[9] * 2.0; + ddy = vec[9] * 2.0; case 2: fxi += vec[6] * xlow * yo; @@ -188,16 +186,12 @@ vips_quadratic_gen(VipsRegion *out_region, dy += vec[3]; case 0: - fxi += vec[0]; - fyi += vec[1]; break; default: g_assert_not_reached(); } - printf("dx = %g, dy = %g\n", dx, dy); - q = VIPS_REGION_ADDR(out_region, xlow, yo); for (xo = xlow; xo < xhigh; xo++) { @@ -260,8 +254,7 @@ vips_quadratic_build(VipsObject *object) if (vips_check_uncoded(class->nickname, in) || vips_check_noncomplex(class->nickname, in) || - vips_check_matrix(class->nickname, - quadratic->coeff, &quadratic->mat)) + vips_check_matrix(class->nickname, quadratic->coeff, &quadratic->mat)) return -1; if (quadratic->mat->Xsize != 2) { @@ -292,6 +285,25 @@ vips_quadratic_build(VipsObject *object) return -1; } + double *vec = VIPS_MATRIX(quadratic->mat, 0, 0); + printf("vips_quadratic_build:\n"); + printf("\ta = %g, g = %g\n", vec[0], vec[1]); + + if (quadratic->order > 0) { + printf("\t--------\n"); + printf("\tb = %g, h = %g\n", vec[2], vec[3]); + printf("\tc = %g, i = %g\n", vec[4], vec[5]); + } + if (quadratic->order > 1) { + printf("\t--------\n"); + printf("\td = %g, j = %g\n", vec[6], vec[7]); + } + if (quadratic->order > 2) { + printf("\t--------\n"); + printf("\te = %g, k = %g\n", vec[8], vec[9]); + printf("\tf = %g, l = %g\n", vec[10], vec[11]); + } + if (!quadratic->interpolate) quadratic->interpolate = vips_interpolate_new("bilinear"); // FIXME: Invalidates operation cache From ae25ff6e75cd9995df03761d2a69962b6d4cd059 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 8 Apr 2025 11:30:55 +0100 Subject: [PATCH 118/174] remove some debugging code --- libvips/resample/quadratic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libvips/resample/quadratic.c b/libvips/resample/quadratic.c index 807a640cd4..fcc9c471f0 100644 --- a/libvips/resample/quadratic.c +++ b/libvips/resample/quadratic.c @@ -285,6 +285,7 @@ vips_quadratic_build(VipsObject *object) return -1; } +#ifdef DEBUG double *vec = VIPS_MATRIX(quadratic->mat, 0, 0); printf("vips_quadratic_build:\n"); printf("\ta = %g, g = %g\n", vec[0], vec[1]); @@ -303,6 +304,7 @@ vips_quadratic_build(VipsObject *object) printf("\te = %g, k = %g\n", vec[8], vec[9]); printf("\tf = %g, l = %g\n", vec[10], vec[11]); } +#endif /*DEBUG*/ if (!quadratic->interpolate) quadratic->interpolate = vips_interpolate_new("bilinear"); // FIXME: Invalidates operation cache From f5cec9dbca668bb2d984ede30de997617c065e4a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 8 Apr 2025 15:18:15 +0100 Subject: [PATCH 119/174] another quadratic fix --- libvips/resample/quadratic.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/libvips/resample/quadratic.c b/libvips/resample/quadratic.c index fcc9c471f0..dd4efb24d9 100644 --- a/libvips/resample/quadratic.c +++ b/libvips/resample/quadratic.c @@ -144,7 +144,6 @@ vips_quadratic_gen(VipsRegion *out_region, VipsPel *q; int xo, yo; /* output coordinates, dstimage */ - int z; double fxi, fyi; /* input coordinates */ double dx, dy; /* xo derivative of input coord. */ double ddx, ddy; /* 2nd xo derivative of input coord. */ @@ -161,7 +160,7 @@ vips_quadratic_gen(VipsRegion *out_region, for (yo = ylow; yo < yhigh; yo++) { fxi = xlow + vec[0]; /* order 0 */ fyi = yo + vec[1]; - dx = 0.0; + dx = 1.0; dy = 0.0; switch (quadratic->order) { @@ -195,10 +194,8 @@ vips_quadratic_gen(VipsRegion *out_region, q = VIPS_REGION_ADDR(out_region, xlow, yo); for (xo = xlow; xo < xhigh; xo++) { - int xi, yi; - - xi = fxi; - yi = fyi; + int xi = fxi; + int yi = fyi; /* Clipping! */ @@ -206,12 +203,11 @@ vips_quadratic_gen(VipsRegion *out_region, yi < 0 || xi >= clip_width || yi >= clip_height) { - for (z = 0; z < ps; z++) + for (int z = 0; z < ps; z++) q[z] = 0; } else - interpolate_fn(quadratic->interpolate, - q, ir, fxi, fyi); + interpolate_fn(quadratic->interpolate, q, ir, fxi, fyi); q += ps; From aabb7bb9351d7b61ef2106a1dff3d77c50566f53 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 10 Apr 2025 13:04:58 +0100 Subject: [PATCH 120/174] oops fix leak test --- libvips/foreign/openslideconnection.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libvips/foreign/openslideconnection.c b/libvips/foreign/openslideconnection.c index 9ddf5bba67..61e7dcb46b 100644 --- a/libvips/foreign/openslideconnection.c +++ b/libvips/foreign/openslideconnection.c @@ -264,10 +264,13 @@ vips__openslideconnection_leak(void) { int n_leaks; + n_leaks = 0; + g_mutex_lock(&vips_openslideconnection_lock); - n_leaks = g_hash_table_size(vips_openslideconnection_cache) - - vips_openslideconnection_unused->length; + if (vips_openslideconnection_cache) + n_leaks += g_hash_table_size(vips_openslideconnection_cache) - + vips_openslideconnection_unused->length; g_mutex_unlock(&vips_openslideconnection_lock); From 103ae5baac20142f216c3cf3cddad17bc04479e4 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 10 Apr 2025 14:21:24 +0100 Subject: [PATCH 121/174] try to improve the doc index, again (#4461) * try to improve the doc index, again * Update doc/libvips-mosaicing.md Co-authored-by: Kleis Auke Wolthuizen * Update doc/libvips-histogram.md Co-authored-by: Kleis Auke Wolthuizen --------- Co-authored-by: Kleis Auke Wolthuizen --- doc/binding.md | 2 +- doc/cite.md | 2 +- doc/developer-checklist.md | 2 +- doc/examples.md | 2 +- doc/extending.md | 2 +- doc/file-format.md | 2 +- doc/function-list.md | 2 +- doc/how-it-opens-files.md | 2 +- doc/how-it-works.md | 2 +- doc/libvips-arithmetic.md | 2 +- doc/libvips-basic.md | 2 +- doc/libvips-colour.md | 2 +- doc/libvips-conversion.md | 2 +- doc/libvips-convolution.md | 2 +- doc/libvips-create.md | 2 +- doc/libvips-draw.md | 2 +- doc/libvips-error.md | 2 +- doc/libvips-freqfilt.md | 2 +- doc/libvips-generate.md | 2 +- doc/libvips-header.md | 2 +- doc/libvips-histogram.md | 2 +- doc/libvips-memory.md | 2 +- doc/libvips-morphology.md | 2 +- doc/libvips-mosaicing.md | 2 +- doc/libvips-resample.md | 2 +- doc/libvips-vips.md | 2 +- doc/making-image-pyramids.md | 2 +- doc/multipage-and-animated-images.md | 2 +- doc/using-from-c.md | 2 +- doc/using-from-cplusplus.md | 2 +- doc/using-the-cli.md | 2 +- doc/using-threads.md | 2 +- doc/using-vipsthumbnail.md | 2 +- doc/vips.toml.in | 12 ++++++------ 34 files changed, 39 insertions(+), 39 deletions(-) diff --git a/doc/binding.md b/doc/binding.md index 053a4e1f1e..12420221b5 100644 --- a/doc/binding.md +++ b/doc/binding.md @@ -1,4 +1,4 @@ -Title: Writing bindings for libvips +Title: Advanced > Writing bindings There are full libvips bindings for quite a few environments now, including C, C++, command-line, Ruby, PHP, Lua, Python, Crystal, Elixir, and JavaScript diff --git a/doc/cite.md b/doc/cite.md index a8e9daa51d..e9c4641612 100644 --- a/doc/cite.md +++ b/doc/cite.md @@ -1,4 +1,4 @@ -Title: References to cite for libvips +Title: Citing libvips Cupitt, J., Martinez, K., Fuller, L. and Wolthuizen, K. A. (2025) [The libvips image processing library]( diff --git a/doc/developer-checklist.md b/doc/developer-checklist.md index bf0313ca7e..86aa3f61a5 100644 --- a/doc/developer-checklist.md +++ b/doc/developer-checklist.md @@ -1,4 +1,4 @@ -Title: Checklist for libvips users +Title: Using > Checklist for libvips users libvips is a slightly unusual library and you may need to take some of its stranger features into account when you design software that uses it. diff --git a/doc/examples.md b/doc/examples.md index 4a98d7beea..6089f20e37 100644 --- a/doc/examples.md +++ b/doc/examples.md @@ -1,4 +1,4 @@ -Title: A few example Python programs using libvips +Title: Using > Python examples This page shows a few libvips examples using Python. They will work with small syntax changes in any language with a libvips binding. diff --git a/doc/extending.md b/doc/extending.md index f1d37136af..e6023afcfe 100644 --- a/doc/extending.md +++ b/doc/extending.md @@ -1,4 +1,4 @@ -Title: How to add operations to libvips +Title: Advanced > Writing operators This section runs quickly through adding a simple operator to libvips. For more information, see [class@Operation] and [class@Region]. A good diff --git a/doc/file-format.md b/doc/file-format.md index 1f94626cfb..a1c04d5ffa 100644 --- a/doc/file-format.md +++ b/doc/file-format.md @@ -1,4 +1,4 @@ -Title: The libvips file format +Title: Technical background > The libvips file format libvips has a simple, native file format. It's very fast, there is no image size limit, and it supports arbitrary metadata. Although few other programs diff --git a/doc/function-list.md b/doc/function-list.md index b2b447485a..0c82e8310a 100644 --- a/doc/function-list.md +++ b/doc/function-list.md @@ -1,4 +1,4 @@ -Title: Index -- all operators in alphabetical order +Title: Operator index / Alphabetical libvips has a set of operators, each of which computes some useful image processing operation. Each operator is implemented as a [class@GObject.Object] diff --git a/doc/how-it-opens-files.md b/doc/how-it-opens-files.md index 8297412496..33e3b6ea3c 100644 --- a/doc/how-it-opens-files.md +++ b/doc/how-it-opens-files.md @@ -1,4 +1,4 @@ -Title: How libvips opens files +Title: Technical background > Opening files libvips has at least four different ways of opening image files, each best for different file types, file sizes and image use cases. libvips tries diff --git a/doc/how-it-works.md b/doc/how-it-works.md index 8e7da5e498..7cda89e9e0 100644 --- a/doc/how-it-works.md +++ b/doc/how-it-works.md @@ -1,4 +1,4 @@ -Title: A high-level technical overview of libvips's evaluation system +Title: Technical background > Evaluation Compared to most image processing libraries, libvips needs little RAM and runs quickly, especially on machines with more than one CPU. libvips achieves this diff --git a/doc/libvips-arithmetic.md b/doc/libvips-arithmetic.md index ad29c52506..cf492cd161 100644 --- a/doc/libvips-arithmetic.md +++ b/doc/libvips-arithmetic.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Pixel arithmetic +Title: Operator index > By section > Arithmetic diff --git a/doc/libvips-basic.md b/doc/libvips-basic.md index 943bd565c1..992dedbbcb 100644 --- a/doc/libvips-basic.md +++ b/doc/libvips-basic.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Aliases, helpers and macros +Title: Operator index > By section > Basic diff --git a/doc/libvips-colour.md b/doc/libvips-colour.md index 13823c6abb..9c37f03223 100644 --- a/doc/libvips-colour.md +++ b/doc/libvips-colour.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Colour operators +Title: Operator index > By section > Colour diff --git a/doc/libvips-conversion.md b/doc/libvips-conversion.md index d91638c18b..198a12ad6f 100644 --- a/doc/libvips-conversion.md +++ b/doc/libvips-conversion.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Convert images in some way +Title: Operator index > By section > Conversion diff --git a/doc/libvips-convolution.md b/doc/libvips-convolution.md index 155a05ae49..fb5a18cc83 100644 --- a/doc/libvips-convolution.md +++ b/doc/libvips-convolution.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Convolve and correlate images +Title: Operator index > By section > Convolution diff --git a/doc/libvips-create.md b/doc/libvips-create.md index 0a352868ac..65796c0e1d 100644 --- a/doc/libvips-create.md +++ b/doc/libvips-create.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Create images +Title: Operator index > By section > Create diff --git a/doc/libvips-draw.md b/doc/libvips-draw.md index 3fd5354c25..39f09b064d 100644 --- a/doc/libvips-draw.md +++ b/doc/libvips-draw.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Drawing operations +Title: Operator index > By section > Draw diff --git a/doc/libvips-error.md b/doc/libvips-error.md index 2de07de1d1..a42c74ee54 100644 --- a/doc/libvips-error.md +++ b/doc/libvips-error.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Error messages and error handling +Title: Operator index > By section > Error diff --git a/doc/libvips-freqfilt.md b/doc/libvips-freqfilt.md index af4672222c..8589d5ba4a 100644 --- a/doc/libvips-freqfilt.md +++ b/doc/libvips-freqfilt.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Fourier transforms and frequency-domain filters +Title: Operator index > By section > Fourier diff --git a/doc/libvips-generate.md b/doc/libvips-generate.md index ee445f6051..72d71a4667 100644 --- a/doc/libvips-generate.md +++ b/doc/libvips-generate.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Calculate pixels and pixel buffers +Title: Operator index > By section > Generate diff --git a/doc/libvips-header.md b/doc/libvips-header.md index 083ca2b4a7..3a4fa9d4b6 100644 --- a/doc/libvips-header.md +++ b/doc/libvips-header.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Image headers +Title: Operator index > By section > Header diff --git a/doc/libvips-histogram.md b/doc/libvips-histogram.md index 1e382244df..c03462b807 100644 --- a/doc/libvips-histogram.md +++ b/doc/libvips-histogram.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Find, manipulate and apply histograms and lookup tables +Title: Operator index > By section > Histogram diff --git a/doc/libvips-memory.md b/doc/libvips-memory.md index 0f3c7d35ea..ad9443e7d4 100644 --- a/doc/libvips-memory.md +++ b/doc/libvips-memory.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Memory utilities +Title: Operator index > By section > Memory diff --git a/doc/libvips-morphology.md b/doc/libvips-morphology.md index 8c8929e58c..40bfe16edc 100644 --- a/doc/libvips-morphology.md +++ b/doc/libvips-morphology.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Morphological operators +Title: Operator index > By section > Morphology diff --git a/doc/libvips-mosaicing.md b/doc/libvips-mosaicing.md index ada51504e3..89a98632aa 100644 --- a/doc/libvips-mosaicing.md +++ b/doc/libvips-mosaicing.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Build image mosaics +Title: Operator index > By section > Mosaicing diff --git a/doc/libvips-resample.md b/doc/libvips-resample.md index c3007528dc..d3cd480ab6 100644 --- a/doc/libvips-resample.md +++ b/doc/libvips-resample.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Resample operations +Title: Operator index > By section > Resample diff --git a/doc/libvips-vips.md b/doc/libvips-vips.md index 16d9324414..0cf9901a68 100644 --- a/doc/libvips-vips.md +++ b/doc/libvips-vips.md @@ -1,4 +1,4 @@ -Title: Operators by section -- Initialize, finalize and version information +Title: Operator index > By section > Initialisation diff --git a/doc/making-image-pyramids.md b/doc/making-image-pyramids.md index 03a3003afd..7a0d5fc0c4 100644 --- a/doc/making-image-pyramids.md +++ b/doc/making-image-pyramids.md @@ -1,4 +1,4 @@ -Title: How to use libvips to make image pyramids +Title: Using > Building image pyramids libvips includes [method@Image.dzsave], an operation that can build image pyramids compatible with [DeepZoom](http://en.wikipedia.org/wiki/Deep_Zoom), diff --git a/doc/multipage-and-animated-images.md b/doc/multipage-and-animated-images.md index 2cae0e7527..e0b2a4d074 100644 --- a/doc/multipage-and-animated-images.md +++ b/doc/multipage-and-animated-images.md @@ -1,4 +1,4 @@ -Title: Processing multipage and animated images +Title: Using > Multipage and animated images libvips represents animated and multipage images as tall, thin strips of frames, like a strip of movie film (or a roll of toilet paper). Special image diff --git a/doc/using-from-c.md b/doc/using-from-c.md index ee658fb7f9..935375bdde 100644 --- a/doc/using-from-c.md +++ b/doc/using-from-c.md @@ -1,4 +1,4 @@ -Title: Using libvips from C +Title: Using > C libvips comes with a convenient, high-level C API. You should read the API docs for full details, but this section will try to give a brief overview. diff --git a/doc/using-from-cplusplus.md b/doc/using-from-cplusplus.md index 8e4cb9e72b..431cdb3780 100644 --- a/doc/using-from-cplusplus.md +++ b/doc/using-from-cplusplus.md @@ -1,4 +1,4 @@ -Title: Using libvips from C++ +Title: Using > C++ libvips comes with a convenient C++ API. It is a very thin wrapper over the C API and adds automatic reference counting, exceptions, operator diff --git a/doc/using-the-cli.md b/doc/using-the-cli.md index 11ea4ef59e..cddacc6226 100644 --- a/doc/using-the-cli.md +++ b/doc/using-the-cli.md @@ -1,4 +1,4 @@ -Title: Using libvips at the command-line +Title: Using > At the command-line Use the `vips` command to execute libvips operations from the command-line. For example: diff --git a/doc/using-threads.md b/doc/using-threads.md index a5ce996c4c..014d76fbf3 100644 --- a/doc/using-threads.md +++ b/doc/using-threads.md @@ -1,4 +1,4 @@ -Title: Using threads +Title: Using > Threads This section tries to summarise the rules for threaded programs using libvips. Generally, libvips is threaded and thread-safe, with a few diff --git a/doc/using-vipsthumbnail.md b/doc/using-vipsthumbnail.md index 5a7eb2150e..a5eb645e4a 100644 --- a/doc/using-vipsthumbnail.md +++ b/doc/using-vipsthumbnail.md @@ -1,4 +1,4 @@ -Title: Using vipsthumbnail +Title: Using > vipsthumbnail libvips ships with a handy command-line image thumbnailer, `vipsthumbnail`. This page introduces it, with some examples. diff --git a/doc/vips.toml.in b/doc/vips.toml.in index a77de08da6..51ee4123eb 100644 --- a/doc/vips.toml.in +++ b/doc/vips.toml.in @@ -43,31 +43,31 @@ content_files = [ "making-image-pyramids.md", "multipage-and-animated-images.md", "using-vipsthumbnail.md", + "using-threads.md", + "developer-checklist.md", "examples.md", "function-list.md", - "libvips-arithmetic.md", "libvips-basic.md", + "libvips-memory.md", + "libvips-error.md", + "libvips-vips.md", + "libvips-arithmetic.md", "libvips-colour.md", "libvips-conversion.md", "libvips-convolution.md", "libvips-create.md", "libvips-draw.md", - "libvips-error.md", "libvips-freqfilt.md", "libvips-generate.md", "libvips-header.md", "libvips-histogram.md", - "libvips-memory.md", "libvips-morphology.md", "libvips-mosaicing.md", "libvips-resample.md", - "libvips-vips.md", - "using-threads.md", "how-it-works.md", "how-it-opens-files.md", - "developer-checklist.md", "file-format.md", "extending.md", From 0b8bb821f2887784e1c01b0c2898a07c92199f75 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 10 Apr 2025 15:25:51 +0200 Subject: [PATCH 122/174] doc: remove a couple of redundant `(method)` overrides (#4462) --- doc/file-format.md | 4 +- doc/libvips-header.md | 16 +++---- libvips/iofuncs/header.c | 95 +++++++++++++++++++++------------------- 3 files changed, 59 insertions(+), 56 deletions(-) diff --git a/doc/file-format.md b/doc/file-format.md index a1c04d5ffa..58bc23e13b 100644 --- a/doc/file-format.md +++ b/doc/file-format.md @@ -82,8 +82,8 @@ Other values of `coding` can set other coding styles. Use ## The metadata Following the image data is a chunk of XML holding a simple list of name-value -pairs. Binary data is encoded with base64. Use [method@Image.image_set] and -friends to set and get image metadata. +pairs. Binary data is encoded with base64. Use [method@Image.set] and friends +to set and get image metadata. You can use `vipsheader -f getext some_file.v` to get the XML from a libvips image, and `vipsedit --setext some_file.v < file.xml` to replace the XML. diff --git a/doc/libvips-header.md b/doc/libvips-header.md index 3a4fa9d4b6..c8f200b965 100644 --- a/doc/libvips-header.md +++ b/doc/libvips-header.md @@ -5,7 +5,7 @@ Title: Operator index > By section > Header libvips supports getting and setting image header data (including metadata) in a uniform way. -Use [method@Image.image_get_typeof] to test for the existence and +Use [method@Image.get_typeof] to test for the existence and [alias@GObject.Type] of a header field. You can attach arbitrary metadata to images. Metadata is copied as images @@ -73,10 +73,10 @@ copied between images efficiently. * [method@Image.get_concurrency] * [method@Image.get_data] * [method@Image.init_fields] -* [method@Image.image_set] -* [method@Image.image_get] +* [method@Image.set] +* [method@Image.get] * [method@Image.get_as_string] -* [method@Image.image_get_typeof] +* [method@Image.get_typeof] * [method@Image.remove] * [method@Image.map] * [method@Image.get_fields] @@ -84,15 +84,15 @@ copied between images efficiently. * [method@Image.get_area] * [method@Image.set_blob] * [method@Image.set_blob_copy] -* [method@Image.image_get_blob] -* [method@Image.image_get_int] +* [method@Image.get_blob] +* [method@Image.get_int] * [method@Image.set_int] -* [method@Image.image_get_double] +* [method@Image.get_double] * [method@Image.set_double] * [method@Image.get_string] * [method@Image.set_string] * [method@Image.print_field] -* [method@Image.image_get_image] +* [method@Image.get_image] * [method@Image.set_image] * [method@Image.set_array_int] * [method@Image.get_array_int] diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 3d1cad1c34..9ccaf40641 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -1161,7 +1161,7 @@ vips__image_copy_fields_array(VipsImage *out, VipsImage *in[]) } /** - * vips_image_set: (method) + * vips_image_set: * @image: image to set the metadata on * @name: the name to give the metadata * @value: the [struct@GObject.Value] to copy into the image @@ -1183,7 +1183,7 @@ vips__image_copy_fields_array(VipsImage *out, VipsImage *in[]) * ``` * * ::: seealso - * [method@Image.image_get]. + * [method@Image.get]. */ void vips_image_set(VipsImage *image, const char *name, GValue *value) @@ -1249,7 +1249,7 @@ vips_set_value_from_pointer(GValue *value, void *data) } /** - * vips_image_get: (method) + * vips_image_get: * @image: image to get the field from * @name: the name to fetch * @value_copy: (transfer full) (out caller-allocates): the @@ -1259,11 +1259,11 @@ vips_set_value_from_pointer(GValue *value, void *data) * but uninitialised. * * This will return -1 and add a message to the error buffer if the field - * does not exist. Use [method@Image.image_get_typeof] to test for the + * does not exist. Use [method@Image.get_typeof] to test for the * existence of a field first if you are not certain it will be there. * * For example, to read a double from an image (though of course you would use - * [method@Image.image_get_double] in practice): + * [method@Image.get_double] in practice): * * ```c * GValue value = G_VALUE_INIT; @@ -1286,7 +1286,7 @@ vips_set_value_from_pointer(GValue *value, void *data) * ``` * * ::: seealso - * [method@Image.image_get_typeof] or [method@Image.image_get_double]. + * [method@Image.get_typeof] or [method@Image.get_double]. * * Returns: (skip): 0 on success, -1 otherwise. */ @@ -1341,7 +1341,7 @@ vips_image_get(const VipsImage *image, const char *name, GValue *value_copy) } /** - * vips_image_get_typeof: (method) + * vips_image_get_typeof: * @image: image to test * @name: the name to search for * @@ -1349,7 +1349,7 @@ vips_image_get(const VipsImage *image, const char *name, GValue *value_copy) * is no field of that name. * * ::: seealso - * [method@Image.image_get]. + * [method@Image.get]. * * Returns: the [alias@GObject.Type] of the field, or zero if there is no * field of that name. @@ -1394,7 +1394,7 @@ vips_image_get_typeof(const VipsImage *image, const char *name) * name was found. * * ::: seealso - * [method@Image.image_set] or [method@Image.image_get_typeof]. + * [method@Image.set] or [method@Image.get_typeof]. * * Returns: `TRUE` if an item of metadata of that name was found and removed */ @@ -1458,7 +1458,7 @@ vips_image_map_fn(VipsMeta *meta, VipsImageMapFn fn, void *a) * iteration, or a non-`NULL` pointer to indicate early termination. * * ::: seealso - * [method@Image.image_get_typeof] or [method@Image.image_get]. + * [method@Image.get_typeof] or [method@Image.get]. * * Returns: (nullable) (transfer none): `NULL` on success, the failing * pointer otherwise. @@ -1550,7 +1550,7 @@ vips_image_get_fields(VipsImage *image) * VIPS no longer needs the metadata, it will be freed with @free_fn. * * ::: seealso - * [method@Image.image_get_double] or [method@Image.image_set]. + * [method@Image.get_double] or [method@Image.set]. */ void vips_image_set_area(VipsImage *image, const char *name, @@ -1594,12 +1594,12 @@ meta_get_value(const VipsImage *image, * @data: (out): return metadata value * * Gets @data from @image under the name @name. A convenience - * function over [method@Image.image_get]. Use [method@Image.image_get_typeof] to + * function over [method@Image.get]. Use [method@Image.get_typeof] to * test for the existence of a piece of metadata. * * ::: seealso - * [method@Image.set_area], [method@Image.image_get] or - * [method@Image.image_get_typeof]. + * [method@Image.set_area], [method@Image.get] or + * [method@Image.get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1630,7 +1630,7 @@ vips_image_get_area(const VipsImage *image, * Attaches @data as a metadata item on @image under the name @name. * * ::: seealso - * [method@Image.image_get_blob] or [method@Image.image_set]. + * [method@Image.get_blob] or [method@Image.set]. */ void vips_image_set_blob(VipsImage *image, const char *name, @@ -1655,7 +1655,7 @@ vips_image_set_blob(VipsImage *image, const char *name, * a copy of the memory area. * * ::: seealso - * [method@Image.image_get_blob] or [method@Image.image_set]. + * [method@Image.get_blob] or [method@Image.set]. */ void vips_image_set_blob_copy(VipsImage *image, @@ -1684,7 +1684,7 @@ vips_image_set_blob_copy(VipsImage *image, } /** - * vips_image_get_blob: (method) + * vips_image_get_blob: * @image: image to get the metadata from * @name: metadata name * @data: (out) (array length=length) (element-type guint8): pointer to area @@ -1692,12 +1692,12 @@ vips_image_set_blob_copy(VipsImage *image, * @length: (out): return the blob length here, optionally * * Gets @data from @image under the name @name, optionally returns its - * length in @length. Use [method@Image.image_get_typeof] to test for the existence + * length in @length. Use [method@Image.get_typeof] to test for the existence * of a piece of metadata. * * ::: seealso - * [method@Image.image_get], [method@Image.image_get_typeof] or - * [method@Blob.get]. + * [method@Image.get], [method@Image.get_typeof] or + * [method@Blob.get]. * * Returns: 0 on success, -1 otherwise. */ @@ -1717,7 +1717,7 @@ vips_image_get_blob(const VipsImage *image, const char *name, } /** - * vips_image_get_int: (method) + * vips_image_get_int: * @image: image to get the header field from * @name: field name * @out: (out): return field value @@ -1726,7 +1726,7 @@ vips_image_get_blob(const VipsImage *image, const char *name, * The value will be transformed into an int, if possible. * * ::: seealso - * [method@Image.image_get] or [method@Image.image_get_typeof]. + * [method@Image.get] or [method@Image.get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1750,10 +1750,10 @@ vips_image_get_int(const VipsImage *image, const char *name, int *out) * @i: metadata value * * Attaches @i as a metadata item on @image under the name @name. A - * convenience function over [method@Image.image_set]. + * convenience function over [method@Image.set]. * * ::: seealso - * [method@Image.image_get_int] or [method@Image.image_set]. + * [method@Image.get_int] or [method@Image.set]. */ void vips_image_set_int(VipsImage *image, const char *name, int i) @@ -1767,7 +1767,7 @@ vips_image_set_int(VipsImage *image, const char *name, int i) } /** - * vips_image_get_double: (method) + * vips_image_get_double: * @image: image to get the header field from * @name: field name * @out: (out): return field value @@ -1776,7 +1776,7 @@ vips_image_set_int(VipsImage *image, const char *name, int i) * The value will be transformed into a double, if possible. * * ::: seealso - * [method@Image.image_get] or [method@Image.image_get_typeof]. + * [method@Image.get] or [method@Image.get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1800,10 +1800,10 @@ vips_image_get_double(const VipsImage *image, const char *name, double *out) * @d: metadata value * * Attaches @d as a metadata item on @image as @name. A - * convenience function over [method@Image.image_set]. + * convenience function over [method@Image.set]. * * ::: seealso - * [method@Image.image_get_double] or [method@Image.image_set]. + * [method@Image.get_double] or [method@Image.set]. */ void vips_image_set_double(VipsImage *image, const char *name, double d) @@ -1830,7 +1830,7 @@ vips_image_set_double(VipsImage *image, const char *name, double d) * Use [method@Image.get_as_string] to fetch any field as a string. * * ::: seealso - * [method@Image.image_get] or [method@Image.image_get_typeof]. + * [method@Image.get] or [method@Image.get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1875,10 +1875,10 @@ vips_image_get_string(const VipsImage *image, const char *name, * * Attaches @str as a metadata item on @image as @name. * A convenience - * function over [method@Image.image_set] using `VIPS_TYPE_REF_STRING`. + * function over [method@Image.set] using `VIPS_TYPE_REF_STRING`. * * ::: seealso - * [method@Image.image_get_double] or [method@Image.image_set]. + * [method@Image.get_double] or [method@Image.set]. */ void vips_image_set_string(VipsImage *image, const char *name, const char *str) @@ -1905,8 +1905,8 @@ vips_image_set_string(VipsImage *image, const char *name, const char *str) * make a string that's for humans. * * ::: seealso - * [method@Image.image_get], [method@Image.image_get_typeof] or - * [method@Buf.appendg]. + * [method@Image.get], [method@Image.get_typeof] or + * [method@Buf.appendg]. * * Returns: 0 on success, -1 otherwise. */ @@ -1964,7 +1964,7 @@ vips_image_print_field(const VipsImage *image, const char *name) } /** - * vips_image_get_image: (method) + * vips_image_get_image: * @image: image to get the metadata from * @name: metadata name * @out: (out) (transfer full): return metadata value @@ -1973,10 +1973,11 @@ vips_image_print_field(const VipsImage *image, const char *name) * The field must be of type `VIPS_TYPE_IMAGE`. * You must unref @out with [method@GObject.Object.unref]. * - * Use [method@Image.image_get_typeof] to test for the + * Use [method@Image.get_typeof] to test for the * existence of a piece of metadata. * - * See also:[method@Image.image_get] or [method@Image.set_image] + * ::: seealso + * [method@Image.get] or [method@Image.set_image] * * Returns: 0 on success, -1 otherwise. */ @@ -2001,10 +2002,10 @@ vips_image_get_image(const VipsImage *image, * @im: metadata value * * Attaches @im as a metadata item on @image as @name. - * A convenience function over [method@Image.image_set]. + * A convenience function over [method@Image.set]. * * ::: seealso - * [method@Image.image_get_image] or [method@Image.image_set]. + * [method@Image.get_image] or [method@Image.set]. */ void vips_image_set_image(VipsImage *image, const char *name, VipsImage *im) @@ -2029,10 +2030,11 @@ vips_image_set_image(VipsImage *image, const char *name, VipsImage *im) * * Do not free @out. @out is valid as long as @image is valid. * - * Use [method@Image.image_get_typeof] to test for the + * Use [method@Image.get_typeof] to test for the * existence of a piece of metadata. * - * See also:[method@Image.image_get] or [method@Image.set_image] + * ::: seealso + * [method@Image.get] or [method@Image.set_image] * * Returns: 0 on success, -1 otherwise. */ @@ -2058,10 +2060,10 @@ vips_image_get_array_int(VipsImage *image, const char *name, * @n: the number of elements * * Attaches @array as a metadata item on @image as @name. - * A convenience function over [method@Image.image_set]. + * A convenience function over [method@Image.set]. * * ::: seealso - * [method@Image.image_get_image] or [method@Image.image_set]. + * [method@Image.get_image] or [method@Image.set]. */ void vips_image_set_array_int(VipsImage *image, const char *name, @@ -2087,10 +2089,11 @@ vips_image_set_array_int(VipsImage *image, const char *name, * * Do not free @out. @out is valid as long as @image is valid. * - * Use [method@Image.image_get_typeof] to test for the + * Use [method@Image.get_typeof] to test for the * existence of a piece of metadata. * - * See also:[method@Image.image_get] or [method@Image.set_image] + * ::: seealso + * [method@Image.get] or [method@Image.set_image] * * Returns: 0 on success, -1 otherwise. */ @@ -2116,10 +2119,10 @@ vips_image_get_array_double(VipsImage *image, const char *name, * @n: the number of elements * * Attaches @array as a metadata item on @image as @name. - * A convenience function over [method@Image.image_set]. + * A convenience function over [method@Image.set]. * * ::: seealso - * [method@Image.image_get_image] or [method@Image.image_set]. + * [method@Image.get_image] or [method@Image.set]. */ void vips_image_set_array_double(VipsImage *image, const char *name, From 579954da96dbb3b2eb67bb6fbd35ddbe643c8d4a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 11 Apr 2025 10:44:47 +0100 Subject: [PATCH 123/174] redo annotations for "colour" (#4460) * redo annotations for "colour" * oops fix leak test * fix image_get_typeof * Update doc/rename.sed Co-authored-by: Kleis Auke Wolthuizen --------- Co-authored-by: Kleis Auke Wolthuizen --- doc/rename.sed | 4 +++- libvips/colour/CMYK2XYZ.c | 2 +- libvips/colour/HSV2sRGB.c | 5 +++-- libvips/colour/LCh2UCS.c | 3 ++- libvips/colour/Lab2LabQ.c | 5 +++-- libvips/colour/Lab2LabS.c | 3 ++- libvips/colour/Lab2XYZ.c | 5 +++-- libvips/colour/LabQ2Lab.c | 5 +++-- libvips/colour/LabQ2LabS.c | 5 +++-- libvips/colour/LabQ2sRGB.c | 11 +++++++---- libvips/colour/LabS2Lab.c | 3 ++- libvips/colour/LabS2LabQ.c | 3 ++- libvips/colour/UCS2LCh.c | 9 +++++---- libvips/colour/XYZ2CMYK.c | 2 +- libvips/colour/XYZ2Lab.c | 5 +++-- libvips/colour/colourspace.c | 13 +++++++------ libvips/colour/dECMC.c | 3 ++- libvips/colour/float2rad.c | 3 ++- libvips/colour/icc_transform.c | 17 +++++++++-------- libvips/colour/rad2float.c | 5 +++-- libvips/colour/sRGB2HSV.c | 5 +++-- libvips/colour/sRGB2scRGB.c | 5 +++-- libvips/colour/scRGB2BW.c | 3 ++- libvips/colour/scRGB2sRGB.c | 3 ++- 24 files changed, 76 insertions(+), 51 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index 5ba6384c4c..c11ad7b82b 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -100,6 +100,7 @@ s/vips_\(ceil\)()/[method@Image.\1]/g s/vips_\(clamp\)()/[method@Image.\1]/g s/vips_\(CMC2LCh\)()/[method@Image.\1]/g s/vips_\(CMYK2XYZ\)()/[method@Image.\1]/g +s/vips_\(colourspace_issupported\)()/[method@Image.\1]/g s/vips_\(colourspace\)()/[method@Image.\1]/g s/vips_\(compass\)()/[method@Image.\1]/g s/vips_\(complex2\)()/[method@Image.\1]/g @@ -199,6 +200,7 @@ s/vips_\(icc_export\)()/[method@Image.\1]/g s/vips_\(icc_import\)()/[method@Image.\1]/g s/vips_\(icc_transform\)()/[method@Image.\1]/g s/vips_\(ifthenelse\)()/[method@Image.\1]/g +s/vips_image_\(get_typeof\)()/[method@Image.\1]/g s/vips_\(imag\)()/[method@Image.\1]/g s/vips_\(insert\)()/[method@Image.\1]/g s/vips_\(invertlut\)()/[method@Image.\1]/g @@ -341,8 +343,8 @@ s/vips_\(shrinkv\)()/[method@Image.\1]/g s/vips_\(sign\)()/[method@Image.\1]/g s/vips_\(similarity\)()/[method@Image.\1]/g s/vips_\(sinh\)()/[method@Image.\1]/g -s/vips_\(sink\)()/[method@Image.\1]/g s/vips_\(sink_disc\)()/[method@Image.\1]/g +s/vips_\(sink\)()/[method@Image.\1]/g s/vips_\(sink_screen\)()/[method@Image.\1]/g s/vips_\(sin\)()/[method@Image.\1]/g s/vips_\(smartcrop\)()/[method@Image.\1]/g diff --git a/libvips/colour/CMYK2XYZ.c b/libvips/colour/CMYK2XYZ.c index 2d888b5bd5..7e132205f1 100644 --- a/libvips/colour/CMYK2XYZ.c +++ b/libvips/colour/CMYK2XYZ.c @@ -213,7 +213,7 @@ vips_CMYK2XYZ_init(VipsCMYK2XYZ *CMYK2XYZ) * fallback profile will be used. * * Conversion is to D65 XYZ with relative intent. If you need more control - * over the process, use vips_icc_import() instead. + * over the process, use [method@Image.icc_import] instead. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/colour/HSV2sRGB.c b/libvips/colour/HSV2sRGB.c index d7ac299ec8..6c1f560475 100644 --- a/libvips/colour/HSV2sRGB.c +++ b/libvips/colour/HSV2sRGB.c @@ -139,10 +139,11 @@ vips_HSV2sRGB_init(VipsHSV2sRGB *HSV2sRGB) * Convert HSV to sRGB. * * HSV is a crude polar coordinate system for RGB images. It is provided for - * compatibility with other image processing systems. See vips_Lab2LCh() for a + * compatibility with other image processing systems. See [method@Image.Lab2LCh] for a * much better colour space. * - * See also: vips_sRGB2HSV(). + * ::: seealso + * [method@Image.sRGB2HSV]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/LCh2UCS.c b/libvips/colour/LCh2UCS.c index 7b4685bdf4..33ab537f2f 100644 --- a/libvips/colour/LCh2UCS.c +++ b/libvips/colour/LCh2UCS.c @@ -233,7 +233,8 @@ vips_LCh2CMC_init(VipsLCh2CMC *LCh2CMC) * This operation generates CMC(1:1). For CMC(2:1), halve Lucs and double * Cucs. * - * See also: vips_CMC2LCh(). + * ::: seealso + * [method@Image.CMC2LCh]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/colour/Lab2LabQ.c b/libvips/colour/Lab2LabQ.c index 7418c434f6..9c79f8d88d 100644 --- a/libvips/colour/Lab2LabQ.c +++ b/libvips/colour/Lab2LabQ.c @@ -161,9 +161,10 @@ vips_Lab2LabQ_init(VipsLab2LabQ *Lab2LabQ) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Convert a Lab three-band float image to LabQ (#VIPS_CODING_LABQ). + * Convert a Lab three-band float image to LabQ ([enum@Vips.Coding.LABQ)]. * - * See also: vips_LabQ2Lab(). + * ::: seealso + * [method@Image.LabQ2Lab]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/Lab2LabS.c b/libvips/colour/Lab2LabS.c index 76a526380a..46ff14701b 100644 --- a/libvips/colour/Lab2LabS.c +++ b/libvips/colour/Lab2LabS.c @@ -107,7 +107,8 @@ vips_Lab2LabS_init(VipsLab2LabS *Lab2LabS) * * Turn Lab to LabS, signed 16-bit int fixed point. * - * See also: vips_LabQ2Lab(). + * ::: seealso + * [method@Image.LabQ2Lab]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/Lab2XYZ.c b/libvips/colour/Lab2XYZ.c index 5d23c2cfd7..870c183e32 100644 --- a/libvips/colour/Lab2XYZ.c +++ b/libvips/colour/Lab2XYZ.c @@ -207,7 +207,7 @@ vips_Lab2XYZ_init(VipsLab2XYZ *Lab2XYZ) * * Optional arguments: * - * * @temp: #VipsArrayDouble, colour temperature + * * @temp: [struct@ArrayDouble], colour temperature * * Turn Lab to XYZ. The colour temperature defaults to D65, but can be * specified with @temp. @@ -238,7 +238,8 @@ vips_Lab2XYZ(VipsImage *in, VipsImage **out, ...) * * Calculate XYZ from Lab, D65. * - * See also: vips_Lab2XYZ(). + * ::: seealso + * [method@Image.Lab2XYZ]. */ void vips_col_Lab2XYZ(float L, float a, float b, float *X, float *Y, float *Z) diff --git a/libvips/colour/LabQ2Lab.c b/libvips/colour/LabQ2Lab.c index 78cc2e83ea..19a27daf26 100644 --- a/libvips/colour/LabQ2Lab.c +++ b/libvips/colour/LabQ2Lab.c @@ -147,9 +147,10 @@ vips_LabQ2Lab_init(VipsLabQ2Lab *LabQ2Lab) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Unpack a LabQ (#VIPS_CODING_LABQ) image to a three-band float image. + * Unpack a LabQ ([enum@Vips.Coding.LABQ)] image to a three-band float image. * - * See also: vips_LabQ2Lab(), vips_LabQ2LabS(), vips_rad2float(). + * ::: seealso + * [method@Image.LabQ2Lab], [method@Image.LabQ2LabS], [method@Image.rad2float]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/LabQ2LabS.c b/libvips/colour/LabQ2LabS.c index 2978d28b11..35c4f649f3 100644 --- a/libvips/colour/LabQ2LabS.c +++ b/libvips/colour/LabQ2LabS.c @@ -126,9 +126,10 @@ vips_LabQ2LabS_init(VipsLabQ2LabS *LabQ2LabS) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Unpack a LabQ (#VIPS_CODING_LABQ) image to a three-band short image. + * Unpack a LabQ ([enum@Vips.Coding.LABQ)] image to a three-band short image. * - * See also: vips_LabS2LabQ(), vips_LabQ2LabS(), vips_rad2float(). + * ::: seealso + * [method@Image.LabS2LabQ], [method@Image.LabQ2LabS], [method@Image.rad2float]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/LabQ2sRGB.c b/libvips/colour/LabQ2sRGB.c index a2b153fd2b..b17530ef95 100644 --- a/libvips/colour/LabQ2sRGB.c +++ b/libvips/colour/LabQ2sRGB.c @@ -222,7 +222,8 @@ vips_col_sRGB2scRGB_16(int r, int g, int b, float *R, float *G, float *B) * * Turn scRGB into XYZ. * - * See also: vips_scRGB2XYZ(). + * ::: seealso + * [method@Image.scRGB2XYZ]. */ int vips_col_scRGB2XYZ(float R, float G, float B, float *X, float *Y, float *Z) @@ -255,7 +256,8 @@ vips_col_scRGB2XYZ(float R, float G, float B, float *X, float *Y, float *Z) * * Turn XYZ into scRGB. * - * See also: vips_XYZ2scRGB(). + * ::: seealso + * [method@Image.XYZ2scRGB]. */ int vips_col_XYZ2scRGB(float X, float Y, float Z, float *R, float *G, float *B) @@ -571,9 +573,10 @@ vips_LabQ2sRGB_init(VipsLabQ2sRGB *LabQ2sRGB) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Unpack a LabQ (#VIPS_CODING_LABQ) image to a three-band short image. + * Unpack a LabQ ([enum@Vips.Coding.LABQ)] image to a three-band short image. * - * See also: vips_LabS2LabQ(), vips_LabQ2sRGB(), vips_rad2float(). + * ::: seealso + * [method@Image.LabS2LabQ], [method@Image.LabQ2sRGB], [method@Image.rad2float]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/LabS2Lab.c b/libvips/colour/LabS2Lab.c index 33ce353fca..0f37529d89 100644 --- a/libvips/colour/LabS2Lab.c +++ b/libvips/colour/LabS2Lab.c @@ -103,7 +103,8 @@ vips_LabS2Lab_init(VipsLabS2Lab *LabS2Lab) * * Convert a LabS three-band signed short image to a three-band float image. * - * See also: vips_LabS2Lab(). + * ::: seealso + * [method@Image.LabS2Lab]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/LabS2LabQ.c b/libvips/colour/LabS2LabQ.c index 962dfbc7c3..9be79149d4 100644 --- a/libvips/colour/LabS2LabQ.c +++ b/libvips/colour/LabS2LabQ.c @@ -153,7 +153,8 @@ vips_LabS2LabQ_init(VipsLabS2LabQ *LabS2LabQ) * * Convert a LabS three-band signed short image to LabQ * - * See also: vips_LabQ2LabS(). + * ::: seealso + * [method@Image.LabQ2LabS]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/UCS2LCh.c b/libvips/colour/UCS2LCh.c index 3a12fab1c8..1649129fc9 100644 --- a/libvips/colour/UCS2LCh.c +++ b/libvips/colour/UCS2LCh.c @@ -141,7 +141,7 @@ make_hI(void) * vips_col_Lcmc2L: * @Lcmc: L cmc * - * Calculate L from Lcmc using a table. Call vips_col_make_tables_CMC() at + * Calculate L from Lcmc using a table. Call [func@col_make_tables_CMC] at * least once before using this function. * * Returns: L* @@ -163,7 +163,7 @@ vips_col_Lcmc2L(float Lcmc) * @Ccmc: Ccmc * * Calculate C from Ccmc using a table. - * Call vips_col_make_tables_CMC() at + * Call [func@col_make_tables_CMC] at * least once before using this function. * * Returns: C. @@ -186,7 +186,7 @@ vips_col_Ccmc2C(float Ccmc) * @hcmc: Hue cmc (degrees) * * Calculate h from C and hcmc, using a table. - * Call vips_col_make_tables_CMC() at + * Call [func@col_make_tables_CMC] at * least once before using this function. * * Returns: h. @@ -292,7 +292,8 @@ vips_CMC2LCh_init(VipsCMC2LCh *CMC2LCh) * * Turn LCh to CMC. * - * See also: vips_LCh2CMC(). + * ::: seealso + * [method@Image.LCh2CMC]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/colour/XYZ2CMYK.c b/libvips/colour/XYZ2CMYK.c index a055bd240f..a3a22fb42e 100644 --- a/libvips/colour/XYZ2CMYK.c +++ b/libvips/colour/XYZ2CMYK.c @@ -222,7 +222,7 @@ vips_XYZ2CMYK_init(VipsXYZ2CMYK *XYZ2CMYK) * Turn XYZ to CMYK. * * Conversion is from D65 XYZ with relative intent. If you need more control - * over the process, use vips_icc_export() instead. + * over the process, use [method@Image.icc_export] instead. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/colour/XYZ2Lab.c b/libvips/colour/XYZ2Lab.c index 8facaccdea..9c60406876 100644 --- a/libvips/colour/XYZ2Lab.c +++ b/libvips/colour/XYZ2Lab.c @@ -180,7 +180,8 @@ vips_XYZ2Lab_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) * * Calculate XYZ from Lab, D65. * - * See also: vips_XYZ2Lab(). + * ::: seealso + * [method@Image.XYZ2Lab]. */ void vips_col_XYZ2Lab(float X, float Y, float Z, float *L, float *a, float *b) @@ -260,7 +261,7 @@ vips_XYZ2Lab_init(VipsXYZ2Lab *XYZ2Lab) * * Optional arguments: * - * * @temp: #VipsArrayDouble, colour temperature + * * @temp: [struct@ArrayDouble], colour temperature * * Turn XYZ to Lab, optionally specifying the colour temperature. @temp * defaults to D65. diff --git a/libvips/colour/colourspace.c b/libvips/colour/colourspace.c index 9bca0895f0..5afd3fac07 100644 --- a/libvips/colour/colourspace.c +++ b/libvips/colour/colourspace.c @@ -424,7 +424,7 @@ static VipsColourRoute vips_colour_routes[] = { * vips_colourspace_issupported: (method) * @image: input image * - * Test if @image is in a colourspace that vips_colourspace() can process. + * Test if @image is in a colourspace that [method@Image.colourspace] can process. * * Returns: %TRUE if @image is in a supported colourspace. */ @@ -601,12 +601,13 @@ vips_colourspace_init(VipsColourspace *colourspace) * @source_space, if set) and runs * a set of colourspace conversion functions to move it to @space. * - * For example, given an image tagged as #VIPS_INTERPRETATION_YXY, running - * vips_colourspace() with @space set to #VIPS_INTERPRETATION_LAB will - * convert with vips_Yxy2XYZ() and vips_XYZ2Lab(). + * For example, given an image tagged as [enum@Vips.Interpretation.YXY], running + * [method@Image.colourspace] with @space set to [enum@Vips.Interpretation.LAB] will + * convert with [method@Image.Yxy2XYZ] and [method@Image.XYZ2Lab]. * - * See also: vips_colourspace_issupported(), - * vips_image_guess_interpretation(). + * ::: seealso + * [method@Image.colourspace_issupported], + * [method@Image.guess_interpretation]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/dECMC.c b/libvips/colour/dECMC.c index 5a279bd758..ea1ac082ce 100644 --- a/libvips/colour/dECMC.c +++ b/libvips/colour/dECMC.c @@ -85,7 +85,8 @@ vips_dECMC_init(VipsdECMC *dECMC) * transform the two source images to CMC yourself, scale the channels * appropriately, and call this function. * - * See also: vips_colourspace() + * ::: seealso + * [method@Image.colourspace] * * Returns: 0 on success, -1 on error */ diff --git a/libvips/colour/float2rad.c b/libvips/colour/float2rad.c index 3ea4553864..dd62579c83 100644 --- a/libvips/colour/float2rad.c +++ b/libvips/colour/float2rad.c @@ -232,7 +232,8 @@ vips_float2rad_init(VipsFloat2rad *float2rad) * * Convert a three-band float image to Radiance 32-bit packed format. * - * See also: vips_rad2float(), #VIPS_CODING_RAD, vips_LabQ2Lab(). + * ::: seealso + * [method@Image.rad2float], [enum@Vips.Coding.RAD], [method@Image.LabQ2Lab]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 8d7d8dcfde..313edd5317 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -118,8 +118,8 @@ * @VIPS_PCS_LAB: use CIELAB D65 as the Profile Connection Space * @VIPS_PCS_XYZ: use XYZ as the Profile Connection Space * - * Pick a Profile Connection Space for vips_icc_import() and - * vips_icc_export(). LAB is usually best, XYZ can be more convenient in some + * Pick a Profile Connection Space for [method@Image.icc_import] and + * [method@Image.icc_export]. LAB is usually best, XYZ can be more convenient in some * cases. */ @@ -1296,7 +1296,8 @@ vips_icc_transform_init(VipsIccTransform *transform) * Transform an image from absolute to relative colorimetry using the * MediaWhitePoint stored in the ICC profile. * - * See also: vips_icc_transform(), vips_icc_import(). + * ::: seealso + * [method@Image.icc_transform], [method@Image.icc_import]. * * Returns: 0 on success, -1 on error. */ @@ -1454,8 +1455,8 @@ vips_icc_is_compatible_profile(VipsImage *image, * * 1. If @embedded is set, libvips will try to use any profile in the input * image metadata. You can test for the presence of an embedded profile - * with vips_image_get_typeof() with #VIPS_META_ICC_NAME as an argument. - * This will return %GType 0 if there is no profile. + * with [method@Image.get_typeof] with #VIPS_META_ICC_NAME as an + * argument. This will return %GType 0 if there is no profile. * * 2. Otherwise, if @input_profile is set, libvips will try to load a * profile from the named file. This can aslso be the name of one of the @@ -1545,8 +1546,8 @@ vips_icc_export(VipsImage *in, VipsImage **out, ...) * * 1. If @embedded is set, libvips will try to use any profile in the input * image metadata. You can test for the presence of an embedded profile - * with vips_image_get_typeof() with #VIPS_META_ICC_NAME as an argument. - * This will return %GType 0 if there is no profile. + * with [method@Image.get_typeof] with #VIPS_META_ICC_NAME as an + * argument. This will return %GType 0 if there is no profile. * * 2. Otherwise, if @input_profile is set, libvips will try to load a * profile from the named file. This can aslso be the name of one of the @@ -1563,7 +1564,7 @@ vips_icc_export(VipsImage *in, VipsImage **out, ...) * The output image has the output profile attached to the #VIPS_META_ICC_NAME * field. * - * Use vips_icc_import() and vips_icc_export() to do either the first or + * Use [method@Image.icc_import] and [method@Image.icc_export] to do either the first or * second half of this operation in isolation. * * Returns: 0 on success, -1 on error. diff --git a/libvips/colour/rad2float.c b/libvips/colour/rad2float.c index fb4bf0f72f..08c6d2ae96 100644 --- a/libvips/colour/rad2float.c +++ b/libvips/colour/rad2float.c @@ -206,9 +206,10 @@ vips_rad2float_init(VipsRad2float *rad2float) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Unpack a RAD (#VIPS_CODING_RAD) image to a three-band float image. + * Unpack a RAD ([enum@Vips.Coding.RAD)] image to a three-band float image. * - * See also: vips_float2rad(), vips_LabQ2LabS(). + * ::: seealso + * [method@Image.float2rad], [method@Image.LabQ2LabS]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/sRGB2HSV.c b/libvips/colour/sRGB2HSV.c index e3e839333f..6e764d29a9 100644 --- a/libvips/colour/sRGB2HSV.c +++ b/libvips/colour/sRGB2HSV.c @@ -160,10 +160,11 @@ vips_sRGB2HSV_init(VipssRGB2HSV *sRGB2HSV) * Convert to HSV. * * HSV is a crude polar coordinate system for RGB images. It is provided for - * compatibility with other image processing systems. See vips_Lab2LCh() for a + * compatibility with other image processing systems. See [method@Image.Lab2LCh] for a * much better colour space. * - * See also: vips_HSV2sRGB(), vips_Lab2LCh(). + * ::: seealso + * [method@Image.HSV2sRGB], [method@Image.Lab2LCh]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/sRGB2scRGB.c b/libvips/colour/sRGB2scRGB.c index 8b151de3ab..f4c8be3a73 100644 --- a/libvips/colour/sRGB2scRGB.c +++ b/libvips/colour/sRGB2scRGB.c @@ -310,11 +310,12 @@ vips_sRGB2scRGB_init(VipssRGB2scRGB *sRGB2scRGB) * * Convert an sRGB image to scRGB. The input image can be 8 or 16-bit. * - * If the input image is tagged as #VIPS_INTERPRETATION_RGB16, any extra + * If the input image is tagged as [enum@Vips.Interpretation.RGB16], any extra * channels after RGB are divided by 256. Thus, scRGB alpha is * always 0 - 255.99. * - * See also: vips_scRGB2XYZ(), vips_scRGB2sRGB(), vips_rad2float(). + * ::: seealso + * [method@Image.scRGB2XYZ], [method@Image.scRGB2sRGB], [method@Image.rad2float]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/scRGB2BW.c b/libvips/colour/scRGB2BW.c index f075d0f57f..080d1cb538 100644 --- a/libvips/colour/scRGB2BW.c +++ b/libvips/colour/scRGB2BW.c @@ -274,7 +274,8 @@ vips_scRGB2BW_init(VipsscRGB2BW *scRGB2BW) * If @depth is 16, any extra channels after RGB are * multiplied by 256. * - * See also: vips_LabS2LabQ(), vips_sRGB2scRGB(), vips_rad2float(). + * ::: seealso + * [method@Image.LabS2LabQ], [method@Image.sRGB2scRGB], [method@Image.rad2float]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/scRGB2sRGB.c b/libvips/colour/scRGB2sRGB.c index e6d6315089..791b7cc393 100644 --- a/libvips/colour/scRGB2sRGB.c +++ b/libvips/colour/scRGB2sRGB.c @@ -307,7 +307,8 @@ vips_scRGB2sRGB_init(VipsscRGB2sRGB *scRGB2sRGB) * If @depth is 16, any extra channels after RGB are * multiplied by 256. * - * See also: vips_LabS2LabQ(), vips_sRGB2scRGB(), vips_rad2float(). + * ::: seealso + * [method@Image.LabS2LabQ], [method@Image.sRGB2scRGB], [method@Image.rad2float]. * * Returns: 0 on success, -1 on error. */ From 07b021695a6b621058604314a22f8eadaab663af Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 15 Apr 2025 11:02:57 +0100 Subject: [PATCH 124/174] fix compiler warning --- libvips/resample/quadratic.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/libvips/resample/quadratic.c b/libvips/resample/quadratic.c index dd4efb24d9..144eae325c 100644 --- a/libvips/resample/quadratic.c +++ b/libvips/resample/quadratic.c @@ -141,15 +141,7 @@ vips_quadratic_gen(VipsRegion *out_region, int xhigh = VIPS_RECT_RIGHT(&out_region->valid); int yhigh = VIPS_RECT_BOTTOM(&out_region->valid); - VipsPel *q; - - int xo, yo; /* output coordinates, dstimage */ - double fxi, fyi; /* input coordinates */ - double dx, dy; /* xo derivative of input coord. */ - double ddx, ddy; /* 2nd xo derivative of input coord. */ - VipsRect image; - image.left = 0; image.top = 0; image.width = in->Xsize; @@ -157,11 +149,18 @@ vips_quadratic_gen(VipsRegion *out_region, if (vips_region_image(ir, &image)) return -1; - for (yo = ylow; yo < yhigh; yo++) { - fxi = xlow + vec[0]; /* order 0 */ + for (int yo = ylow; yo < yhigh; yo++) { + double fxi, fyi; /* input coordinates */ + double dx, dy; /* xo derivative of input coord. */ + double ddx, ddy; /* 2nd xo derivative of input coord. */ + VipsPel *q; + + fxi = xlow + vec[0]; /* order 0 */ fyi = yo + vec[1]; dx = 1.0; dy = 0.0; + ddx = 0.0; + ddy = 0.0; switch (quadratic->order) { case 3: @@ -193,7 +192,7 @@ vips_quadratic_gen(VipsRegion *out_region, q = VIPS_REGION_ADDR(out_region, xlow, yo); - for (xo = xlow; xo < xhigh; xo++) { + for (int xo = xlow; xo < xhigh; xo++) { int xi = fxi; int yi = fyi; From dfc1d15daa3cde7ef682c06e69514e94192f856c Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 15 Apr 2025 12:37:53 +0100 Subject: [PATCH 125/174] clarify some comments --- libvips/colour/icc_transform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 313edd5317..0051638305 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -936,7 +936,7 @@ vips_icc_import_line(VipsColour *colour, float *q; int i; - /* Buffer of encoded 16-bit pixels we transform. + /* Transform to PCS pixels here. */ guint16 encoded[3 * PIXEL_BUFFER_SIZE]; @@ -1098,7 +1098,7 @@ vips_icc_export_line_xyz(VipsColour *colour, VipsPel *q; int x; - /* Buffer of encoded float pixels we transform to device space. + /* Buffer of PCS pixels we transform to device space. */ float encoded[3 * PIXEL_BUFFER_SIZE]; From 9df3b96ac873672a197b55090907b2b74e737827 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 15 Apr 2025 14:25:16 +0100 Subject: [PATCH 126/174] use vips_image_decode() in colour.c --- libvips/colour/colour.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libvips/colour/colour.c b/libvips/colour/colour.c index d917c1558d..aa59183e5f 100644 --- a/libvips/colour/colour.c +++ b/libvips/colour/colour.c @@ -407,9 +407,9 @@ vips_colour_code_build(VipsObject *object) /* If this is a LABQ and the coder wants uncoded, unpack. */ if (in && - in->Coding == VIPS_CODING_LABQ && - code->input_coding == VIPS_CODING_NONE) { - if (vips_LabQ2Lab(in, &t[0], NULL)) + code->input_coding == VIPS_CODING_NONE && + in->Coding != code->input_coding) { + if (vips_image_decode(in, &t[0])) return -1; in = t[0]; } From a7e8f464e3dec9b1efcc0c81f2978b1e0646b2fb Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 16 Apr 2025 15:58:12 +0100 Subject: [PATCH 127/174] fix linear resize of 16-bit rgba (#4467) * fix linear resize of 16-bit rgba We were changing the interpretation in icc_import and icc_export, but we were not rescaling the alpha. As a result, 16-bit RGBA images had a alpha of 65535 in PCS, not 255. This PR moves alpha channel scaling into the base VipsColour class, so we get correct scaling automatically, and moves XYZ <-> scRGB conversion back on top of VipsColourCode, partially reverting #3627 see https://github.com/libvips/libvips/issues/4343 * Update libvips/colour/colour.c Co-authored-by: Kleis Auke Wolthuizen * review comments --------- Co-authored-by: Kleis Auke Wolthuizen --- libvips/colour/XYZ2scRGB.c | 125 ++++----------------------------- libvips/colour/colour.c | 54 ++++++++------- libvips/colour/scRGB2XYZ.c | 137 ++++--------------------------------- 3 files changed, 58 insertions(+), 258 deletions(-) diff --git a/libvips/colour/XYZ2scRGB.c b/libvips/colour/XYZ2scRGB.c index 3329d90aa6..a882d85747 100644 --- a/libvips/colour/XYZ2scRGB.c +++ b/libvips/colour/XYZ2scRGB.c @@ -47,20 +47,10 @@ #include "pcolour.h" -/* We can't use VipsColourCode as our parent class. We want to handle - * alpha ourselves. - */ - -typedef struct _VipsXYZ2scRGB { - VipsOperation parent_instance; - - VipsImage *in; - VipsImage *out; -} VipsXYZ2scRGB; +typedef VipsColourTransform VipsXYZ2scRGB; +typedef VipsColourTransformClass VipsXYZ2scRGBClass; -typedef VipsOperationClass VipsXYZ2scRGBClass; - -G_DEFINE_TYPE(VipsXYZ2scRGB, vips_XYZ2scRGB, VIPS_TYPE_OPERATION); +G_DEFINE_TYPE(VipsXYZ2scRGB, vips_XYZ2scRGB, VIPS_TYPE_COLOUR_TRANSFORM); /* We used to have the comment: @@ -79,12 +69,12 @@ G_DEFINE_TYPE(VipsXYZ2scRGB, vips_XYZ2scRGB, VIPS_TYPE_OPERATION); */ static void -vips_XYZ2scRGB_line(float *restrict q, float *restrict p, - int extra_bands, int width) +vips_XYZ2scRGB_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) { - int i, j; + float *restrict p = (float *) in[0]; + float *restrict q = (float *) out; - for (i = 0; i < width; i++) { + for (int i = 0; i < width; i++) { const float X = p[0]; const float Y = p[1]; const float Z = p[2]; @@ -100,118 +90,27 @@ vips_XYZ2scRGB_line(float *restrict q, float *restrict p, q[2] = B; q += 3; - - for (j = 0; j < extra_bands; j++) - q[j] = VIPS_CLIP(0, p[j] / 255.0, 1.0); - p += extra_bands; - q += extra_bands; } } -static int -vips_XYZ2scRGB_gen(VipsRegion *out_region, - void *seq, void *a, void *b, gboolean *stop) -{ - VipsRegion *ir = (VipsRegion *) seq; - VipsRect *r = &out_region->valid; - VipsImage *in = ir->im; - - int y; - - if (vips_region_prepare(ir, r)) - return -1; - - VIPS_GATE_START("vips_XYZ2scRGB: work"); - - for (y = 0; y < r->height; y++) { - float *p = (float *) - VIPS_REGION_ADDR(ir, r->left, r->top + y); - float *q = (float *) - VIPS_REGION_ADDR(out_region, r->left, r->top + y); - - vips_XYZ2scRGB_line(q, p, in->Bands - 3, r->width); - } - - VIPS_GATE_STOP("vips_XYZ2scRGB: work"); - - return 0; -} - -static int -vips_XYZ2scRGB_build(VipsObject *object) -{ - VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); - VipsXYZ2scRGB *XYZ2scRGB = (VipsXYZ2scRGB *) object; - - VipsImage **t = (VipsImage **) vips_object_local_array(object, 2); - - VipsImage *in; - VipsImage *out; - - if (VIPS_OBJECT_CLASS(vips_XYZ2scRGB_parent_class)->build(object)) - return -1; - - in = XYZ2scRGB->in; - if (vips_check_bands_atleast(class->nickname, in, 3)) - return -1; - - if (vips_cast_float(in, &t[0], NULL)) - return -1; - in = t[0]; - - out = vips_image_new(); - if (vips_image_pipelinev(out, - VIPS_DEMAND_STYLE_THINSTRIP, in, NULL)) { - g_object_unref(out); - return -1; - } - out->Type = VIPS_INTERPRETATION_scRGB; - out->BandFmt = VIPS_FORMAT_FLOAT; - - if (vips_image_generate(out, - vips_start_one, vips_XYZ2scRGB_gen, vips_stop_one, - in, XYZ2scRGB)) { - g_object_unref(out); - return -1; - } - - g_object_set(object, "out", out, NULL); - - return 0; -} - static void vips_XYZ2scRGB_class_init(VipsXYZ2scRGBClass *class) { - GObjectClass *gobject_class = G_OBJECT_CLASS(class); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsOperationClass *operation_class = VIPS_OPERATION_CLASS(class); - - gobject_class->set_property = vips_object_set_property; - gobject_class->get_property = vips_object_get_property; + VipsColourClass *colour_class = VIPS_COLOUR_CLASS(class); object_class->nickname = "XYZ2scRGB"; object_class->description = _("transform XYZ to scRGB"); - object_class->build = vips_XYZ2scRGB_build; - - operation_class->flags = VIPS_OPERATION_SEQUENTIAL; - VIPS_ARG_IMAGE(class, "in", 1, - _("Input"), - _("Input image"), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET(VipsXYZ2scRGB, in)); - - VIPS_ARG_IMAGE(class, "out", 100, - _("Output"), - _("Output image"), - VIPS_ARGUMENT_REQUIRED_OUTPUT, - G_STRUCT_OFFSET(VipsXYZ2scRGB, out)); + colour_class->process_line = vips_XYZ2scRGB_line; } static void vips_XYZ2scRGB_init(VipsXYZ2scRGB *XYZ2scRGB) { + VipsColour *colour = VIPS_COLOUR(XYZ2scRGB); + + colour->interpretation = VIPS_INTERPRETATION_scRGB; } /** diff --git a/libvips/colour/colour.c b/libvips/colour/colour.c index aa59183e5f..3bc9d6e2f9 100644 --- a/libvips/colour/colour.c +++ b/libvips/colour/colour.c @@ -165,8 +165,6 @@ vips_colour_build(VipsObject *object) VipsImage **extra_bands; VipsImage *out; - int i; - #ifdef DEBUG printf("vips_colour_build: "); vips_object_print_name(object); @@ -177,11 +175,10 @@ vips_colour_build(VipsObject *object) return -1; if (colour->n > MAX_INPUT_IMAGES) { - vips_error(class->nickname, - "%s", _("too many input images")); + vips_error(class->nickname, "%s", _("too many input images")); return -1; } - for (i = 0; i < colour->n; i++) + for (int i = 0; i < colour->n; i++) if (vips_image_pio_input(colour->in[i])) return -1; @@ -201,7 +198,7 @@ vips_colour_build(VipsObject *object) VipsImage **new_in = (VipsImage **) vips_object_local_array(object, colour->n); - for (i = 0; i < colour->n; i++) { + for (int i = 0; i < colour->n; i++) { if (vips_check_bands_atleast(class->nickname, in[i], colour->input_bands)) return -1; @@ -246,39 +243,50 @@ vips_colour_build(VipsObject *object) if (vips_image_generate(out, vips_start_many, vips_colour_gen, vips_stop_many, in, colour)) { - g_object_unref(out); + VIPS_UNREF(out); return -1; } /* Reattach higher bands, if necessary. If we have more than one input * image, just use the first extra bands. */ - for (i = 0; i < colour->n; i++) + for (int i = 0; i < colour->n; i++) if (extra_bands[i]) { - VipsImage *t1, *t2; + VipsImage **t = (VipsImage **) vips_object_local_array(object, 3); + + double max_alpha_before = + vips_interpretation_max_alpha(extra_bands[i]->Type); + double max_alpha_after = + vips_interpretation_max_alpha(out->Type); + + VipsImage *alpha; - /* We can't just reattach the extra bands: they might - * be float (for example) and we might be trying to - * make a short image. Cast extra to match the body of - * the image. + alpha = extra_bands[i]; + + /* Rescale, if the alpha scale has changed. */ + if (max_alpha_before != max_alpha_after) { + if (vips_linear1(alpha, &t[0], + max_alpha_after / max_alpha_before, 0.0, NULL)) { + VIPS_UNREF(out); + return -1; + } + alpha = t[0]; + } - if (vips_cast(extra_bands[i], &t1, out->BandFmt, - "shift", TRUE, - NULL)) { - g_object_unref(out); + if (vips_cast(alpha, &t[1], out->BandFmt, NULL)) { + VIPS_UNREF(out); return -1; } + alpha = t[1]; - if (vips_bandjoin2(out, t1, &t2, - NULL)) { - g_object_unref(t1); - g_object_unref(out); + if (vips_bandjoin2(out, alpha, &t[2], NULL)) { + VIPS_UNREF(out); return -1; } g_object_unref(out); - g_object_unref(t1); - out = t2; + out = t[2]; + t[2] = NULL; break; } diff --git a/libvips/colour/scRGB2XYZ.c b/libvips/colour/scRGB2XYZ.c index a7bee766fa..2bcd6a2091 100644 --- a/libvips/colour/scRGB2XYZ.c +++ b/libvips/colour/scRGB2XYZ.c @@ -49,28 +49,18 @@ #include "pcolour.h" -/* We can't use VipsColourCode as our parent class. We want to handle - * alpha ourselves. - */ - -typedef struct _VipsscRGB2XYZ { - VipsOperation parent_instance; - - VipsImage *in; - VipsImage *out; -} VipsscRGB2XYZ; +typedef VipsColourTransform VipsscRGB2XYZ; +typedef VipsColourTransformClass VipsscRGB2XYZClass; -typedef VipsOperationClass VipsscRGB2XYZClass; - -G_DEFINE_TYPE(VipsscRGB2XYZ, vips_scRGB2XYZ, VIPS_TYPE_OPERATION); +G_DEFINE_TYPE(VipsscRGB2XYZ, vips_scRGB2XYZ, VIPS_TYPE_COLOUR_TRANSFORM); static void -vips_scRGB2XYZ_line(float *restrict q, float *restrict p, - int extra_bands, int width) +vips_scRGB2XYZ_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) { - int i, j; + float *restrict p = (float *) in[0]; + float *restrict q = (float *) out; - for (i = 0; i < width; i++) { + for (int i = 0; i < width; i++) { const float R = p[0] * VIPS_D65_Y0; const float G = p[1] * VIPS_D65_Y0; const float B = p[2] * VIPS_D65_Y0; @@ -79,130 +69,33 @@ vips_scRGB2XYZ_line(float *restrict q, float *restrict p, * as the original is defined in a separate file and is part of * the public API so a compiler will not inline. */ - q[0] = 0.4124F * R + - 0.3576F * G + - 0.1805F * B; - q[1] = 0.2126F * R + - 0.7152F * G + - 0.0722F * B; - q[2] = 0.0193F * R + - 0.1192F * G + - 0.9505F * B; + q[0] = 0.4124F * R + 0.3576F * G + 0.1805F * B; + q[1] = 0.2126F * R + 0.7152F * G + 0.0722F * B; + q[2] = 0.0193F * R + 0.1192F * G + 0.9505F * B; p += 3; q += 3; - - for (j = 0; j < extra_bands; j++) - q[j] = VIPS_FCLIP(0, p[j] * 255.0, 255.0); - p += extra_bands; - q += extra_bands; } } -static int -vips_scRGB2XYZ_gen(VipsRegion *out_region, - void *seq, void *a, void *b, gboolean *stop) -{ - VipsRegion *ir = (VipsRegion *) seq; - VipsRect *r = &out_region->valid; - VipsImage *in = ir->im; - - int y; - - if (vips_region_prepare(ir, r)) - return -1; - - VIPS_GATE_START("vips_scRGB2XYZ_gen: work"); - - for (y = 0; y < r->height; y++) { - float *p = (float *) - VIPS_REGION_ADDR(ir, r->left, r->top + y); - float *q = (float *) - VIPS_REGION_ADDR(out_region, r->left, r->top + y); - - vips_scRGB2XYZ_line(q, p, in->Bands - 3, r->width); - } - - VIPS_GATE_STOP("vips_scRGB2XYZ_gen: work"); - - return 0; -} - -static int -vips_scRGB2XYZ_build(VipsObject *object) -{ - VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); - VipsscRGB2XYZ *scRGB2XYZ = (VipsscRGB2XYZ *) object; - - VipsImage **t = (VipsImage **) vips_object_local_array(object, 2); - - VipsImage *in; - VipsImage *out; - - if (VIPS_OBJECT_CLASS(vips_scRGB2XYZ_parent_class)->build(object)) - return -1; - - in = scRGB2XYZ->in; - if (vips_check_bands_atleast(class->nickname, in, 3)) - return -1; - - if (vips_cast_float(in, &t[0], NULL)) - return -1; - in = t[0]; - - out = vips_image_new(); - if (vips_image_pipelinev(out, - VIPS_DEMAND_STYLE_THINSTRIP, in, NULL)) { - g_object_unref(out); - return -1; - } - out->Type = VIPS_INTERPRETATION_XYZ; - out->BandFmt = VIPS_FORMAT_FLOAT; - - if (vips_image_generate(out, - vips_start_one, vips_scRGB2XYZ_gen, vips_stop_one, - in, scRGB2XYZ)) { - g_object_unref(out); - return -1; - } - - g_object_set(object, "out", out, NULL); - - return 0; -} - static void vips_scRGB2XYZ_class_init(VipsscRGB2XYZClass *class) { - GObjectClass *gobject_class = G_OBJECT_CLASS(class); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsOperationClass *operation_class = VIPS_OPERATION_CLASS(class); - - gobject_class->set_property = vips_object_set_property; - gobject_class->get_property = vips_object_get_property; + VipsColourClass *colour_class = VIPS_COLOUR_CLASS(class); object_class->nickname = "scRGB2XYZ"; object_class->description = _("transform scRGB to XYZ"); - object_class->build = vips_scRGB2XYZ_build; - - operation_class->flags = VIPS_OPERATION_SEQUENTIAL; - VIPS_ARG_IMAGE(class, "in", 1, - _("Input"), - _("Input image"), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET(VipsscRGB2XYZ, in)); - - VIPS_ARG_IMAGE(class, "out", 100, - _("Output"), - _("Output image"), - VIPS_ARGUMENT_REQUIRED_OUTPUT, - G_STRUCT_OFFSET(VipsscRGB2XYZ, out)); + colour_class->process_line = vips_scRGB2XYZ_line; } static void vips_scRGB2XYZ_init(VipsscRGB2XYZ *scRGB2XYZ) { + VipsColour *colour = VIPS_COLOUR(scRGB2XYZ); + + colour->interpretation = VIPS_INTERPRETATION_XYZ; } /** From d003027b5a1e6a32cbb55560c751cbc05ddc9b57 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 17 Apr 2025 12:34:22 +0200 Subject: [PATCH 128/174] doc: fix a couple of `seealso` admonitions (#4471) --- libvips/convolution/canny.c | 2 +- libvips/iofuncs/init.c | 2 +- libvips/iofuncs/source.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libvips/convolution/canny.c b/libvips/convolution/canny.c index 7b08e787bd..f2e1457290 100644 --- a/libvips/convolution/canny.c +++ b/libvips/convolution/canny.c @@ -498,7 +498,7 @@ vips_canny_init(VipsCanny *canny) * edges. * * ::: seealso - * vips_sobel(). + * [method@Image.sobel]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 5ccabd89ff..78432515d5 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -266,7 +266,7 @@ vips_get_prgname(void) * * ::: seealso * [func@shutdown], [func@add_option_entries], [func@version], - * [func@guess_prefix], [func@guess_libdir]. + * [func@guess_prefix], [func@guess_libdir]. * * Returns: 0 on success, -1 otherwise */ diff --git a/libvips/iofuncs/source.c b/libvips/iofuncs/source.c index 1da8894193..e679e55ffa 100644 --- a/libvips/iofuncs/source.c +++ b/libvips/iofuncs/source.c @@ -139,7 +139,7 @@ static gint64 vips__pipe_read_limit = 1024 * 1024 * 1024; * * ::: seealso * `--vips-pipe-read-limit` and the environment variable - * `VIPS_PIPE_READ_LIMIT`. + * `VIPS_PIPE_READ_LIMIT`. */ void vips_pipe_read_limit_set(gint64 limit) From d5fb8169b8ff205d7fa6e9a35c18710c162cb6eb Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 17 Apr 2025 15:14:47 +0100 Subject: [PATCH 129/174] update conversion docs (#4472) * ooof update conversion docs to new format, revise arithmetic and colour * fix icc_transform optional args --- doc/rename.sed | 30 +++++++++- libvips/arithmetic/clamp.c | 8 +-- libvips/arithmetic/find_trim.c | 18 +++--- libvips/arithmetic/hist_find.c | 6 +- libvips/arithmetic/hist_find_indexed.c | 10 ++-- libvips/arithmetic/hist_find_ndim.c | 6 +- libvips/arithmetic/hough_circle.c | 10 ++-- libvips/arithmetic/hough_line.c | 8 +-- libvips/arithmetic/linear.c | 13 ++-- libvips/arithmetic/max.c | 16 ++--- libvips/arithmetic/measure.c | 12 ++-- libvips/arithmetic/min.c | 16 ++--- libvips/colour/Lab2XYZ.c | 7 +-- libvips/colour/XYZ2Lab.c | 7 +-- libvips/colour/colourspace.c | 12 ++-- libvips/colour/icc_transform.c | 67 ++++++++++----------- libvips/colour/scRGB2BW.c | 11 ++-- libvips/colour/scRGB2sRGB.c | 11 ++-- libvips/conversion/addalpha.c | 3 +- libvips/conversion/arrayjoin.c | 24 ++++---- libvips/conversion/autorot.c | 11 ++-- libvips/conversion/bandbool.c | 35 +++++------ libvips/conversion/bandfold.c | 10 ++-- libvips/conversion/bandjoin.c | 8 ++- libvips/conversion/bandmean.c | 3 +- libvips/conversion/bandrank.c | 10 ++-- libvips/conversion/bandunfold.c | 10 ++-- libvips/conversion/byteswap.c | 3 +- libvips/conversion/cache.c | 22 +++---- libvips/conversion/cast.c | 62 +++++++++---------- libvips/conversion/conversion.c | 83 ++++++++++++++------------ libvips/conversion/copy.c | 34 ++++++----- libvips/conversion/embed.c | 34 +++++------ libvips/conversion/extract.c | 18 +++--- libvips/conversion/falsecolour.c | 3 +- libvips/conversion/flatten.c | 17 +++--- libvips/conversion/flip.c | 3 +- libvips/conversion/gamma.c | 10 ++-- libvips/conversion/grid.c | 3 +- libvips/conversion/ifthenelse.c | 22 +++---- libvips/conversion/insert.c | 12 ++-- libvips/conversion/join.c | 21 ++++--- libvips/conversion/msb.c | 10 ++-- libvips/conversion/premultiply.c | 32 +++++----- libvips/conversion/recomb.c | 3 +- libvips/conversion/replicate.c | 3 +- libvips/conversion/rot.c | 22 ++++--- libvips/conversion/rot45.c | 12 ++-- libvips/conversion/scale.c | 12 ++-- libvips/conversion/sequential.c | 14 ++--- libvips/conversion/smartcrop.c | 19 +++--- libvips/conversion/subsample.c | 14 ++--- libvips/conversion/switch.c | 5 +- libvips/conversion/tilecache.c | 64 ++++++++++---------- libvips/conversion/transpose3d.c | 10 ++-- libvips/conversion/unpremultiply.c | 34 +++++------ libvips/conversion/wrap.c | 15 ++--- libvips/conversion/zoom.c | 3 +- 58 files changed, 521 insertions(+), 480 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index c11ad7b82b..b33181aae3 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -121,6 +121,7 @@ s/vips_\(cos\)()/[method@Image.\1]/g s/vips_\(countlines\)()/[method@Image.\1]/g s/vips_\(crop\)()/[method@Image.\1]/g s/vips_\(cross_phase\)()/[method@Image.\1]/g +s/vips_\(csvload\)()/[ctor@Image.\1]/g s/vips_\(csvsave\)()/[method@Image.\1]/g s/vips_\(csvsave_target\)()/[method@Image.\1]/g s/vips_\(dE00\)()/[method@Image.\1]/g @@ -199,6 +200,7 @@ s/vips_\(HSV2sRGB\)()/[method@Image.\1]/g s/vips_\(icc_export\)()/[method@Image.\1]/g s/vips_\(icc_import\)()/[method@Image.\1]/g s/vips_\(icc_transform\)()/[method@Image.\1]/g +s/vips_\(identity\)()/[ctor@Image.\1]/g s/vips_\(ifthenelse\)()/[method@Image.\1]/g s/vips_image_\(get_typeof\)()/[method@Image.\1]/g s/vips_\(imag\)()/[method@Image.\1]/g @@ -210,6 +212,7 @@ s/vips_\(join\)()/[method@Image.\1]/g s/vips_\(jp2ksave_buffer\)()/[method@Image.\1]/g s/vips_\(jp2ksave\)()/[method@Image.\1]/g s/vips_\(jp2ksave_target\)()/[method@Image.\1]/g +s/vips_\(jpegload\)()/[ctor@Image.\1]/g s/vips_\(jpegsave_buffer\)()/[method@Image.\1]/g s/vips_\(jpegsave\)()/[method@Image.\1]/g s/vips_\(jpegsave_mime\)()/[method@Image.\1]/g @@ -285,10 +288,13 @@ s/vips_\(orimage_const\)()/[method@Image.\1]/g s/vips_\(orimage\)()/[method@Image.\1]/g s/vips_\(percent\)()/[method@Image.\1]/g s/vips_\(phasecor\)()/[method@Image.\1]/g +s/vips_\(pngload\)()/[ctor@Image.\1]/g s/vips_\(pngsave_buffer\)()/[method@Image.\1]/g s/vips_\(pngsave\)()/[method@Image.\1]/g s/vips_\(pngsave_target\)()/[method@Image.\1]/g s/vips_\(polar\)()/[method@Image.\1]/g +s/vips_\(pow_const1\)()/[method@Image.\1]/g +s/vips_\(pow_const\)()/[method@Image.\1]/g s/vips_\(pow\)()/[method@Image.\1]/g s/vips_\(ppmsave\)()/[method@Image.\1]/g s/vips_\(ppmsave_target\)()/[method@Image.\1]/g @@ -302,6 +308,7 @@ s/vips_\(radsave_buffer\)()/[method@Image.\1]/g s/vips_\(radsave\)()/[method@Image.\1]/g s/vips_\(radsave_target\)()/[method@Image.\1]/g s/vips_\(rank\)()/[method@Image.\1]/g +s/vips_\(rawload\)()/[ctor@Image.\1]/g s/vips_\(rawsave_buffer\)()/[method@Image.\1]/g s/vips_\(rawsave_fd\)()/[method@Image.\1]/g s/vips_\(rawsave\)()/[method@Image.\1]/g @@ -381,15 +388,29 @@ s/vips_\(XYZ2Yxy\)()/[method@Image.\1]/g s/vips_\(Yxy2XYZ\)()/[method@Image.\1]/g s/vips_\(zoom\)()/[method@Image.\1]/g +s/vips_\(arrayjoin\)()/[func@Image.\1]/g +s/vips_\(bandjoin\)()/[func@Image.\1]/g +s/vips_\(bandrank\)()/[func@Image.\1]/g +s/vips_\(composite\)()/[func@Image.\1]/g +s/vips_\(sum\)()/[func@Image.\1]/g +s/vips_\(switch\)()/[func@Image.\1]/g + s/vips_\([^(]*\)()/[func@\1]/g +s/#Vips\(Extend\)/[enum@\1]/g +s/#Vips\(Angle45\)/[enum@\1]/g +s/#Vips\(Interesting\)/[enum@\1]/g s/#Vips\(Access\)/[enum@\1]/g +s/#Vips\(Align\)/[enum@\1]/g +s/#Vips\(Angle\)/[enum@\1]/g +s/#Vips\(ArgumentFlags\)/[flags@\1]/g s/#Vips\(BandFormat\)/[enum@\1]/g -s/#Vips\(Interpretation\)/[enum@\1]/g s/#Vips\(Coding\)/[enum@\1]/g s/#Vips\(DemandStyle\)/[enum@\1]/g +s/#Vips\(Intent\)/[enum@\1]/g +s/#Vips\(Interpretation\)/[enum@\1]/g +s/#Vips\(PCS\)/[enum@\1]/g s/#Vips\(Precision\)/[enum@\1]/g -s/#Vips\(ArgumentFlags\)/[flags@\1]/g s/#Vips\(Rect\)/[struct@\1]/g s/#Vips\(Progress\)/[struct@\1]/g @@ -420,6 +441,7 @@ s/#Vips\(ThreadpoolWorkFn\)/[callback@\1]/g s/#Vips\(ThreadpoolProgressFn\)/[callback@\1]/g s/#VIPS_OPERATION_MATH_\([^ ,.]*\)/[enum@Vips.OperationMath.\1]/g +s/#VIPS_PCS_\([^ ,.]*\)/[enum@Vips.PCS.\1]/g s/#VIPS_OPERATION_MATH2_\([^ ,.]*\)/[enum@Vips.OperationMath2.\1]/g s/#VIPS_OPERATION_RELATIONAL_\([^ ,.]*\)/[enum@Vips.OperationRelational.\1]/g s/#VIPS_OPERATION_BOOLEAN_\([^ ,.]*\)/[enum@Vips.OperationBoolean.\1]/g @@ -435,6 +457,8 @@ s/#VIPS_INTERPRETATION_\([^ ,.]*\)/[enum@Vips.Interpretation.\1]/g s/#VIPS_ACCESS_\([^ ,.]*\)/[enum@Vips.Access.\1]/g s/#VIPS_CODING_\([^ ,.]*\)/[enum@Vips.Coding.\1]/g +s/g_\(assert_not_reached\)/banana_\1_banana/g + s/g_thread_\([^(]*new\)()/[ctor@GLib.Thread.\1]/g s/g_object_\(new\)()/[ctor@GObject.Object.\1]/g s/g_object_\([^(]*\)()/[method@GObject.Object.\1]/g @@ -446,3 +470,5 @@ s/%GInput/[class@Gio.Input]/g s/%GSList/[struct@GLib.SList]/g s/g_\([^(]*\)()/[func@GLib.\1]/g + +s/banana_\(.*\)_banana/g_\1/g diff --git a/libvips/arithmetic/clamp.c b/libvips/arithmetic/clamp.c index 02bb6278ae..4d51fdbf3d 100644 --- a/libvips/arithmetic/clamp.c +++ b/libvips/arithmetic/clamp.c @@ -186,14 +186,14 @@ vips_clamp_init(VipsClamp *clamp) * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @min: %gdouble, minimum value - * * @max: %gdouble, maximum value - * * This operation clamps pixel values to a range, by default 0 - 1. * * Use @min and @max to change the range. * + * ::: tip "Optional arguments" + * * @min: %gdouble, minimum value + * * @max: %gdouble, maximum value + * * ::: seealso * [method@Image.sign], [method@Image.abs], [ctor@Image.sdf]. * diff --git a/libvips/arithmetic/find_trim.c b/libvips/arithmetic/find_trim.c index af1723cdf9..f7af45c515 100644 --- a/libvips/arithmetic/find_trim.c +++ b/libvips/arithmetic/find_trim.c @@ -256,11 +256,6 @@ vips_find_trim_init(VipsFindTrim *find_trim) * @height: (out): output height * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @threshold: %gdouble, background / object threshold - * * @background: [struct@ArrayDouble], background colour - * * @line_art: %gboolean, enable line art mode - * * Search @in for the bounding box of the non-background area. * * Any alpha is flattened out, then the image is median-filtered (unless @@ -269,12 +264,12 @@ vips_find_trim_init(VipsFindTrim *find_trim) * the absolute difference are calculated from this binary image and searched * for the first row or column in each direction to obtain the bounding box. * - * If the image is entirely background, [method@Image.find_trim] returns @width == 0 - * and @height == 0. + * If the image is entirely background, [method@Image.find_trim] returns + * @width == 0 and @height == 0. * * @background defaults to 255, or 65535 for 16-bit images. Set another value, - * or use [method@Image.getpoint] to pick a value from an edge. You'll need to flatten - * before [method@Image.getpoint] to get a correct background value. + * or use [method@Image.getpoint] to pick a value from an edge. You'll need + * to flatten before [method@Image.getpoint] to get a correct background value. * * @threshold defaults to 10. * @@ -285,6 +280,11 @@ vips_find_trim_init(VipsFindTrim *find_trim) * * The image needs to be at least 3x3 pixels in size. * + * ::: tip "Optional arguments" + * * @threshold: %gdouble, background / object threshold + * * @background: [struct@ArrayDouble], background colour + * * @line_art: %gboolean, enable line art mode + * * ::: seealso * [method@Image.getpoint], [method@Image.extract_area], [method@Image.smartcrop]. * diff --git a/libvips/arithmetic/hist_find.c b/libvips/arithmetic/hist_find.c index fa1011795e..fc67898f07 100644 --- a/libvips/arithmetic/hist_find.c +++ b/libvips/arithmetic/hist_find.c @@ -453,9 +453,6 @@ vips_hist_find_init(VipsHistFind *hist_find) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @band: band to equalise - * * Find the histogram of @in. Find the histogram for band @band (producing a * one-band histogram), or for all bands (producing an n-band histogram) if * @band is -1. @@ -463,6 +460,9 @@ vips_hist_find_init(VipsHistFind *hist_find) * char and uchar images are cast to uchar before histogramming, all other * image types are cast to ushort. * + * ::: tip "Optional arguments" + * * @band: band to equalise + * * ::: seealso * [method@Image.hist_find_ndim], [method@Image.hist_find_indexed]. * diff --git a/libvips/arithmetic/hist_find_indexed.c b/libvips/arithmetic/hist_find_indexed.c index 4d2ef38cb5..fad61a47ec 100644 --- a/libvips/arithmetic/hist_find_indexed.c +++ b/libvips/arithmetic/hist_find_indexed.c @@ -498,8 +498,6 @@ vips_hist_find_indexed_init(VipsHistFindIndexed *indexed) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @combine: #VipsCombine, combine bins like this * * Make a histogram of @in, but use image @index to pick the bins. In other * words, element zero in @out contains the combination of all the pixels in @in @@ -515,8 +513,12 @@ vips_hist_find_indexed_init(VipsHistFindIndexed *indexed) * Normally, bins are summed, but you can use @combine to set other combine * modes. * - * This operation is useful in conjunction with [method@Image.labelregions]. You can - * use it to find the centre of gravity of blobs in an image, for example. + * This operation is useful in conjunction with [method@Image.labelregions]. + * You can use it to find the centre of gravity of blobs in an image, for + * example. + * + * ::: tip "Optional arguments" + * * @combine: #VipsCombine, combine bins like this * * ::: seealso * [method@Image.hist_find], [method@Image.labelregions]. diff --git a/libvips/arithmetic/hist_find_ndim.c b/libvips/arithmetic/hist_find_ndim.c index d403477f23..bb35016cd3 100644 --- a/libvips/arithmetic/hist_find_ndim.c +++ b/libvips/arithmetic/hist_find_ndim.c @@ -335,9 +335,6 @@ vips_hist_find_ndim_init(VipsHistFindNDim *ndim) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @bins: number of bins to make on each axis - * * Make a one, two or three dimensional histogram of a 1, 2 or * 3 band image. Divide each axis into @bins bins .. ie. * output is 1 x bins, bins x bins, or bins x bins x bins bands. @@ -346,6 +343,9 @@ vips_hist_find_ndim_init(VipsHistFindNDim *ndim) * char and uchar images are cast to uchar before histogramming, all other * image types are cast to ushort. * + * ::: tip "Optional arguments" + * * @bins: number of bins to make on each axis + * * ::: seealso * [method@Image.hist_find], [method@Image.hist_find_indexed]. * diff --git a/libvips/arithmetic/hough_circle.c b/libvips/arithmetic/hough_circle.c index 8287eebdbb..8c538bd113 100644 --- a/libvips/arithmetic/hough_circle.c +++ b/libvips/arithmetic/hough_circle.c @@ -265,11 +265,6 @@ vips_hough_circle_init(VipsHoughCircle *hough_circle) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @scale: scale down dimensions by this much - * * @min_radius: smallest radius to search for - * * @max_radius: largest radius to search for - * * Find the circular Hough transform of an image. @in must be one band, with * non-zero pixels for image edges. @out is three-band, with the third channel * representing the detected circle radius. The operation scales the number of @@ -286,6 +281,11 @@ vips_hough_circle_init(VipsHoughCircle *hough_circle) * @in, and reduce the number of radii tested (and hence the number of bands * int @out) by a factor of three as well. * + * ::: tip "Optional arguments" + * * @scale: scale down dimensions by this much + * * @min_radius: smallest radius to search for + * * @max_radius: largest radius to search for + * * ::: seealso * [method@Image.hough_line]. * diff --git a/libvips/arithmetic/hough_line.c b/libvips/arithmetic/hough_line.c index ec14bfa251..7b1df999e8 100644 --- a/libvips/arithmetic/hough_line.c +++ b/libvips/arithmetic/hough_line.c @@ -171,10 +171,6 @@ vips_hough_line_init(VipsHoughLine *hough_line) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @width: horizontal size of parameter space - * * @height: vertical size of parameter space - * * Find the line Hough transform for @in. @in must have one band. @out has one * band, with pixels being the number of votes for that line. The X dimension * of @out is the line angle in 0 - 180 degrees, the Y dimension is the @@ -183,6 +179,10 @@ vips_hough_line_init(VipsHoughLine *hough_line) * Use @width @height to set the size of the parameter space image (@out), * that is, how accurate the line determination should be. * + * ::: tip "Optional arguments" + * * @width: horizontal size of parameter space + * * @height: vertical size of parameter space + * * ::: seealso * [method@Image.hough_circle]. * diff --git a/libvips/arithmetic/linear.c b/libvips/arithmetic/linear.c index 33c4a7924e..060a3eb6ab 100644 --- a/libvips/arithmetic/linear.c +++ b/libvips/arithmetic/linear.c @@ -505,9 +505,6 @@ vips_linearv(VipsImage *in, VipsImage **out, * @n: length of constant arrays * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @uchar: output uchar pixels - * * Pass an image through a linear transform, ie. (@out = @in * @a + @b). Output * is float for integer input, double for double input, complex for * complex input and double complex for double complex input. Set @uchar to @@ -520,6 +517,9 @@ vips_linearv(VipsImage *in, VipsImage **out, * element and the image only has a single band, the result is a many-band * image where each band corresponds to one array element. * + * ::: tip "Optional arguments" + * * @uchar: output uchar pixels + * * ::: seealso * [method@Image.linear1], [method@Image.add]. * @@ -547,12 +547,11 @@ vips_linear(VipsImage *in, VipsImage **out, * @b: constant for addition * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @uchar: output uchar pixels - * * Run [method@Image.linear] with a single constant. * + * ::: tip "Optional arguments" + * * @uchar: output uchar pixels + * * ::: seealso * [method@Image.linear]. * diff --git a/libvips/arithmetic/max.c b/libvips/arithmetic/max.c index c4c436c1c7..9eaa80a9e6 100644 --- a/libvips/arithmetic/max.c +++ b/libvips/arithmetic/max.c @@ -510,14 +510,6 @@ vips_max_init(VipsMax *max) * @out: (out): output pixel maximum * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @x: horizontal position of maximum - * * @y: vertical position of maximum - * * @size: number of maxima to find - * * @out_array: return array of maximum values - * * @x_array: corresponding horizontal positions - * * @y_array: corresponding vertical positions - * * This operation finds the maximum value in an image. * * By default it finds the single largest value. If @size is set >1, it will @@ -539,6 +531,14 @@ vips_max_init(VipsMax *max) * If there are more than @size maxima, the maxima returned will be a random * selection of the maxima in the image. * + * ::: tip "Optional arguments" + * * @x: horizontal position of maximum + * * @y: vertical position of maximum + * * @size: number of maxima to find + * * @out_array: return array of maximum values + * * @x_array: corresponding horizontal positions + * * @y_array: corresponding vertical positions + * * ::: seealso * [method@Image.min], [method@Image.stats]. * diff --git a/libvips/arithmetic/measure.c b/libvips/arithmetic/measure.c index 7d81687c2b..0d747441a5 100644 --- a/libvips/arithmetic/measure.c +++ b/libvips/arithmetic/measure.c @@ -259,12 +259,6 @@ vips_measure_init(VipsMeasure *measure) * @v: patches down chart * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @left: area of image containing chart - * * @top: area of image containing chart - * * @width: area of image containing chart - * * @height: area of image containing chart - * * Analyse a grid of colour patches, producing an array of patch averages. * The mask has a row for each measured patch and a column for each image * band. The operations issues a warning if any patch has a deviation more @@ -275,6 +269,12 @@ vips_measure_init(VipsMeasure *measure) * @width, @height arguments to indicate the * position of the chart. * + * ::: tip "Optional arguments" + * * @left: area of image containing chart + * * @top: area of image containing chart + * * @width: area of image containing chart + * * @height: area of image containing chart + * * ::: seealso * [method@Image.avg], [method@Image.deviate]. * diff --git a/libvips/arithmetic/min.c b/libvips/arithmetic/min.c index 8aee643744..e8f651fa94 100644 --- a/libvips/arithmetic/min.c +++ b/libvips/arithmetic/min.c @@ -510,14 +510,6 @@ vips_min_init(VipsMin *min) * @out: (out): output pixel minimum * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @x: horizontal position of minimum - * * @y: vertical position of minimum - * * @size: number of minima to find - * * @out_array: return array of minimum values - * * @x_array: corresponding horizontal positions - * * @y_array: corresponding vertical positions - * * This operation finds the minimum value in an image. * * By default it finds the single smallest value. If @size is set >1, it will @@ -540,6 +532,14 @@ vips_min_init(VipsMin *min) * If there are more than @size minima, the minima returned will be a random * selection of the minima in the image. * + * ::: tip "Optional arguments" + * * @x: horizontal position of minimum + * * @y: vertical position of minimum + * * @size: number of minima to find + * * @out_array: return array of minimum values + * * @x_array: corresponding horizontal positions + * * @y_array: corresponding vertical positions + * * ::: seealso * [method@Image.min], [method@Image.stats]. * diff --git a/libvips/colour/Lab2XYZ.c b/libvips/colour/Lab2XYZ.c index 870c183e32..87495900b3 100644 --- a/libvips/colour/Lab2XYZ.c +++ b/libvips/colour/Lab2XYZ.c @@ -205,13 +205,12 @@ vips_Lab2XYZ_init(VipsLab2XYZ *Lab2XYZ) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @temp: [struct@ArrayDouble], colour temperature - * * Turn Lab to XYZ. The colour temperature defaults to D65, but can be * specified with @temp. * + * ::: tip "Optional arguments" + * * @temp: [struct@ArrayDouble], colour temperature + * * Returns: 0 on success, -1 on error */ int diff --git a/libvips/colour/XYZ2Lab.c b/libvips/colour/XYZ2Lab.c index 9c60406876..7014632099 100644 --- a/libvips/colour/XYZ2Lab.c +++ b/libvips/colour/XYZ2Lab.c @@ -259,13 +259,12 @@ vips_XYZ2Lab_init(VipsXYZ2Lab *XYZ2Lab) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @temp: [struct@ArrayDouble], colour temperature - * * Turn XYZ to Lab, optionally specifying the colour temperature. @temp * defaults to D65. * + * ::: tip "Optional arguments" + * * @temp: [struct@ArrayDouble], colour temperature + * * Returns: 0 on success, -1 on error. */ int diff --git a/libvips/colour/colourspace.c b/libvips/colour/colourspace.c index 5afd3fac07..ca80fccb5b 100644 --- a/libvips/colour/colourspace.c +++ b/libvips/colour/colourspace.c @@ -593,17 +593,17 @@ vips_colourspace_init(VipsColourspace *colourspace) * @space: convert to this colour space * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @source_space: input colour space - * * This operation looks at the interpretation field of @in (or uses * @source_space, if set) and runs * a set of colourspace conversion functions to move it to @space. * * For example, given an image tagged as [enum@Vips.Interpretation.YXY], running - * [method@Image.colourspace] with @space set to [enum@Vips.Interpretation.LAB] will - * convert with [method@Image.Yxy2XYZ] and [method@Image.XYZ2Lab]. + * [method@Image.colourspace] with @space set to + * [enum@Vips.Interpretation.LAB] will convert with [method@Image.Yxy2XYZ] + * and [method@Image.XYZ2Lab]. + * + * ::: tip "Optional arguments" + * * @source_space: input colour space * * ::: seealso * [method@Image.colourspace_issupported], diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 0051638305..470a1ce50f 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -1440,16 +1440,9 @@ vips_icc_is_compatible_profile(VipsImage *image, * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Import an image from device space to D65 LAB with an ICC profile. * - * * @pcs: #VipsPCS, use XYZ or LAB PCS - * * @intent: #VipsIntent, transform with this intent - * * @black_point_compensation: %gboolean, enable black point compensation - * * @embedded: %gboolean, use profile embedded in input image - * * @input_profile: %gchararray, get the input profile from here - * - * Import an image from device space to D65 LAB with an ICC profile. If @pcs is - * set to #VIPS_PCS_XYZ, use CIE XYZ PCS instead. + * If @pcs is set to [enum@Vips.PCS.XYZ], use CIE XYZ PCS instead. * * The input profile is searched for in three places: * @@ -1459,7 +1452,7 @@ vips_icc_is_compatible_profile(VipsImage *image, * argument. This will return %GType 0 if there is no profile. * * 2. Otherwise, if @input_profile is set, libvips will try to load a - * profile from the named file. This can aslso be the name of one of the + * profile from the named file. This can also be the name of one of the * built-in profiles. * * 3. Otherwise, libvips will try to pick a compatible profile from the set @@ -1468,6 +1461,13 @@ vips_icc_is_compatible_profile(VipsImage *image, * If @black_point_compensation is set, LCMS black point compensation is * enabled. * + * ::: tip "Optional arguments" + * * @pcs: [enum@PCS], use XYZ or LAB PCS + * * @intent: [enum@Intent], transform with this intent + * * @black_point_compensation: %gboolean, enable black point compensation + * * @embedded: %gboolean, use profile embedded in input image + * * @input_profile: %gchararray, get the input profile from here + * * Returns: 0 on success, -1 on error. */ int @@ -1489,17 +1489,9 @@ vips_icc_import(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @pcs: #VipsPCS, use XYZ or LAB PCS - * * @intent: #VipsIntent, transform with this intent - * * @black_point_compensation: %gboolean, enable black point compensation - * * @output_profile: %gchararray, get the output profile from here - * * @depth: %gint, depth of output image in bits - * * Export an image from D65 LAB to device space with an ICC profile. - * If @pcs is - * set to #VIPS_PCS_XYZ, use CIE XYZ PCS instead. + * + * If @pcs is set to [enum@Vips.PCS.XYZ], use CIE XYZ PCS instead. * If @output_profile is not set, use the embedded profile, if any. * If @output_profile is set, export with that and attach it to the output * image. @@ -1507,6 +1499,13 @@ vips_icc_import(VipsImage *in, VipsImage **out, ...) * If @black_point_compensation is set, LCMS black point compensation is * enabled. * + * ::: tip "Optional arguments" + * * @pcs: [enum@PCS], use XYZ or LAB PCS + * * @intent: [enum@Intent], transform with this intent + * * @black_point_compensation: %gboolean, enable black point compensation + * * @output_profile: %gchararray, get the output profile from here + * * @depth: %gint, depth of output image in bits + * * Returns: 0 on success, -1 on error. */ int @@ -1529,18 +1528,10 @@ vips_icc_export(VipsImage *in, VipsImage **out, ...) * @output_profile: get the output profile from here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Transform an image with a pair of ICC profiles. * - * * @pcs: #VipsPCS, use XYZ or LAB PCS - * * @intent: #VipsIntent, transform with this intent - * * @black_point_compensation: %gboolean, enable black point compensation - * * @embedded: %gboolean, use profile embedded in input image - * * @input_profile: %gchararray, get the input profile from here - * * @depth: %gint, depth of output image in bits - * - * Transform an image with a pair of ICC profiles. The input image is moved to - * profile-connection space with the input profile and then to the output - * space with the output profile. + * The input image is moved to profile-connection space with the input + * profile and then to the output space with the output profile. * * The input profile is searched for in three places: * @@ -1550,7 +1541,7 @@ vips_icc_export(VipsImage *in, VipsImage **out, ...) * argument. This will return %GType 0 if there is no profile. * * 2. Otherwise, if @input_profile is set, libvips will try to load a - * profile from the named file. This can aslso be the name of one of the + * profile from the named file. This can also be the name of one of the * built-in profiles. * * 3. Otherwise, libvips will try to pick a compatible profile from the set @@ -1564,8 +1555,16 @@ vips_icc_export(VipsImage *in, VipsImage **out, ...) * The output image has the output profile attached to the #VIPS_META_ICC_NAME * field. * - * Use [method@Image.icc_import] and [method@Image.icc_export] to do either the first or - * second half of this operation in isolation. + * Use [method@Image.icc_import] and [method@Image.icc_export] to do either + * the first or second half of this operation in isolation. + * + * ::: tip "Optional arguments" + * * @pcs: [enum@PCS], use XYZ or LAB PCS + * * @intent: [enum@Intent], transform with this intent + * * @black_point_compensation: %gboolean, enable black point compensation + * * @embedded: %gboolean, use profile embedded in input image + * * @input_profile: %gchararray, get the input profile from here + * * @depth: %gint, depth of output image in bits * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/scRGB2BW.c b/libvips/colour/scRGB2BW.c index 080d1cb538..369ad1d66d 100644 --- a/libvips/colour/scRGB2BW.c +++ b/libvips/colour/scRGB2BW.c @@ -265,17 +265,14 @@ vips_scRGB2BW_init(VipsscRGB2BW *scRGB2BW) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @depth: depth of output image in bits - * * Convert an scRGB image to greyscale. Set @depth to 16 to get 16-bit output. * - * If @depth is 16, any extra channels after RGB are - * multiplied by 256. + * ::: tip "Optional arguments" + * * @depth: depth of output image in bits * * ::: seealso - * [method@Image.LabS2LabQ], [method@Image.sRGB2scRGB], [method@Image.rad2float]. + * [method@Image.LabS2LabQ], [method@Image.sRGB2scRGB], + * [method@Image.rad2float]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/scRGB2sRGB.c b/libvips/colour/scRGB2sRGB.c index 791b7cc393..82f9793188 100644 --- a/libvips/colour/scRGB2sRGB.c +++ b/libvips/colour/scRGB2sRGB.c @@ -298,17 +298,14 @@ vips_scRGB2sRGB_init(VipsscRGB2sRGB *scRGB2sRGB) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @depth: depth of output image in bits - * * Convert an scRGB image to sRGB. Set @depth to 16 to get 16-bit output. * - * If @depth is 16, any extra channels after RGB are - * multiplied by 256. + * ::: tip "Optional arguments" + * * @depth: depth of output image in bits * * ::: seealso - * [method@Image.LabS2LabQ], [method@Image.sRGB2scRGB], [method@Image.rad2float]. + * [method@Image.LabS2LabQ], [method@Image.sRGB2scRGB], + * [method@Image.rad2float]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/addalpha.c b/libvips/conversion/addalpha.c index 2932296481..6e11b2662a 100644 --- a/libvips/conversion/addalpha.c +++ b/libvips/conversion/addalpha.c @@ -106,7 +106,8 @@ vips_addalpha_init(VipsAddAlpha *addalpha) * * Append an alpha channel. * - * See also: vips_image_hasalpha(). + * ::: seealso + * [method@Image.hasalpha]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/arrayjoin.c b/libvips/conversion/arrayjoin.c index 8c086d1c23..97f8fc3af7 100644 --- a/libvips/conversion/arrayjoin.c +++ b/libvips/conversion/arrayjoin.c @@ -475,16 +475,6 @@ vips_arrayjoinv(VipsImage **in, VipsImage **out, int n, va_list ap) * @n: number of input images * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @across: %gint, number of images per row - * * @shim: %gint, space between images, in pixels - * * @background: #VipsArrayDouble, background ink colour - * * @halign: #VipsAlign, low, centre or high alignment - * * @valign: #VipsAlign, low, centre or high alignment - * * @hspacing: %gint, horizontal distance between images - * * @vspacing: %gint, vertical distance between images - * * Lay out the images in @in in a grid. The grid is @across images across and * however high is necessary to use up all of @in. Images are set down * left-to-right and top-to-bottom. @across defaults to @n. @@ -511,10 +501,20 @@ vips_arrayjoinv(VipsImage **in, VipsImage **out, int n, va_list ap) * Smallest common format in * arithmetic). * - * vips_colourspace() can be useful for moving the images to a common + * [method@Image.colourspace] can be useful for moving the images to a common * colourspace for compositing. * - * See also: vips_join(), vips_insert(), vips_colourspace(). + * ::: tip "Optional arguments" + * * @across: %gint, number of images per row + * * @shim: %gint, space between images, in pixels + * * @background: [struct@ArrayDouble], background ink colour + * * @halign: [enum@Align], low, centre or high alignment + * * @valign: [enum@Align], low, centre or high alignment + * * @hspacing: %gint, horizontal distance between images + * * @vspacing: %gint, vertical distance between images + * + * ::: seealso + * [method@Image.join], [method@Image.insert], [method@Image.colourspace]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/autorot.c b/libvips/conversion/autorot.c index 0dcedbd47a..f83be2d743 100644 --- a/libvips/conversion/autorot.c +++ b/libvips/conversion/autorot.c @@ -90,7 +90,7 @@ vips_autorot_remove_angle_sub(VipsImage *image, * @image: image to remove orientation from * * Remove the orientation tag on @image. Also remove any exif orientation tags. - * You must vips_copy() the image before calling this function since it + * You must [method@Image.copy] the image before calling this function since it * modifies metadata. */ void @@ -237,11 +237,6 @@ vips_autorot_init(VipsAutorot *autorot) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @angle: output #VipsAngle the image was rotated by - * * @flip: output %gboolean whether the image was flipped - * * Look at the image metadata and rotate and flip the image to make it * upright. The #VIPS_META_ORIENTATION tag is removed from @out to prevent * accidental double rotation. @@ -249,6 +244,10 @@ vips_autorot_init(VipsAutorot *autorot) * Read @angle to find the amount the image was rotated by. Read @flip to * see if the image was also flipped. * + * ::: tip "Optional arguments" + * * @angle: output [enum@Angle] the image was rotated by + * * @flip: output %gboolean whether the image was flipped + * * Returns: 0 on success, -1 on error */ int diff --git a/libvips/conversion/bandbool.c b/libvips/conversion/bandbool.c index 33b977a3f3..2709818891 100644 --- a/libvips/conversion/bandbool.c +++ b/libvips/conversion/bandbool.c @@ -258,14 +258,14 @@ vips_bandboolv(VipsImage *in, VipsImage **out, /** * vips_bandbool: (method) - * @in: left-hand input #VipsImage - * @out: (out): output #VipsImage + * @in: left-hand input [class@Image] + * @out: (out): output [class@Image] * @boolean: boolean operation to perform * @...: %NULL-terminated list of optional named arguments * * Perform various boolean operations across the bands of an image. For * example, a three-band uchar image operated on with - * #VIPS_OPERATION_BOOLEAN_AND will produce a one-band uchar image where each + * [enum@Vips.OperationBoolean.AND] will produce a one-band uchar image where each * pixel is the bitwise and of the band elements of the corresponding pixel in * the input image. * @@ -275,10 +275,11 @@ vips_bandboolv(VipsImage *in, VipsImage **out, * * The output image always has one band. * - * This operation is useful in conjunction with vips_relational(). You can use + * This operation is useful in conjunction with [method@Image.relational]. You can use * it to see if all image bands match exactly. * - * See also: vips_boolean_const(). + * ::: seealso + * [method@Image.boolean_const]. * * Returns: 0 on success, -1 on error */ @@ -298,12 +299,12 @@ vips_bandbool(VipsImage *in, VipsImage **out, /** * vips_bandand: (method) - * @in: left-hand input #VipsImage - * @out: (out): output #VipsImage + * @in: left-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_AND on an image. See - * vips_bandbool(). + * Perform [enum@Vips.OperationBoolean.AND] on an image. See + * [method@Image.bandbool]. * * Returns: 0 on success, -1 on error */ @@ -322,12 +323,12 @@ vips_bandand(VipsImage *in, VipsImage **out, ...) /** * vips_bandor: (method) - * @in: left-hand input #VipsImage - * @out: (out): output #VipsImage + * @in: left-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_OR on an image. See - * vips_bandbool(). + * Perform [enum@Vips.OperationBoolean.OR] on an image. See + * [method@Image.bandbool]. * * Returns: 0 on success, -1 on error */ @@ -346,12 +347,12 @@ vips_bandor(VipsImage *in, VipsImage **out, ...) /** * vips_bandeor: (method) - * @in: left-hand input #VipsImage - * @out: (out): output #VipsImage + * @in: left-hand input [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Perform #VIPS_OPERATION_BOOLEAN_EOR on an image. See - * vips_bandbool(). + * Perform [enum@Vips.OperationBoolean.EOR] on an image. See + * [method@Image.bandbool]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/bandfold.c b/libvips/conversion/bandfold.c index e56d73cec7..e1d3e0287b 100644 --- a/libvips/conversion/bandfold.c +++ b/libvips/conversion/bandfold.c @@ -185,16 +185,16 @@ vips_bandfold_init(VipsBandfold *bandfold) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @factor: fold by this factor - * * Fold up an image horizontally: width is collapsed into bands. * Use @factor to set how much to fold by: @factor 3, for example, will make * the output image three times narrower than the input, and with three times * as many bands. By default the whole of the input width is folded up. * - * See also: vips_csvload(), vips_bandunfold(). + * ::: tip "Optional arguments" + * * @factor: %gint, fold by this factor + * + * ::: seealso + * [ctor@Image.csvload], [method@Image.bandunfold]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/bandjoin.c b/libvips/conversion/bandjoin.c index 8150b038ab..1ba4270fa2 100644 --- a/libvips/conversion/bandjoin.c +++ b/libvips/conversion/bandjoin.c @@ -246,7 +246,8 @@ vips_bandjoinv(VipsImage **in, VipsImage **out, int n, va_list ap) * Smallest common format in * arithmetic). * - * See also: vips_insert(). + * ::: seealso + * [method@Image.insert]. * * Returns: 0 on success, -1 on error */ @@ -270,7 +271,7 @@ vips_bandjoin(VipsImage **in, VipsImage **out, int n, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Join a pair of images together, bandwise. See vips_bandjoin(). + * Join a pair of images together, bandwise. See [func@Image.bandjoin]. * * Returns: 0 on success, -1 on error */ @@ -477,7 +478,8 @@ vips_bandjoin_constv(VipsImage *in, VipsImage **out, * * Append a set of constant bands to an image. * - * See also: vips_bandjoin(). + * ::: seealso + * [func@Image.bandjoin]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/bandmean.c b/libvips/conversion/bandmean.c index 730e62eba8..c5448a865f 100644 --- a/libvips/conversion/bandmean.c +++ b/libvips/conversion/bandmean.c @@ -231,7 +231,8 @@ vips_bandmean_init(VipsBandmean *bandmean) * the same as the input band format. Integer types use round-to-nearest * averaging. * - * See also: vips_add(), vips_avg(), vips_recomb() + * ::: seealso + * [method@Image.add], [method@Image.avg], [method@Image.recomb] * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/bandrank.c b/libvips/conversion/bandrank.c index 4fa658a27c..9b6c9550c7 100644 --- a/libvips/conversion/bandrank.c +++ b/libvips/conversion/bandrank.c @@ -293,10 +293,6 @@ vips_bandrankv(VipsImage **in, VipsImage **out, int n, va_list ap) * @n: number of input images * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @index: pick this index from list of sorted values - * * Sorts the images @in band-element-wise, then outputs an * image in which each band element is selected from the sorted list by the * @index parameter. For example, if @index @@ -314,7 +310,11 @@ vips_bandrankv(VipsImage **in, VipsImage **out, int n, va_list ap) * * Smaller input images are expanded by adding black pixels. * - * See also: vips_rank(). + * ::: tip "Optional arguments" + * * @index: %gint, pick this index from list of sorted values + * + * ::: seealso + * [method@Image.rank]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/bandunfold.c b/libvips/conversion/bandunfold.c index 0ab05fd0fd..466bc96cc2 100644 --- a/libvips/conversion/bandunfold.c +++ b/libvips/conversion/bandunfold.c @@ -188,16 +188,16 @@ vips_bandunfold_init(VipsBandunfold *bandunfold) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @factor: unfold by this factor - * * Unfold image bands into x axis. * Use @factor to set how much to unfold by: @factor 3, for example, will make * the output image three times wider than the input, and with one third * as many bands. By default, all bands are unfolded. * - * See also: vips_csvload(), vips_bandfold(). + * ::: tip "Optional arguments" + * * @factor: unfold by this factor + * + * ::: seealso + * [ctor@Image.csvload], [method@Image.bandfold]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/byteswap.c b/libvips/conversion/byteswap.c index e2c3b33006..802e11d5e8 100644 --- a/libvips/conversion/byteswap.c +++ b/libvips/conversion/byteswap.c @@ -254,7 +254,8 @@ vips_byteswap_init(VipsByteswap *byteswap) * * Swap the byte order in an image. * - * See also: vips_rawload(). + * ::: seealso + * [ctor@Image.rawload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/cache.c b/libvips/conversion/cache.c index 6644411974..8ac1285098 100644 --- a/libvips/conversion/cache.c +++ b/libvips/conversion/cache.c @@ -1,4 +1,4 @@ -/* vips_sink_screen() as an operation. +/* [method@Image.sink_screen] as an operation. * * 13/1/12 * - from tilecache.c @@ -143,25 +143,19 @@ vips_cache_init(VipsCache *cache) } /** - * vips_cache: (method) + * vips_cache: * @in: input image * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @tile_width: width of tiles in cache - * * @tile_height: height of tiles in cache - * * @max_tiles: maximum number of tiles to cache - * - * This operation behaves rather like vips_copy() between images + * This operation behaves rather like [method@Image.copy] between images * @in and @out, except that it keeps a cache of computed pixels. * This cache is made of up to @max_tiles tiles (a value of -1 * means any number of tiles), and each tile is of size @tile_width * by @tile_height pixels. By default it will cache 250 128 x 128 pixel tiles, * enough for two 1920 x 1080 images. * - * This operation is a thin wrapper over vips_sink_screen(), see the + * This operation is a thin wrapper over [method@Image.sink_screen], see the * documentation for that operation for details. * * It uses a set of background threads to calculate pixels and the various @@ -170,7 +164,13 @@ vips_cache_init(VipsCache *cache) * of those pixels have been calculated. Pixels are calculated with a set of * threads. * - * See also: vips_tilecache(). + * ::: tip "Optional arguments" + * * @tile_width: width of tiles in cache + * * @tile_height: height of tiles in cache + * * @max_tiles: maximum number of tiles to cache + * + * ::: seealso + * [method@Image.tilecache]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/cast.c b/libvips/conversion/cast.c index 557e2dbdda..9eb908a464 100644 --- a/libvips/conversion/cast.c +++ b/libvips/conversion/cast.c @@ -565,10 +565,6 @@ vips_castv(VipsImage *in, VipsImage **out, VipsBandFormat format, va_list ap) * @format: format to convert to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @shift: %gboolean, integer values are shifted - * * Convert @in to @format. You can convert between any pair of formats. * Floats are truncated (not rounded). Out of range values are clipped. * @@ -579,8 +575,12 @@ vips_castv(VipsImage *in, VipsImage **out, VipsBandFormat format, va_list ap) * shift every value left by 8 bits. The bottom bit is copied into the new * bits, so 255 would become 65535. * - * See also: vips_scale(), vips_complexform(), vips_real(), vips_imag(), - * vips_cast_uchar(), vips_msb(). + * ::: tip "Optional arguments" + * * @shift: %gboolean, integer values are shifted + * + * ::: seealso + * [method@Image.scale], [method@Image.complexform], [method@Image.real], + * [method@Image.imag], [method@Image.cast_uchar], [method@Image.msb]. * * Returns: 0 on success, -1 on error */ @@ -603,11 +603,10 @@ vips_cast(VipsImage *in, VipsImage **out, VipsBandFormat format, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Convert @in to [enum@Vips.BandFormat.UCHAR]. See [method@Image.cast]. * - * * @shift: %gboolean, integer values are shifted - * - * Convert @in to #VIPS_FORMAT_UCHAR. See vips_cast(). + * ::: tip "Optional arguments" + * * @shift: %gboolean, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -630,11 +629,10 @@ vips_cast_uchar(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @shift: %gboolean, integer values are shifted + * Convert @in to [enum@Vips.BandFormat.CHAR]. See [method@Image.cast]. * - * Convert @in to #VIPS_FORMAT_CHAR. See vips_cast(). + * ::: tip "Optional arguments" + * * @shift: %gboolean, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -657,11 +655,10 @@ vips_cast_char(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Convert @in to [enum@Vips.BandFormat.USHORT]. See [method@Image.cast]. * - * * @shift: %gboolean, integer values are shifted - * - * Convert @in to #VIPS_FORMAT_USHORT. See vips_cast(). + * ::: tip "Optional arguments" + * * @shift: %gboolean, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -684,11 +681,10 @@ vips_cast_ushort(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @shift: %gboolean, integer values are shifted + * Convert @in to [enum@Vips.BandFormat.SHORT]. See [method@Image.cast]. * - * Convert @in to #VIPS_FORMAT_SHORT. See vips_cast(). + * ::: tip "Optional arguments" + * * @shift: %gboolean, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -711,11 +707,10 @@ vips_cast_short(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Convert @in to [enum@Vips.BandFormat.UINT]. See [method@Image.cast]. * - * * @shift: %gboolean, integer values are shifted - * - * Convert @in to #VIPS_FORMAT_UINT. See vips_cast(). + * ::: tip "Optional arguments" + * * @shift: %gboolean, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -738,11 +733,10 @@ vips_cast_uint(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @shift: %gboolean, integer values are shifted + * Convert @in to [enum@Vips.BandFormat.INT]. See [method@Image.cast]. * - * Convert @in to #VIPS_FORMAT_INT. See vips_cast(). + * ::: tip "Optional arguments" + * * @shift: %gboolean, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -765,7 +759,7 @@ vips_cast_int(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Convert @in to #VIPS_FORMAT_FLOAT. See vips_cast(). + * Convert @in to [enum@Vips.BandFormat.FLOAT]. See [method@Image.cast]. * * Returns: 0 on success, -1 on error */ @@ -788,7 +782,7 @@ vips_cast_float(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Convert @in to #VIPS_FORMAT_DOUBLE. See vips_cast(). + * Convert @in to [enum@Vips.BandFormat.DOUBLE]. See [method@Image.cast]. * * Returns: 0 on success, -1 on error */ @@ -811,7 +805,7 @@ vips_cast_double(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Convert @in to #VIPS_FORMAT_COMPLEX. See vips_cast(). + * Convert @in to [enum@Vips.BandFormat.COMPLEX]. See [method@Image.cast]. * * Returns: 0 on success, -1 on error */ @@ -834,7 +828,7 @@ vips_cast_complex(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Convert @in to #VIPS_FORMAT_DPCOMPLEX. See vips_cast(). + * Convert @in to [enum@Vips.BandFormat.DPCOMPLEX]. See [method@Image.cast]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/conversion.c b/libvips/conversion/conversion.c index 89cd2fc563..bffd426ae4 100644 --- a/libvips/conversion/conversion.c +++ b/libvips/conversion/conversion.c @@ -57,13 +57,6 @@ * @mode: array of (@n - 1) #VipsBlendMode * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @compositing_space: #VipsInterpretation to composite in - * * @premultiplied: %gboolean, images are already premultiplied - * * @x: #VipsArrayInt, array of (@n - 1) x coordinates - * * @y: #VipsArrayInt, array of (@n - 1) y coordinates - * * Composite an array of images together. * * Images are placed in a stack, with @in[0] at the bottom and @in[@n - 1] at @@ -72,15 +65,17 @@ * in @mode. * * Images are transformed to a compositing space before processing. This is - * #VIPS_INTERPRETATION_sRGB, #VIPS_INTERPRETATION_B_W, - * #VIPS_INTERPRETATION_RGB16, or #VIPS_INTERPRETATION_GREY16 + * [enum@Vips.Interpretation.sRGB], [enum@Vips.Interpretation.B_W], + * [enum@Vips.Interpretation.RGB16], or [enum@Vips.Interpretation.GREY16] * by default, depending on * how many bands and bits the input images have. You can select any other - * space, such as #VIPS_INTERPRETATION_LAB or #VIPS_INTERPRETATION_scRGB. + * space, such as [enum@Vips.Interpretation.LAB] or + * [enum@Vips.Interpretation.scRGB]. * * The output image is in the compositing space. It will always be - * #VIPS_FORMAT_FLOAT unless one of the inputs is #VIPS_FORMAT_DOUBLE, in - * which case the output will be double as well. + * [enum@Vips.BandFormat.FLOAT] unless one of the inputs is + * [enum@Vips.BandFormat.DOUBLE], in which case the output will be double + * as well. * * Complex images are not supported. * @@ -93,10 +88,17 @@ * against that rectangle. * * Image are normally treated as unpremultiplied, so this operation can be used - * directly on PNG images. If your images have been through vips_premultiply(), - * set @premultiplied. + * directly on PNG images. If your images have been through + * [method@Image.premultiply], set @premultiplied. * - * See also: vips_insert(). + * ::: tip "Optional arguments" + * * @compositing_space: [enum@Interpretation] to composite in + * * @premultiplied: %gboolean, images are already premultiplied + * * @x: [struct@ArrayInt], array of (@n - 1) x coordinates + * * @y: [struct@ArrayInt], array of (@n - 1) y coordinates + * + * ::: seealso + * [method@Image.insert]. * * Returns: 0 on success, -1 on error */ @@ -109,14 +111,13 @@ * @mode: composite with this blend mode * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @compositing_space: #VipsInterpretation to composite in - * * @premultiplied: %gboolean, images are already premultiplied - * * @x: %gint, position of overlay - * * @y: %gint, position of overlay + * Composite @overlay on top of @base with @mode. See [func@Image.composite]. * - * Composite @overlay on top of @base with @mode. See vips_composite(). + * ::: tip "Optional arguments" + * * @compositing_space: [enum@Interpretation] to composite in + * * @premultiplied: %gboolean, images are already premultiplied + * * @x: %gint, position of overlay + * * @y: %gint, position of overlay * * Returns: 0 on success, -1 on error */ @@ -149,7 +150,7 @@ * @VIPS_BLEND_MODE_DIFFERENCE: difference of the two * @VIPS_BLEND_MODE_EXCLUSION: somewhat like DIFFERENCE, but lower-contrast * - * The various Porter-Duff and PDF blend modes. See vips_composite(), + * The various Porter-Duff and PDF blend modes. See [func@Image.composite], * for example. * * The Cairo docs have a nice explanation of all the blend modes: @@ -165,12 +166,13 @@ * @VIPS_ALIGN_CENTRE: align centre * @VIPS_ALIGN_HIGH: align high coordinate edge * - * See vips_join() and so on. + * See [method@Image.join] and so on. * - * Operations like vips_join() need to be told whether to align images on the + * Operations like [method@Image.join] need to be told whether to align images on the * low or high coordinate edge, or centre. * - * See also: vips_join(). + * ::: seealso + * [method@Image.join]. */ /** @@ -180,11 +182,12 @@ * @VIPS_ANGLE_D180: 180 degree rotate * @VIPS_ANGLE_D270: 90 degrees anti-clockwise * - * See vips_rot() and so on. + * See [method@Image.rot] and so on. * * Fixed rotate angles. * - * See also: vips_rot(). + * ::: seealso + * [method@Image.rot]. */ /** @@ -198,14 +201,15 @@ * @VIPS_INTERESTING_ALL: everything is interesting * * Pick the algorithm vips uses to decide image "interestingness". This is used - * by vips_smartcrop(), for example, to decide what parts of the image to + * by [method@Image.smartcrop], for example, to decide what parts of the image to * keep. * * #VIPS_INTERESTING_NONE and #VIPS_INTERESTING_LOW mean the same -- the * crop is positioned at the top or left. #VIPS_INTERESTING_HIGH positions at * the bottom or right. * - * See also: vips_smartcrop(). + * ::: seealso + * [method@Image.smartcrop]. */ /** @@ -220,7 +224,7 @@ * @VIPS_COMPASS_DIRECTION_SOUTH_WEST: south-west * @VIPS_COMPASS_DIRECTION_NORTH_WEST: north-west * - * A direction on a compass. Used for vips_gravity(), for example. + * A direction on a compass. Used for [method@Image.gravity], for example. */ /** @@ -234,11 +238,12 @@ * @VIPS_ANGLE45_D270: 90 degrees anti-clockwise * @VIPS_ANGLE45_D315: 45 degrees anti-clockwise * - * See vips_rot45() and so on. + * See [method@Image.rot45] and so on. * * Fixed rotate angles. * - * See also: vips_rot45(). + * ::: seealso + * [method@Image.rot45]. */ /** @@ -250,7 +255,7 @@ * @VIPS_EXTEND_WHITE: extend with white (all bits set) pixels * @VIPS_EXTEND_BACKGROUND: extend with colour from the @background property * - * See vips_embed(), vips_conv(), vips_affine() and so on. + * See [method@Image.embed], [method@Image.conv], [method@Image.affine] and so on. * * When the edges of an image are extended, you can specify * how you want the extension done. @@ -272,7 +277,8 @@ * We have to specify the exact value of each enum member since we have to * keep these frozen for back compat with vips7. * - * See also: vips_embed(). + * ::: seealso + * [method@Image.embed]. */ /** @@ -280,12 +286,13 @@ * @VIPS_DIRECTION_HORIZONTAL: left-right * @VIPS_DIRECTION_VERTICAL: top-bottom * - * See vips_flip(), vips_join() and so on. + * See [method@Image.flip], [method@Image.join] and so on. * - * Operations like vips_flip() need to be told whether to flip left-right or + * Operations like [method@Image.flip] need to be told whether to flip left-right or * top-bottom. * - * See also: vips_flip(), vips_join(). + * ::: seealso + * [method@Image.flip], [method@Image.join]. */ G_DEFINE_ABSTRACT_TYPE(VipsConversion, vips_conversion, VIPS_TYPE_OPERATION); diff --git a/libvips/conversion/copy.c b/libvips/conversion/copy.c index 288cbeccca..40174bab57 100644 --- a/libvips/conversion/copy.c +++ b/libvips/conversion/copy.c @@ -364,19 +364,6 @@ vips_copy_init(VipsCopy *copy) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @width: %gint, set image width - * * @height: %gint, set image height - * * @bands: %gint, set image bands - * * @format: #VipsBandFormat, set image format - * * @coding: #VipsCoding, set image coding - * * @interpretation: #VipsInterpretation, set image interpretation - * * @xres: %gdouble, set image xres - * * @yres: %gdouble, set image yres - * * @xoffset: %gint, set image xoffset - * * @yoffset: %gint, set image yoffset - * * Copy an image, optionally modifying the header. VIPS copies images by * copying pointers, so this operation is instant, even for very large images. * @@ -385,7 +372,21 @@ vips_copy_init(VipsCopy *copy) * you can turn a 4-band uchar image into a 2-band ushort image, but you * cannot change a 100 x 100 RGB image into a 300 x 100 mono image. * - * See also: vips_byteswap(), vips_bandfold(), vips_bandunfold(). + * ::: tip "Optional arguments" + * * @width: %gint, set image width + * * @height: %gint, set image height + * * @bands: %gint, set image bands + * * @format: [enum@BandFormat], set image format + * * @coding: [enum@Coding], set image coding + * * @interpretation: [enum@Interpretation], set image interpretation + * * @xres: %gdouble, set image xres + * * @yres: %gdouble, set image yres + * * @xoffset: %gint, set image xoffset + * * @yoffset: %gint, set image yoffset + * + * ::: seealso + * [method@Image.byteswap], [method@Image.bandfold], + * [method@Image.bandunfold]. * * Returns: 0 on success, -1 on error. */ @@ -412,10 +413,11 @@ vips_copy(VipsImage *in, VipsImage **out, ...) * again to output. If the image is already a file, just copy straight * through. * - * The file is allocated with vips_image_new_temp_file(). + * The file is allocated with [ctor@Image.new_temp_file]. * The file is automatically deleted when @out is closed. * - * See also: vips_copy(), vips_image_new_temp_file(). + * ::: seealso + * [method@Image.copy], [ctor@Image.new_temp_file]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/embed.c b/libvips/conversion/embed.c index 9f10486b77..a33c6b08bb 100644 --- a/libvips/conversion/embed.c +++ b/libvips/conversion/embed.c @@ -682,18 +682,17 @@ vips_embed_init(VipsEmbed *embed) * @height: @out should be this many pixels down * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * The opposite of [method@Image.extract_area]: embed @in within an image of + * size @width by @height at position @x, @y. * - * * @extend: #VipsExtend to generate the edge pixels (default: black) - * * @background: #VipsArrayDouble colour for edge pixels + * @extend controls what appears in the new pels, see [enum@Extend]. * - * The opposite of vips_extract_area(): embed @in within an image of size - * @width by @height at position @x, @y. + * ::: tip "Optional arguments" + * * @extend: [enum@Extend] to generate the edge pixels (default: black) + * * @background: [struct@ArrayDouble] colour for edge pixels * - * @extend - * controls what appears in the new pels, see #VipsExtend. - * - * See also: vips_extract_area(), vips_insert(). + * ::: seealso + * [method@Image.extract_area], [method@Image.insert]. * * Returns: 0 on success, -1 on error. */ @@ -830,18 +829,17 @@ vips_gravity_init(VipsGravity *gravity) * @height: @out should be this many pixels down * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @extend: #VipsExtend to generate the edge pixels (default: black) - * * @background: #VipsArrayDouble colour for edge pixels + * The opposite of [method@Image.extract_area]: place @in within an image of + * size @width by @height at a certain gravity. * - * The opposite of vips_extract_area(): place @in within an image of size - * @width by @height at a certain gravity. + * @extend controls what appears in the new pels, see #VipsExtend. * - * @extend - * controls what appears in the new pels, see #VipsExtend. + * ::: tip "Optional arguments" + * * @extend: #VipsExtend to generate the edge pixels (default: black) + * * @background: [struct@ArrayDouble] colour for edge pixels * - * See also: vips_extract_area(), vips_insert(). + * ::: seealso + * [method@Image.extract_area], [method@Image.insert]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/extract.c b/libvips/conversion/extract.c index fe7dedad40..407c831bb7 100644 --- a/libvips/conversion/extract.c +++ b/libvips/conversion/extract.c @@ -250,7 +250,8 @@ vips_extract_area_init(VipsExtractArea *extract) * * Extract an area from an image. The area must fit within @in. * - * See also: vips_extract_bands(), vips_smartcrop(). + * ::: seealso + * [method@Image.extract_band], [method@Image.smartcrop]. * * Returns: 0 on success, -1 on error. */ @@ -306,9 +307,10 @@ vips_crop_get_type(void) * @height: height of area to extract * @...: %NULL-terminated list of optional named arguments * - * A synonym for vips_extract_area(). + * A synonym for [method@Image.extract_area]. * - * See also: vips_extract_bands(), vips_smartcrop(). + * ::: seealso + * [method@Image.extract_band], [method@Image.smartcrop]. * * Returns: 0 on success, -1 on error. */ @@ -462,15 +464,15 @@ vips_extract_band_init(VipsExtractBand *extract) * @band: index of first band to extract * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @n: number of bands to extract - * * Extract a band or bands from an image. Extracting out of range is an error. * * @n defaults to 1. * - * See also: vips_extract_area(). + * ::: tip "Optional arguments" + * * @n: %gint, number of bands to extract + * + * ::: seealso + * [method@Image.extract_area]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/falsecolour.c b/libvips/conversion/falsecolour.c index e25286e121..0e9f62b2f6 100644 --- a/libvips/conversion/falsecolour.c +++ b/libvips/conversion/falsecolour.c @@ -399,7 +399,8 @@ vips_falsecolour_init(VipsFalsecolour *falsecolour) * map. The map is supposed to make small differences in brightness more * obvious. * - * See also: vips_maplut(). + * ::: seealso + * [method@Image.maplut]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/flatten.c b/libvips/conversion/flatten.c index 88d7351e46..1efbb59fb5 100644 --- a/libvips/conversion/flatten.c +++ b/libvips/conversion/flatten.c @@ -6,7 +6,7 @@ * 4/1/14 * - better rounding * 9/5/15 - * - add max_alpha to match vips_premultiply() etc. + * - add max_alpha to match [method@Image.premultiply] etc. * 25/5/16 * - max_alpha defaults to 65535 for RGB16/GREY16 * 12/9/21 @@ -449,11 +449,6 @@ vips_flatten_init(VipsFlatten *flatten) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @background: #VipsArrayDouble colour for new pixels - * * @max_alpha: %gdouble, maximum value for alpha - * * Take the last band of @in as an alpha and use it to blend the * remaining channels with @background. * @@ -461,14 +456,18 @@ vips_flatten_init(VipsFlatten *flatten) * and 0 means 100% background. @background defaults to zero (black). * * @max_alpha has the default value 255, or 65535 for images tagged as - * #VIPS_INTERPRETATION_RGB16 or - * #VIPS_INTERPRETATION_GREY16. + * [enum@Vips.Interpretation.RGB16] or [enum@Vips.Interpretation.GREY16]. * * Useful for flattening PNG images to RGB. * * Non-complex images only. * - * See also: vips_premultiply(), vips_pngload(). + * ::: tip "Optional arguments" + * * @background: [struct@ArrayDouble] colour for new pixels + * * @max_alpha: %gdouble, maximum value for alpha + * + * ::: seealso + * [method@Image.premultiply], [ctor@Image.pngload]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/flip.c b/libvips/conversion/flip.c index 0f56a12fa0..152b07af26 100644 --- a/libvips/conversion/flip.c +++ b/libvips/conversion/flip.c @@ -264,7 +264,8 @@ vips_flip_init(VipsFlip *flip) * * Flips an image left-right or up-down. * - * See also: vips_rot(). + * ::: seealso + * [method@Image.rot]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/gamma.c b/libvips/conversion/gamma.c index e709c54ac3..3eddea1ea8 100644 --- a/libvips/conversion/gamma.c +++ b/libvips/conversion/gamma.c @@ -164,14 +164,14 @@ vips_gamma_init(VipsGamma *gamma) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @exponent: gamma, default 1.0 / 2.4 - * * Calculate @in ** (1 / @exponent), normalising to the maximum range of the * input type. For float types use 1.0 as the maximum. * - * See also: vips_identity(), vips_pow_const1(), vips_maplut() + * ::: tip "Optional arguments" + * * @exponent: %gdouble, gamma, default 1.0 / 2.4 + * + * ::: seealso + * [ctor@Image.identity], [method@Image.pow_const1], [method@Image.maplut] * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/grid.c b/libvips/conversion/grid.c index 83d67bbee7..75c02d8b27 100644 --- a/libvips/conversion/grid.c +++ b/libvips/conversion/grid.c @@ -252,7 +252,8 @@ vips_grid_init(VipsGrid *grid) * only really need two of these. Requiring three is a double-check that the * image has the expected geometry. * - * See also: vips_embed(), vips_insert(), vips_join(). + * ::: seealso + * [method@Image.embed], [method@Image.insert], [method@Image.join]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/ifthenelse.c b/libvips/conversion/ifthenelse.c index 1b952dfcd2..a6de3e81d9 100644 --- a/libvips/conversion/ifthenelse.c +++ b/libvips/conversion/ifthenelse.c @@ -558,16 +558,12 @@ vips_ifthenelse_init(VipsIfthenelse *ifthenelse) /** * vips_ifthenelse: (method) - * @cond: condition #VipsImage - * @in1: then #VipsImage - * @in2: else #VipsImage - * @out: (out): output #VipsImage + * @cond: condition [class@Image] + * @in1: then [class@Image] + * @in2: else [class@Image] + * @out: (out): output [class@Image] * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @blend: blend smoothly between @in1 and @in2 - * * This operation scans the condition image @cond * and uses it to select pixels from either the then image @in1 or the else * image @in2. Non-zero means @in1, 0 means @in2. @@ -585,9 +581,15 @@ vips_ifthenelse_init(VipsIfthenelse *ifthenelse) * If @blend is %TRUE, then values in @out are smoothly blended between @in1 * and @in2 using the formula: * - * @out = (@cond / 255) * @in1 + (1 - @cond / 255) * @in2 + * ``` + * out = (cond / 255) * in1 + (1 - cond / 255) * in2 + * ``` + * + * ::: tip "Optional arguments" + * * @blend: %gboolean, blend smoothly between @in1 and @in2 * - * See also: vips_equal(). + * ::: seealso + * [method@Image.equal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/insert.c b/libvips/conversion/insert.c index ccfec3de3d..85b442dd67 100644 --- a/libvips/conversion/insert.c +++ b/libvips/conversion/insert.c @@ -520,11 +520,6 @@ vips_insert_init(VipsInsert *insert) * @y: top position of @sub * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @expand: expand output to hold whole of both images - * * @background: colour for new pixels - * * Insert @sub into @main at position @x, @y. * * Normally @out shows the whole of @main. If @expand is #TRUE then @out is @@ -544,7 +539,12 @@ vips_insert_init(VipsInsert *insert) * Smallest common format in * arithmetic). * - * See also: vips_join(), vips_embed(), vips_extract_area(). + * ::: tip "Optional arguments" + * * @expand: %gdouble, expand output to hold whole of both images + * * @background: [struct@ArrayDouble], colour for new pixels + * + * ::: seealso + * [method@Image.join], [method@Image.embed], [method@Image.extract_area]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/join.c b/libvips/conversion/join.c index 5a505827ea..a9ae970b13 100644 --- a/libvips/conversion/join.c +++ b/libvips/conversion/join.c @@ -284,8 +284,6 @@ vips_join_class_init(VipsJoinClass *class) static void vips_join_init(VipsJoin *join) { - /* Init our instance fields. - */ join->background = vips_array_double_newv(1, 0.0); } @@ -297,13 +295,6 @@ vips_join_init(VipsJoin *join) * @direction: join horizontally or vertically * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @expand: %TRUE to expand the output image to hold all of the input pixels - * * @shim: space between images, in pixels - * * @background: background ink colour - * * @align: low, centre or high alignment - * * Join @in1 and @in2 together, left-right or up-down depending on the value * of @direction. * @@ -329,9 +320,17 @@ vips_join_init(VipsJoin *join) * arithmetic). * * If you are going to be joining many thousands of images in a regular - * grid, vips_arrayjoin() is a better choice. + * grid, [func@Image.arrayjoin] is a better choice. + * + * ::: tip "Optional arguments" + * * @expand: %gboolean, %TRUE to expand the output image to hold all of + * the input pixels + * * @shim: %gint, space between images, in pixels + * * @background: [struct@ArrayDouble], background ink colour + * * @align: [enumAlign], low, centre or high alignment * - * See also: vips_arrayjoin(), vips_insert(). + * ::: seealso + * [func@Image.arrayjoin], [method@Image.insert]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/msb.c b/libvips/conversion/msb.c index 87046600ff..fe89700177 100644 --- a/libvips/conversion/msb.c +++ b/libvips/conversion/msb.c @@ -269,10 +269,6 @@ vips_msb_init(VipsMsb *msb) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @band: %gint, msb just this band - * * Turn any integer image to 8-bit unsigned char by discarding all but the most * significant byte. Signed values are converted to unsigned by adding 128. * @@ -280,7 +276,11 @@ vips_msb_init(VipsMsb *msb) * * This operator also works for LABQ coding. * - * See also: vips_scale(), vips_cast(). + * ::: tip "Optional arguments" + * * @band: %gint, msb just this band + * + * ::: seealso + * [method@Image.scale], [method@Image.cast]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/premultiply.c b/libvips/conversion/premultiply.c index 812043f749..cafb8c2b10 100644 --- a/libvips/conversion/premultiply.c +++ b/libvips/conversion/premultiply.c @@ -283,19 +283,15 @@ vips_premultiply_init(VipsPremultiply *premultiply) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @max_alpha: %gdouble, maximum value for alpha - * * Premultiplies any alpha channel. - * The final band is taken to be the alpha - * and the bands are transformed as: * - * |[ - * alpha = clip(0, in[in.bands - 1], @max_alpha); - * norm = alpha / @max_alpha; - * out = [in[0] * norm, ..., in[in.bands - 1] * norm, alpha]; - * ]| + * The final band is taken to be the alpha and the bands are transformed as: + * + * ``` + * alpha = clip(0, in[in.bands - 1], max_alpha) + * norm = alpha / max_alpha + * out = [in[0] * norm, ..., in[in.bands - 1] * norm, alpha] + * ``` * * So for an N-band image, the first N - 1 bands are multiplied by the clipped * and normalised final band, the final band is clipped. @@ -303,16 +299,20 @@ vips_premultiply_init(VipsPremultiply *premultiply) * the image is passed through unaltered. * * The result is - * #VIPS_FORMAT_FLOAT unless the input format is #VIPS_FORMAT_DOUBLE, in which - * case the output is double as well. + * [enum@Vips.BandFormat.FLOAT] unless the input format is + * [enum@Vips.BandFormat.DOUBLE], in which case the output is double as well. * * @max_alpha has the default value 255, or 65535 for images tagged as - * #VIPS_INTERPRETATION_RGB16 or - * #VIPS_INTERPRETATION_GREY16. + * [enum@Vips.Interpretation.RGB16] or [enum@Vips.Interpretation.GREY16], and + * 1.0 for images tagged as [enum@Vips.Interpretation.scRGB]. * * Non-complex images only. * - * See also: vips_unpremultiply(), vips_flatten(). + * ::: tip "Optional arguments" + * * @max_alpha: %gdouble, maximum value for alpha + * + * ::: seealso + * [method@Image.unpremultiply], [method@Image.flatten]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/recomb.c b/libvips/conversion/recomb.c index 8bf50558e7..e0d4f9efdf 100644 --- a/libvips/conversion/recomb.c +++ b/libvips/conversion/recomb.c @@ -254,7 +254,8 @@ vips_recomb_init(VipsRecomb *recomb) * * It's useful for various sorts of colour space conversions. * - * See also: vips_bandmean(). + * ::: seealso + * [method@Image.bandmean]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/replicate.c b/libvips/conversion/replicate.c index 5f33b3fb7f..5a0c8727e6 100644 --- a/libvips/conversion/replicate.c +++ b/libvips/conversion/replicate.c @@ -228,7 +228,8 @@ vips_replicate_init(VipsReplicate *replicate) * * Repeats an image many times. * - * See also: vips_extract_area(). + * ::: seealso + * [method@Image.extract_area]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/rot.c b/libvips/conversion/rot.c index 938287ef95..310e26157c 100644 --- a/libvips/conversion/rot.c +++ b/libvips/conversion/rot.c @@ -395,10 +395,11 @@ vips_rotv(VipsImage *in, VipsImage **out, VipsAngle angle, va_list ap) * * Rotate @in by a multiple of 90 degrees. * - * Use vips_similarity() to rotate by an arbitrary angle. vips_rot45() is - * useful for rotating convolution masks by 45 degrees. + * Use [method@Image.similarity] to rotate by an arbitrary angle. + * [method@Image.rot45] is useful for rotating convolution masks by 45 degrees. * - * See also: vips_flip(), vips_similarity(), vips_rot45(). + * ::: seealso + * [method@Image.flip], [method@Image.similarity], [method@Image.rot45]. * * Returns: 0 on success, -1 on error */ @@ -421,9 +422,10 @@ vips_rot(VipsImage *in, VipsImage **out, VipsAngle angle, ...) * @out: output image * @...: %NULL-terminated list of optional named arguments * - * Rotate @in by 90 degrees clockwise. A convenience function over vips_rot(). + * Rotate @in by 90 degrees clockwise. A convenience function over [method@Image.rot]. * - * See also: vips_rot(). + * ::: seealso + * [method@Image.rot]. * * Returns: 0 on success, -1 on error */ @@ -446,9 +448,10 @@ vips_rot90(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Rotate @in by 180 degrees. A convenience function over vips_rot(). + * Rotate @in by 180 degrees. A convenience function over [method@Image.rot]. * - * See also: vips_rot(). + * ::: seealso + * [method@Image.rot]. * * Returns: 0 on success, -1 on error */ @@ -471,9 +474,10 @@ vips_rot180(VipsImage *in, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Rotate @in by 270 degrees clockwise. A convenience function over vips_rot(). + * Rotate @in by 270 degrees clockwise. A convenience function over [method@Image.rot]. * - * See also: vips_rot(). + * ::: seealso + * [method@Image.rot]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/rot45.c b/libvips/conversion/rot45.c index 440930b36c..8c712d869d 100644 --- a/libvips/conversion/rot45.c +++ b/libvips/conversion/rot45.c @@ -290,17 +290,17 @@ vips_rot45_init(VipsRot45 *rot45) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @angle: #VipsAngle45 rotation angle - * * Rotate @in by a multiple of 45 degrees. Odd-length sides and square images * only. * * This operation is useful for rotating convolution masks. Use - * vips_similarity() to rotate images by arbitrary angles. + * [method@Image.similarity] to rotate images by arbitrary angles. + * + * ::: tip "Optional arguments" + * * @angle: [enum@Angle45], rotation angle * - * See also: vips_rot(), vips_similarity(). + * ::: seealso + * [method@Image.rot], [method@Image.similarity]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/scale.c b/libvips/conversion/scale.c index 4a51fe0e82..7a2c5f7e33 100644 --- a/libvips/conversion/scale.c +++ b/libvips/conversion/scale.c @@ -184,11 +184,6 @@ vips_scale_init(VipsScale *scale) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @log: log scale pixels - * * @exp: exponent for log scale - * * Search the image for the maximum and minimum value, then return the image * as unsigned 8-bit, scaled so that the maximum value is 255 and the * minimum is zero. @@ -196,7 +191,12 @@ vips_scale_init(VipsScale *scale) * If @log is set, transform with log10(1.0 + pow(x, @exp)) + .5, * then scale so max == 255. By default, @exp is 0.25. * - * See also: vips_cast(). + * ::: tip "Optional arguments" + * * @log: %gboolean, log scale pixels + * * @exp: %gdouble, exponent for log scale + * + * ::: seealso + * [method@Image.cast]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/sequential.c b/libvips/conversion/sequential.c index da114e449a..5e2ea258a8 100644 --- a/libvips/conversion/sequential.c +++ b/libvips/conversion/sequential.c @@ -282,19 +282,19 @@ vips_sequential_init(VipsSequential *sequential) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @tile_height: height of cache strips - * - * This operation behaves rather like vips_copy() between images + * This operation behaves rather like [method@Image.copy] between images * @in and @out, except that it checks that pixels on @in are only requested * top-to-bottom. This operation is useful for loading file formats which are * strictly top-to-bottom, like PNG. * * @tile_height can be used to set the size of the tiles that - * vips_sequential() uses. The default value is 1. + * [method@Image.sequential] uses. The default value is 1. + * + * ::: tip "Optional arguments" + * * @tile_height: %gint, height of cache strips * - * See also: vips_cache(), vips_linecache(), vips_tilecache(). + * ::: seealso + * [method@Image.linecache], [method@Image.tilecache]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/smartcrop.c b/libvips/conversion/smartcrop.c index 1874d1e070..40a5b59b80 100644 --- a/libvips/conversion/smartcrop.c +++ b/libvips/conversion/smartcrop.c @@ -493,13 +493,6 @@ vips_smartcrop_init(VipsSmartcrop *smartcrop) * @height: height of area to extract * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @interesting: #VipsInteresting to use to find interesting areas (default: #VIPS_INTERESTING_ATTENTION) - * * @premultiplied: %gboolean, input image already has premultiplied alpha - * * @attention_x: %gint, horizontal position of attention centre when using attention based cropping - * * @attention_y: %gint, vertical position of attention centre when using attention based cropping - * * Crop an image down to a specified width and height by removing boring parts. * * Use @interesting to pick the method vips uses to decide which bits of the @@ -508,7 +501,17 @@ vips_smartcrop_init(VipsSmartcrop *smartcrop) * You can test xoffset / yoffset on @out to find the location of the crop * within the input image. * - * See also: vips_extract_area(). + * ::: tip "Optional arguments" + * * @interesting: [enum@Interesting] to use to find interesting areas + * (default: [enum@Vips.Interesting.ATTENTION]) + * * @premultiplied: %gboolean, input image already has premultiplied alpha + * * @attention_x: %gint, horizontal position of attention centre when + * using attention based cropping (output) + * * @attention_y: %gint, vertical position of attention centre when + * using attention based cropping (output) + * + * ::: seealso + * [method@Image.extract_area]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/subsample.c b/libvips/conversion/subsample.c index 461d261fb2..521e88f3ab 100644 --- a/libvips/conversion/subsample.c +++ b/libvips/conversion/subsample.c @@ -14,7 +14,7 @@ * 2/11/13 * - add @point to force point sample mode * 22/1/16 - * - remove SEQUENTIAL hint, it confuses vips_sequential() + * - remove SEQUENTIAL hint, it confuses [method@Image.sequential] */ /* @@ -260,7 +260,7 @@ vips_subsample_class_init(VipsSubsampleClass *class) vobject_class->build = vips_subsample_build; /* We don't work well as sequential: we can easily skip the first few - * scanlines, and that confuses vips_sequential(). + * scanlines, and that confuses [method@Image.sequential]. */ VIPS_ARG_IMAGE(class, "input", 1, @@ -304,10 +304,6 @@ vips_subsample_init(VipsSubsample *subsample) * @yfac: vertical shrink factor * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @point: turn on point sample mode - * * Subsample an image by an integer fraction. This is fast, nearest-neighbour * shrink. * @@ -318,7 +314,11 @@ vips_subsample_init(VipsSubsample *subsample) * If @point is set, @in will always be sampled in points. This can be faster * if the previous operations in the pipeline are very slow. * - * See also: vips_affine(), vips_shrink(), vips_zoom(). + * ::: tip "Optional arguments" + * * @point: %gboolean, turn on point sample mode + * + * ::: seealso + * [method@Image.affine], [method@Image.shrink], [method@Image.zoom]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/switch.c b/libvips/conversion/switch.c index 1e2bc31e24..0b47864660 100644 --- a/libvips/conversion/switch.c +++ b/libvips/conversion/switch.c @@ -238,9 +238,10 @@ vips_switchv(VipsImage **tests, VipsImage **out, int n, va_list ap) * bounding box of the set of images in @tests, and that size is used for * @out. @tests can have up to 255 elements. * - * Combine with vips_case() to make an efficient multi-way vips_ifthenelse(). + * Combine with [method@Image.case] to make an efficient multi-way [method@Image.ifthenelse]. * - * See also: vips_maplut(), vips_case(), vips_ifthenelse(). + * ::: seealso + * [method@Image.maplut], [method@Image.case], [method@Image.ifthenelse]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/tilecache.c b/libvips/conversion/tilecache.c index ba308050fb..9bba127eef 100644 --- a/libvips/conversion/tilecache.c +++ b/libvips/conversion/tilecache.c @@ -822,40 +822,41 @@ vips_tile_cache_init(VipsTileCache *cache) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: * - * * @tile_width: width of tiles in cache - * * @tile_height: height of tiles in cache - * * @max_tiles: maximum number of tiles to cache - * * @access: hint expected access pattern #VipsAccess - * * @threaded: allow many threads - * * @persistent: don't drop cache at end of computation - * - * This operation behaves rather like vips_copy() between images + * This operation behaves rather like [method@Image.copy] between images * @in and @out, except that it keeps a cache of computed pixels. * This cache is made of up to @max_tiles tiles (a value of -1 * means any number of tiles), and each tile is of size @tile_width * by @tile_height pixels. * * Each cache tile is made with a single call to - * vips_region_prepare(). + * [method@Region.prepare]. * * When the cache fills, a tile is chosen for reuse. If @access is - * #VIPS_ACCESS_RANDOM, then the least-recently-used tile is reused. If - * @access is #VIPS_ACCESS_SEQUENTIAL + * [enum@Vips.Access.RANDOM], then the least-recently-used tile is reused. If + * @access is [enum@Vips.Access.SEQUENTIAL] * the top-most tile is reused. * * By default, @tile_width and @tile_height are 128 pixels, and the operation - * will cache up to 1,000 tiles. @access defaults to #VIPS_ACCESS_RANDOM. + * will cache up to 1,000 tiles. @access defaults to [enum@Vips.Access.RANDOM]. * * Normally, only a single thread at once is allowed to calculate tiles. If - * you set @threaded to %TRUE, vips_tilecache() will allow many threads to - * calculate tiles at once, and share the cache between them. + * you set @threaded to %TRUE, [method@Image.tilecache] will allow many + * threads to calculate tiles at once, and share the cache between them. * * Normally the cache is dropped when computation finishes. Set @persistent to * %TRUE to keep the cache between computations. * - * See also: vips_cache(), vips_linecache(). + * ::: tip "Optional arguments" + * * @tile_width: %gint, width of tiles in cache + * * @tile_height: %gint, height of tiles in cache + * * @max_tiles: %gint, maximum number of tiles to cache + * * @access: [enum@Access], hint expected access pattern + * * @threaded: %gboolean, allow many threads + * * @persistent: %gboolean, don't drop cache at end of computation + * + * ::: seealso + * [method@Image.linecache]. * * Returns: 0 on success, -1 on error. */ @@ -995,34 +996,33 @@ vips_line_cache_init(VipsLineCache *cache) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @access: hint expected access pattern #VipsAccess - * * @tile_height: height of tiles in cache - * * @threaded: allow many threads - * - * This operation behaves rather like vips_copy() between images + * This operation behaves rather like [method@Image.copy] between images * @in and @out, except that it keeps a cache of computed scanlines. * * The number of lines cached is enough for a small amount of non-local * access. * - * Each cache tile is made with a single call to - * vips_region_prepare(). + * Each cache tile is made with a single call to [method@Region.prepare]. * * When the cache fills, a tile is chosen for reuse. If @access is - * #VIPS_ACCESS_RANDOM, then the least-recently-used tile is reused. If - * @access is #VIPS_ACCESS_SEQUENTIAL, then - * the top-most tile is reused. @access defaults to #VIPS_ACCESS_RANDOM. + * [enum@Vips.Access.RANDOM], then the least-recently-used tile is reused. If + * @access is [enum@Vips.Access.SEQUENTIAL], then + * the top-most tile is reused. @access defaults to [enum@Vips.Access.RANDOM]. * * @tile_height can be used to set the size of the strips that - * vips_linecache() uses. The default is 1 (a single scanline). + * [method@Image.linecache] uses. The default is 1 (a single scanline). * * Normally, only a single thread at once is allowed to calculate tiles. If - * you set @threaded to %TRUE, vips_linecache() will allow many threads to - * calculate tiles at once and share the cache between them. + * you set @threaded to %TRUE, [method@Image.linecache] will allow many + * threads to calculate tiles at once and share the cache between them. + * + * ::: tip "Optional arguments" + * * @access: [enum@Access], hint expected access pattern + * * @tile_height: %gint, height of tiles in cache + * * @threaded: %gboolean, allow many threads * - * See also: vips_cache(), vips_tilecache(). + * ::: seealso + * [method@Image.tilecache]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/conversion/transpose3d.c b/libvips/conversion/transpose3d.c index 64c1da70b4..37d26d1de0 100644 --- a/libvips/conversion/transpose3d.c +++ b/libvips/conversion/transpose3d.c @@ -188,10 +188,6 @@ vips_transpose3d_init(VipsTranspose3d *transpose3d) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page_height: %gint, size of each input page - * * Transpose a volumetric image. * * Volumetric images are very tall, thin images, with the metadata item @@ -206,7 +202,11 @@ vips_transpose3d_init(VipsTranspose3d *transpose3d) * #VIPS_META_PAGE_HEIGHT in the output image is the number of pages in the * input image. * - * See also: vips_grid(). + * ::: tip "Optional arguments" + * * @page_height: %gint, size of each input page + * + * ::: seealso + * [method@Image.grid]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/unpremultiply.c b/libvips/conversion/unpremultiply.c index d6f6659668..ba5aa6ec90 100644 --- a/libvips/conversion/unpremultiply.c +++ b/libvips/conversion/unpremultiply.c @@ -352,39 +352,39 @@ vips_unpremultiply_init(VipsUnpremultiply *unpremultiply) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @max_alpha: %gdouble, maximum value for alpha - * * @alpha_band: %gint, band containing alpha data - * * Unpremultiplies any alpha channel. + * * Band @alpha_band (by default the final band) contains the alpha and all * other bands are transformed as: * - * |[ - * alpha = (int) clip(0, in[in.bands - 1], @max_alpha); - * norm = (double) alpha / @max_alpha; + * ``` + * alpha = (int) clip(0, in[in.bands - 1], max_alpha); + * norm = (double) alpha / max_alpha * if (alpha == 0) - * out = [0, ..., 0, alpha]; + * out = [0, ..., 0, alpha] * else - * out = [in[0] / norm, ..., in[in.bands - 1] / norm, alpha]; - * ]| + * out = [in[0] / norm, ..., in[in.bands - 1] / norm, alpha] + * ``` * * So for an N-band image, the first N - 1 bands are divided by the clipped * and normalised final band, the final band is clipped. * If there is only a single band, the image is passed through unaltered. * - * The result is - * #VIPS_FORMAT_FLOAT unless the input format is #VIPS_FORMAT_DOUBLE, in which - * case the output is double as well. + * The result is [enum@Vips.BandFormat.FLOAT] unless the input format is + * [enum@Vips.BandFormat.DOUBLE], in which case the output is double as well. * * @max_alpha has the default value 255, or 65535 for images tagged as - * #VIPS_INTERPRETATION_RGB16 or - * #VIPS_INTERPRETATION_GREY16. + * [enum@Vips.Interpretation.RGB16] or [enum@Vips.Interpretation.GREY16], and + * 1.0 for images tagged as [enum@Vips.Interpretation.scRGB. * * Non-complex images only. * - * See also: vips_premultiply(), vips_flatten(). + * ::: tip "Optional arguments" + * * @max_alpha: %gdouble, maximum value for alpha + * * @alpha_band: %gint, band containing alpha data + * + * ::: seealso + * [method@Image.premultiply], [method@Image.flatten]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/wrap.c b/libvips/conversion/wrap.c index 2a81a41d85..a965b12b9c 100644 --- a/libvips/conversion/wrap.c +++ b/libvips/conversion/wrap.c @@ -147,16 +147,17 @@ vips_wrap_init(VipsWrap *wrap) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Slice an image up and move the segments about so that the pixel that was + * at 0, 0 is now at @x, @y. * - * * @x: horizontal displacement - * * @y: vertical displacement + * If @x and @y are not set, they default to the centre of the image. * - * Slice an image up and move the segments about so that the pixel that was - * at 0, 0 is now at @x, @y. If @x and @y are not set, they default to the - * centre of the image. + * ::: tip "Optional arguments" + * * @x: horizontal displacement + * * @y: vertical displacement * - * See also: vips_embed(), vips_replicate(). + * ::: seealso + * [method@Image.embed], [method@Image.replicate]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/zoom.c b/libvips/conversion/zoom.c index b1c99c748e..c20bcaac1c 100644 --- a/libvips/conversion/zoom.c +++ b/libvips/conversion/zoom.c @@ -406,7 +406,8 @@ vips_zoom_init(VipsZoom *zoom) * Zoom an image by repeating pixels. This is fast nearest-neighbour * zoom. * - * See also: vips_affine(), vips_subsample(). + * ::: seealso + * [method@Image.affine], [method@Image.subsample]. * * Returns: 0 on success, -1 on error. */ From d53b8a7268397cda00b4cf818d558219c843688b Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 18 Apr 2025 14:20:15 +0200 Subject: [PATCH 130/174] doc: minor gi-docgen improvements (#4473) * doc: unify `seealso` admonitions with other files * doc: use spaces instead of tabs * doc: port hyperlinks to Markdown * doc: port tables to Markdown * doc: port emphasis to Markdown * doc: port functions and types to gi-docgen linking syntax --- libvips/arithmetic/abs.c | 2 +- libvips/arithmetic/add.c | 69 +++++++------------------------ libvips/arithmetic/boolean.c | 2 +- libvips/arithmetic/divide.c | 69 +++++++------------------------ libvips/arithmetic/linear.c | 2 +- libvips/arithmetic/math2.c | 2 +- libvips/arithmetic/multiply.c | 69 +++++++------------------------ libvips/arithmetic/relational.c | 2 +- libvips/arithmetic/remainder.c | 2 +- libvips/arithmetic/subtract.c | 69 +++++++------------------------ libvips/arithmetic/sum.c | 69 +++++++------------------------ libvips/colour/Lab2XYZ.c | 2 +- libvips/colour/XYZ2Lab.c | 2 +- libvips/colour/colourspace.c | 2 +- libvips/colour/icc_transform.c | 57 ++++++++++++------------- libvips/conversion/arrayjoin.c | 2 +- libvips/conversion/bandfold.c | 2 +- libvips/conversion/bandjoin.c | 2 +- libvips/conversion/insert.c | 2 +- libvips/conversion/join.c | 2 +- libvips/create/buildlut.c | 51 ++++++----------------- libvips/create/invertlut.c | 32 +++----------- libvips/deprecated/im_lab_morph.c | 57 ++++++------------------- libvips/deprecated/vips7compat.c | 2 +- libvips/foreign/csvload.c | 4 +- libvips/histogram/hist_plot.c | 8 ++-- libvips/iofuncs/buf.c | 6 +-- libvips/iofuncs/dbuf.c | 2 +- libvips/iofuncs/header.c | 44 ++++++++++---------- libvips/iofuncs/image.c | 2 +- libvips/mosaicing/merge.c | 2 +- libvips/mosaicing/mosaic1.c | 2 +- 32 files changed, 184 insertions(+), 458 deletions(-) diff --git a/libvips/arithmetic/abs.c b/libvips/arithmetic/abs.c index 5a80869291..9801f64b0d 100644 --- a/libvips/arithmetic/abs.c +++ b/libvips/arithmetic/abs.c @@ -218,7 +218,7 @@ vips_abs_init(VipsAbs *abs) * * This operation finds the absolute value of an image. It does a copy for * unsigned integer types, negate for negative values in - * signed integer types, fabs(3) for + * signed integer types, [`fabs()`](man:fabs(3)) for * float types, and calculates modulus for complex * types. * diff --git a/libvips/arithmetic/add.c b/libvips/arithmetic/add.c index 514cfc7f8e..c638b2847a 100644 --- a/libvips/arithmetic/add.c +++ b/libvips/arithmetic/add.c @@ -206,62 +206,23 @@ vips_add_init(VipsAdd *add) * * The two input images are cast up to the smallest common format (see table * Smallest common format in - * arithmetic), then the + * [arithmetic](libvips-arithmetic.html)), then the * following table is used to determine the output type: * - *
- * Codestin Search App - * - * - * - * input type - * output type - * - * - * - * - * uchar - * ushort - * - * - * char - * short - * - * - * ushort - * uint - * - * - * short - * int - * - * - * uint - * uint - * - * - * int - * int - * - * - * float - * float - * - * - * double - * double - * - * - * complex - * complex - * - * - * double complex - * double complex - * - * - * - *
+ * ## [method@Image.add] type promotion + * + * | input type | output type | + * |----------------|----------------| + * | uchar | ushort | + * | char | short | + * | ushort | uint | + * | short | int | + * | uint | uint | + * | int | int | + * | float | float | + * | double | double | + * | complex | complex | + * | double complex | double complex | * * In other words, the output type is just large enough to hold the whole * range of possible values. diff --git a/libvips/arithmetic/boolean.c b/libvips/arithmetic/boolean.c index 6c97790b62..1eb9d27b0a 100644 --- a/libvips/arithmetic/boolean.c +++ b/libvips/arithmetic/boolean.c @@ -318,7 +318,7 @@ vips_booleanv(VipsImage *left, VipsImage *right, VipsImage **out, * * The two input images are cast up to the smallest common format (see table * Smallest common format in - * arithmetic). + * [arithmetic](libvips-arithmetic.html)). * * ::: seealso * [method@Image.boolean_const]. diff --git a/libvips/arithmetic/divide.c b/libvips/arithmetic/divide.c index 89b73bbb4f..7644b90b6a 100644 --- a/libvips/arithmetic/divide.c +++ b/libvips/arithmetic/divide.c @@ -239,62 +239,23 @@ vips_divide_init(VipsDivide *divide) * * The two input images are cast up to the smallest common format (see table * Smallest common format in - * arithmetic), then the + * [arithmetic](libvips-arithmetic.html)), then the * following table is used to determine the output type: * - * - * Codestin Search App - * - * - * - * input type - * output type - * - * - * - * - * uchar - * float - * - * - * char - * float - * - * - * ushort - * float - * - * - * short - * float - * - * - * uint - * float - * - * - * int - * float - * - * - * float - * float - * - * - * double - * double - * - * - * complex - * complex - * - * - * double complex - * double complex - * - * - * - *
+ * ## [method@Image.divide] type promotion + * + * | input type | output type | + * |----------------|----------------| + * | uchar | float | + * | char | float | + * | ushort | float | + * | short | float | + * | uint | float | + * | int | float | + * | float | float | + * | double | double | + * | complex | complex | + * | double complex | double complex | * * In other words, the output type is just large enough to hold the whole * range of possible values. diff --git a/libvips/arithmetic/linear.c b/libvips/arithmetic/linear.c index 060a3eb6ab..6b2861fe7f 100644 --- a/libvips/arithmetic/linear.c +++ b/libvips/arithmetic/linear.c @@ -550,7 +550,7 @@ vips_linear(VipsImage *in, VipsImage **out, * Run [method@Image.linear] with a single constant. * * ::: tip "Optional arguments" - * * @uchar: output uchar pixels + * * @uchar: output uchar pixels * * ::: seealso * [method@Image.linear]. diff --git a/libvips/arithmetic/math2.c b/libvips/arithmetic/math2.c index 5aade17a97..96c3eae484 100644 --- a/libvips/arithmetic/math2.c +++ b/libvips/arithmetic/math2.c @@ -283,7 +283,7 @@ vips_math2v(VipsImage *left, VipsImage *right, VipsImage **out, * * The two input images are cast up to the smallest common format (see table * Smallest common format in - * arithmetic), and that format is the + * [arithmetic](libvips-arithmetic.html)), and that format is the * result type. * * ::: seealso diff --git a/libvips/arithmetic/multiply.c b/libvips/arithmetic/multiply.c index 5a296661e0..8656847d09 100644 --- a/libvips/arithmetic/multiply.c +++ b/libvips/arithmetic/multiply.c @@ -223,62 +223,23 @@ vips_multiply_init(VipsMultiply *multiply) * * The two input images are cast up to the smallest common format (see table * Smallest common format in - * arithmetic), then the + * [arithmetic](libvips-arithmetic.html)), then the * following table is used to determine the output type: * - * - * Codestin Search App - * - * - * - * input type - * output type - * - * - * - * - * uchar - * ushort - * - * - * char - * short - * - * - * ushort - * uint - * - * - * short - * int - * - * - * uint - * uint - * - * - * int - * int - * - * - * float - * float - * - * - * double - * double - * - * - * complex - * complex - * - * - * double complex - * double complex - * - * - * - *
+ * ## [method@Image.multiply] type promotion + * + * | input type | output type | + * |----------------|----------------| + * | uchar | ushort | + * | char | short | + * | ushort | uint | + * | short | int | + * | uint | uint | + * | int | int | + * | float | float | + * | double | double | + * | complex | complex | + * | double complex | double complex | * * In other words, the output type is just large enough to hold the whole * range of possible values. diff --git a/libvips/arithmetic/relational.c b/libvips/arithmetic/relational.c index ac2eb46e91..a04481b684 100644 --- a/libvips/arithmetic/relational.c +++ b/libvips/arithmetic/relational.c @@ -288,7 +288,7 @@ vips_relationalv(VipsImage *left, VipsImage *right, VipsImage **out, * * The two input images are cast up to the smallest common format (see table * Smallest common format in - * arithmetic). + * [arithmetic](libvips-arithmetic.html)). * * To decide if pixels match exactly, that is have the same value in every * band, use [method@Image.bandbool] after this operation to AND or OR image bands diff --git a/libvips/arithmetic/remainder.c b/libvips/arithmetic/remainder.c index 3eed597b19..28a59fb164 100644 --- a/libvips/arithmetic/remainder.c +++ b/libvips/arithmetic/remainder.c @@ -225,7 +225,7 @@ vips_remainder_init(VipsRemainder *remainder) * * The two input images are cast up to the smallest common format (see table * Smallest common format in - * arithmetic), and that format is the + * [arithmetic](libvips-arithmetic.html)), and that format is the * result type. * * ::: seealso diff --git a/libvips/arithmetic/subtract.c b/libvips/arithmetic/subtract.c index 20456d4941..7f797f807a 100644 --- a/libvips/arithmetic/subtract.c +++ b/libvips/arithmetic/subtract.c @@ -202,62 +202,23 @@ vips_subtract_init(VipsSubtract *subtract) * * The two input images are cast up to the smallest common format (see table * Smallest common format in - * arithmetic), then the + * [arithmetic](libvips-arithmetic.html)), then the * following table is used to determine the output type: * - * - * Codestin Search App - * - * - * - * input type - * output type - * - * - * - * - * uchar - * short - * - * - * char - * short - * - * - * ushort - * int - * - * - * short - * int - * - * - * uint - * int - * - * - * int - * int - * - * - * float - * float - * - * - * double - * double - * - * - * complex - * complex - * - * - * double complex - * double complex - * - * - * - *
+ * ## [method@Image.subtract] type promotion + * + * | input type | output type | + * |----------------|----------------| + * | uchar | short | + * | char | short | + * | ushort | int | + * | short | int | + * | uint | int | + * | int | int | + * | float | float | + * | double | double | + * | complex | complex | + * | double complex | double complex | * * In other words, the output type is just large enough to hold the whole * range of possible values. diff --git a/libvips/arithmetic/sum.c b/libvips/arithmetic/sum.c index be772af81a..d568c69fbc 100644 --- a/libvips/arithmetic/sum.c +++ b/libvips/arithmetic/sum.c @@ -190,62 +190,23 @@ vips_sumv(VipsImage **in, VipsImage **out, int n, va_list ap) * * The input images are cast up to the smallest common format (see table * Smallest common format in - * arithmetic), then the + * [arithmetic](libvips-arithmetic.html)), then the * following table is used to determine the output type: * - * - * Codestin Search App - * - * - * - * input type - * output type - * - * - * - * - * uchar - * uint - * - * - * char - * int - * - * - * ushort - * uint - * - * - * short - * int - * - * - * uint - * uint - * - * - * int - * int - * - * - * float - * float - * - * - * double - * double - * - * - * complex - * complex - * - * - * double complex - * double complex - * - * - * - *
+ * ## [func@Image.sum] type promotion + * + * | input type | output type | + * |----------------|----------------| + * | uchar | uint | + * | char | int | + * | ushort | uint | + * | short | int | + * | uint | uint | + * | int | int | + * | float | float | + * | double | double | + * | complex | complex | + * | double complex | double complex | * * In other words, the output type is just large enough to hold the whole * range of possible values. diff --git a/libvips/colour/Lab2XYZ.c b/libvips/colour/Lab2XYZ.c index 87495900b3..973fc94812 100644 --- a/libvips/colour/Lab2XYZ.c +++ b/libvips/colour/Lab2XYZ.c @@ -209,7 +209,7 @@ vips_Lab2XYZ_init(VipsLab2XYZ *Lab2XYZ) * specified with @temp. * * ::: tip "Optional arguments" - * * @temp: [struct@ArrayDouble], colour temperature + * * @temp: [struct@ArrayDouble], colour temperature * * Returns: 0 on success, -1 on error */ diff --git a/libvips/colour/XYZ2Lab.c b/libvips/colour/XYZ2Lab.c index 7014632099..9f86425da3 100644 --- a/libvips/colour/XYZ2Lab.c +++ b/libvips/colour/XYZ2Lab.c @@ -263,7 +263,7 @@ vips_XYZ2Lab_init(VipsXYZ2Lab *XYZ2Lab) * defaults to D65. * * ::: tip "Optional arguments" - * * @temp: [struct@ArrayDouble], colour temperature + * * @temp: [struct@ArrayDouble], colour temperature * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/colourspace.c b/libvips/colour/colourspace.c index ca80fccb5b..4c6c3589ec 100644 --- a/libvips/colour/colourspace.c +++ b/libvips/colour/colourspace.c @@ -603,7 +603,7 @@ vips_colourspace_init(VipsColourspace *colourspace) * and [method@Image.XYZ2Lab]. * * ::: tip "Optional arguments" - * * @source_space: input colour space + * * @source_space: input colour space * * ::: seealso * [method@Image.colourspace_issupported], diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 470a1ce50f..65243f754e 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -693,11 +693,12 @@ vips_icc_verify_blob(VipsIcc *icc, VipsBlob **blob) /* Try to set the import profile. We read the input profile like this: * - * embedded filename action - * 0 0 image - * 1 0 image - * 0 1 file - * 1 1 image, then fall back to file + * | embedded | filename | action | + * |----------|----------|-------------------------------| + * | 0 | 0 | image | + * | 1 | 0 | image | + * | 0 | 1 | file | + * | 1 | 1 | image, then fall back to file | * * If averything fails, we fall back to one of our built-in profiles, * depending on the input image. @@ -1446,27 +1447,27 @@ vips_icc_is_compatible_profile(VipsImage *image, * * The input profile is searched for in three places: * - * 1. If @embedded is set, libvips will try to use any profile in the input - * image metadata. You can test for the presence of an embedded profile - * with [method@Image.get_typeof] with #VIPS_META_ICC_NAME as an - * argument. This will return %GType 0 if there is no profile. + * 1. If @embedded is set, libvips will try to use any profile in the input + * image metadata. You can test for the presence of an embedded profile + * with [method@Image.get_typeof] with #VIPS_META_ICC_NAME as an + * argument. This will return %GType 0 if there is no profile. * - * 2. Otherwise, if @input_profile is set, libvips will try to load a - * profile from the named file. This can also be the name of one of the - * built-in profiles. + * 2. Otherwise, if @input_profile is set, libvips will try to load a + * profile from the named file. This can also be the name of one of the + * built-in profiles. * - * 3. Otherwise, libvips will try to pick a compatible profile from the set - * of built-in profiles. + * 3. Otherwise, libvips will try to pick a compatible profile from the set + * of built-in profiles. * * If @black_point_compensation is set, LCMS black point compensation is * enabled. * * ::: tip "Optional arguments" - * * @pcs: [enum@PCS], use XYZ or LAB PCS - * * @intent: [enum@Intent], transform with this intent - * * @black_point_compensation: %gboolean, enable black point compensation - * * @embedded: %gboolean, use profile embedded in input image - * * @input_profile: %gchararray, get the input profile from here + * * @pcs: [enum@PCS], use XYZ or LAB PCS + * * @intent: [enum@Intent], transform with this intent + * * @black_point_compensation: %gboolean, enable black point compensation + * * @embedded: %gboolean, use profile embedded in input image + * * @input_profile: %gchararray, get the input profile from here * * Returns: 0 on success, -1 on error. */ @@ -1535,17 +1536,17 @@ vips_icc_export(VipsImage *in, VipsImage **out, ...) * * The input profile is searched for in three places: * - * 1. If @embedded is set, libvips will try to use any profile in the input - * image metadata. You can test for the presence of an embedded profile - * with [method@Image.get_typeof] with #VIPS_META_ICC_NAME as an - * argument. This will return %GType 0 if there is no profile. + * 1. If @embedded is set, libvips will try to use any profile in the input + * image metadata. You can test for the presence of an embedded profile + * with [method@Image.get_typeof] with #VIPS_META_ICC_NAME as an + * argument. This will return %GType 0 if there is no profile. * - * 2. Otherwise, if @input_profile is set, libvips will try to load a - * profile from the named file. This can also be the name of one of the - * built-in profiles. + * 2. Otherwise, if @input_profile is set, libvips will try to load a + * profile from the named file. This can also be the name of one of the + * built-in profiles. * - * 3. Otherwise, libvips will try to pick a compatible profile from the set - * of built-in profiles. + * 3. Otherwise, libvips will try to pick a compatible profile from the set + * of built-in profiles. * * If @black_point_compensation is set, LCMS black point compensation is * enabled. diff --git a/libvips/conversion/arrayjoin.c b/libvips/conversion/arrayjoin.c index 97f8fc3af7..e6139b8836 100644 --- a/libvips/conversion/arrayjoin.c +++ b/libvips/conversion/arrayjoin.c @@ -499,7 +499,7 @@ vips_arrayjoinv(VipsImage **in, VipsImage **out, int n, va_list ap) * * The input images are cast up to the smallest common type (see table * Smallest common format in - * arithmetic). + * [arithmetic](libvips-arithmetic.html)). * * [method@Image.colourspace] can be useful for moving the images to a common * colourspace for compositing. diff --git a/libvips/conversion/bandfold.c b/libvips/conversion/bandfold.c index e1d3e0287b..7de838af8e 100644 --- a/libvips/conversion/bandfold.c +++ b/libvips/conversion/bandfold.c @@ -191,7 +191,7 @@ vips_bandfold_init(VipsBandfold *bandfold) * as many bands. By default the whole of the input width is folded up. * * ::: tip "Optional arguments" - * * @factor: %gint, fold by this factor + * * @factor: %gint, fold by this factor * * ::: seealso * [ctor@Image.csvload], [method@Image.bandunfold]. diff --git a/libvips/conversion/bandjoin.c b/libvips/conversion/bandjoin.c index 1ba4270fa2..eee8f97b67 100644 --- a/libvips/conversion/bandjoin.c +++ b/libvips/conversion/bandjoin.c @@ -244,7 +244,7 @@ vips_bandjoinv(VipsImage **in, VipsImage **out, int n, va_list ap) * * The input images are cast up to the smallest common type (see table * Smallest common format in - * arithmetic). + * [arithmetic](libvips-arithmetic.html)). * * ::: seealso * [method@Image.insert]. diff --git a/libvips/conversion/insert.c b/libvips/conversion/insert.c index 85b442dd67..3ef12cdfac 100644 --- a/libvips/conversion/insert.c +++ b/libvips/conversion/insert.c @@ -537,7 +537,7 @@ vips_insert_init(VipsInsert *insert) * * The two input images are cast up to the smallest common type (see table * Smallest common format in - * arithmetic). + * [arithmetic](libvips-arithmetic.html)). * * ::: tip "Optional arguments" * * @expand: %gdouble, expand output to hold whole of both images diff --git a/libvips/conversion/join.c b/libvips/conversion/join.c index a9ae970b13..148b5aa980 100644 --- a/libvips/conversion/join.c +++ b/libvips/conversion/join.c @@ -317,7 +317,7 @@ vips_join_init(VipsJoin *join) * * The two input images are cast up to the smallest common type (see table * Smallest common format in - * arithmetic). + * [arithmetic](libvips-arithmetic.html)). * * If you are going to be joining many thousands of images in a regular * grid, [func@Image.arrayjoin] is a better choice. diff --git a/libvips/create/buildlut.c b/libvips/create/buildlut.c index 8056a2817a..efaaefc37e 100644 --- a/libvips/create/buildlut.c +++ b/libvips/create/buildlut.c @@ -284,48 +284,21 @@ vips_buildlut_init(VipsBuildlut *lut) * * For example, consider this 2 x 2 matrix of (x, y) coordinates: * - * - * - * - * 0 - * 0 - * - * - * 255 - * 100 - * - * - * + * ``` + * 2 2 + * 0 0 + * 255 100 + * ``` * * We then generate a 1 x 256 element LUT like this: * - * - * - * - * Index - * Value - * - * - * - * - * 0 - * 0 - * - * - * 1 - * 0.4 - * - * - * etc. - * 0.4 - * - * - * 255 - * 100 - * - * - * - * + * | Index | Value | + * |-------|-------| + * | 0 | 0 | + * | 1 | 0.4 | + * | etc. | 0.4 | + * | 255 | 100 | + * This is then written as the output image, with the left column giving the * index in the image to place the value. * diff --git a/libvips/create/invertlut.c b/libvips/create/invertlut.c index 02a89baa4c..507fc634f5 100644 --- a/libvips/create/invertlut.c +++ b/libvips/create/invertlut.c @@ -321,32 +321,12 @@ vips_invertlut_init(VipsInvertlut *lut) * * Eg. input like this: * - * - * - * - * 4 - * 3 - * - * - * 0.1 - * 0.2 - * 0.3 - * 0.1 - * - * - * 0.2 - * 0.4 - * 0.4 - * 0.2 - * - * - * 0.7 - * 0.5 - * 0.6 - * 0.3 - * - * - * + * ``` + * 4 3 + * 0.1 0.2 0.3 0.1 + * 0.2 0.4 0.4 0.2 + * 0.7 0.5 0.6 0.3 + * ``` * * Means a patch with 10% reflectance produces an image with 20% in * channel 1, 30% in channel 2, and 10% in channel 3, and so on. diff --git a/libvips/deprecated/im_lab_morph.c b/libvips/deprecated/im_lab_morph.c index 987c9918d6..daa469f6d2 100644 --- a/libvips/deprecated/im_lab_morph.c +++ b/libvips/deprecated/im_lab_morph.c @@ -208,42 +208,18 @@ morph_buffer(float *in, float *out, int width, Params *parm) * * We perform three adjustments: * - * - * - * - * cast + * ## Cast * * Pass in @mask containing CIELAB readings for a neutral greyscale. For * example: * - * - * - * - * 3 - * 4 - * - * - * 14.23 - * 4.8 - * -3.95 - * - * - * 18.74 - * 2.76 - * -2.62 - * - * - * 23.46 - * 1.4 - * -1.95 - * - * - * 27.53 - * 1.76 - * -2.01 - * - * - * + * ``` + * 3 4 + * 14.23 4.8 -3.95 + * 18.74 2.76 -2.62 + * 23.46 1.4 -1.95 + * 27.53 1.76 -2.01 + * ``` * * Interpolation from this makes cast corrector. The top and tail are * interpolated towards [0, 0, 0] and [100, 0, 0], intermediate values are @@ -252,23 +228,14 @@ morph_buffer(float *in, float *out, int width, Params *parm) * * Each pixel is displaced in a/b by the amount specified for that L in the * table. - * - * - * - * - * L* + * + * ## L* * * Pass in scale and offset for L. L' = (L + offset) * scale. - * - * - * - * - * saturation + * + * ## Saturation * * scale a and b by these amounts, eg. 1.5 increases saturation. - * - * - * * * Find the top two by generating and printing a greyscale. Find the bottom * by printing a Macbeth and looking at a/b spread diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index e9c6a7212b..067f39fa89 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -5707,7 +5707,7 @@ im__insert_base(const char *domain, * * The two input images are cast up to the smallest common type (see table * Smallest common format in - * arithmetic). + * [arithmetic](libvips-arithmetic.html)). * * See also: im_insert(), im_lrjoin(). * diff --git a/libvips/foreign/csvload.c b/libvips/foreign/csvload.c index 1615ad225c..6193ea3841 100644 --- a/libvips/foreign/csvload.c +++ b/libvips/foreign/csvload.c @@ -700,11 +700,11 @@ vips_foreign_load_csv_source_init(VipsForeignLoadCsvSource *source) * meaning read all lines to end of file. * * @whitespace sets the skippable whitespace characters. - * Default space. + * Default *space*. * Whitespace characters are always run together. * * @separator sets the characters that separate fields. - * Default ;,tab. Separators are never run together. + * Default ;,*tab*. Separators are never run together. * * Use @fail_on to set the type of error that will cause load to fail. By * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. diff --git a/libvips/histogram/hist_plot.c b/libvips/histogram/hist_plot.c index 1e63c03482..e6243f0856 100644 --- a/libvips/histogram/hist_plot.c +++ b/libvips/histogram/hist_plot.c @@ -356,14 +356,14 @@ vips_hist_plot_init(VipsHistPlot *hist_plot) * Plot a 1 by any or any by 1 image file as a max by any or * any by max image using these rules: * - * unsigned char max is always 256 + * *unsigned char* max is always 256 * - * other unsigned integer types output 0 - maximum + * *other unsigned integer types* output 0 - maximum * value of @in. * - * signed int types min moved to 0, max moved to max + min. + * *signed int types* min moved to 0, max moved to max + min. * - * float types min moved to 0, max moved to any + * *float types* min moved to 0, max moved to any * (square output) * * Returns: 0 on success, -1 on error diff --git a/libvips/iofuncs/buf.c b/libvips/iofuncs/buf.c index bd2f8a60ba..e45684c3bb 100644 --- a/libvips/iofuncs/buf.c +++ b/libvips/iofuncs/buf.c @@ -397,10 +397,10 @@ vips_buf_removec(VipsBuf *buf, char ch) /** * vips_buf_vappendf: * @buf: the buffer - * @fmt: printf()-style format string + * @fmt: `printf()`-style format string * @ap: arguments to format string * - * Append to @buf, args as vprintf(). + * Append to @buf, args as [`vprintf()`](man:vprintf(3)). * * Returns: %FALSE on overflow, %TRUE otherwise. */ @@ -434,7 +434,7 @@ vips_buf_vappendf(VipsBuf *buf, const char *fmt, va_list ap) /** * vips_buf_appendf: * @buf: the buffer - * @fmt: printf()-style format string + * @fmt: `printf()`-style format string * @...: arguments to format string * * Format the string and append to @buf. diff --git a/libvips/iofuncs/dbuf.c b/libvips/iofuncs/dbuf.c index 635c82c201..6d3d3556e7 100644 --- a/libvips/iofuncs/dbuf.c +++ b/libvips/iofuncs/dbuf.c @@ -183,7 +183,7 @@ vips_dbuf_write(VipsDbuf *dbuf, const unsigned char *data, size_t size) /** * vips_dbuf_writef: * @dbuf: the buffer - * @fmt: printf()-style format string + * @fmt: `printf()`-style format string * @...: arguments to format string * * Format the string and write to @dbuf. diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 9ccaf40641..0ffae26993 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -1011,7 +1011,7 @@ vips_image_get_orientation_swap(VipsImage *image) * images which you are sure have not been shared with another thread. * * ::: seealso - * [method@Image.wio_input] or [method@Image.copy_memory]. + * [method@Image.wio_input], [method@Image.copy_memory]. * * Returns: (nullable) (transfer none): a pointer to pixel data, if possible. */ @@ -1286,7 +1286,7 @@ vips_set_value_from_pointer(GValue *value, void *data) * ``` * * ::: seealso - * [method@Image.get_typeof] or [method@Image.get_double]. + * [method@Image.get_typeof], [method@Image.get_double]. * * Returns: (skip): 0 on success, -1 otherwise. */ @@ -1394,7 +1394,7 @@ vips_image_get_typeof(const VipsImage *image, const char *name) * name was found. * * ::: seealso - * [method@Image.set] or [method@Image.get_typeof]. + * [method@Image.set], [method@Image.get_typeof]. * * Returns: `TRUE` if an item of metadata of that name was found and removed */ @@ -1458,7 +1458,7 @@ vips_image_map_fn(VipsMeta *meta, VipsImageMapFn fn, void *a) * iteration, or a non-`NULL` pointer to indicate early termination. * * ::: seealso - * [method@Image.get_typeof] or [method@Image.get]. + * [method@Image.get_typeof], [method@Image.get]. * * Returns: (nullable) (transfer none): `NULL` on success, the failing * pointer otherwise. @@ -1550,7 +1550,7 @@ vips_image_get_fields(VipsImage *image) * VIPS no longer needs the metadata, it will be freed with @free_fn. * * ::: seealso - * [method@Image.get_double] or [method@Image.set]. + * [method@Image.get_double], [method@Image.set]. */ void vips_image_set_area(VipsImage *image, const char *name, @@ -1598,7 +1598,7 @@ meta_get_value(const VipsImage *image, * test for the existence of a piece of metadata. * * ::: seealso - * [method@Image.set_area], [method@Image.get] or + * [method@Image.set_area], [method@Image.get], * [method@Image.get_typeof]. * * Returns: 0 on success, -1 otherwise. @@ -1630,7 +1630,7 @@ vips_image_get_area(const VipsImage *image, * Attaches @data as a metadata item on @image under the name @name. * * ::: seealso - * [method@Image.get_blob] or [method@Image.set]. + * [method@Image.get_blob], [method@Image.set]. */ void vips_image_set_blob(VipsImage *image, const char *name, @@ -1655,7 +1655,7 @@ vips_image_set_blob(VipsImage *image, const char *name, * a copy of the memory area. * * ::: seealso - * [method@Image.get_blob] or [method@Image.set]. + * [method@Image.get_blob], [method@Image.set]. */ void vips_image_set_blob_copy(VipsImage *image, @@ -1696,7 +1696,7 @@ vips_image_set_blob_copy(VipsImage *image, * of a piece of metadata. * * ::: seealso - * [method@Image.get], [method@Image.get_typeof] or + * [method@Image.get], [method@Image.get_typeof], * [method@Blob.get]. * * Returns: 0 on success, -1 otherwise. @@ -1726,7 +1726,7 @@ vips_image_get_blob(const VipsImage *image, const char *name, * The value will be transformed into an int, if possible. * * ::: seealso - * [method@Image.get] or [method@Image.get_typeof]. + * [method@Image.get], [method@Image.get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1753,7 +1753,7 @@ vips_image_get_int(const VipsImage *image, const char *name, int *out) * convenience function over [method@Image.set]. * * ::: seealso - * [method@Image.get_int] or [method@Image.set]. + * [method@Image.get_int], [method@Image.set]. */ void vips_image_set_int(VipsImage *image, const char *name, int i) @@ -1776,7 +1776,7 @@ vips_image_set_int(VipsImage *image, const char *name, int i) * The value will be transformed into a double, if possible. * * ::: seealso - * [method@Image.get] or [method@Image.get_typeof]. + * [method@Image.get], [method@Image.get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1803,7 +1803,7 @@ vips_image_get_double(const VipsImage *image, const char *name, double *out) * convenience function over [method@Image.set]. * * ::: seealso - * [method@Image.get_double] or [method@Image.set]. + * [method@Image.get_double], [method@Image.set]. */ void vips_image_set_double(VipsImage *image, const char *name, double d) @@ -1830,7 +1830,7 @@ vips_image_set_double(VipsImage *image, const char *name, double d) * Use [method@Image.get_as_string] to fetch any field as a string. * * ::: seealso - * [method@Image.get] or [method@Image.get_typeof]. + * [method@Image.get], [method@Image.get_typeof]. * * Returns: 0 on success, -1 otherwise. */ @@ -1878,7 +1878,7 @@ vips_image_get_string(const VipsImage *image, const char *name, * function over [method@Image.set] using `VIPS_TYPE_REF_STRING`. * * ::: seealso - * [method@Image.get_double] or [method@Image.set]. + * [method@Image.get_double], [method@Image.set]. */ void vips_image_set_string(VipsImage *image, const char *name, const char *str) @@ -1905,7 +1905,7 @@ vips_image_set_string(VipsImage *image, const char *name, const char *str) * make a string that's for humans. * * ::: seealso - * [method@Image.get], [method@Image.get_typeof] or + * [method@Image.get], [method@Image.get_typeof], * [method@Buf.appendg]. * * Returns: 0 on success, -1 otherwise. @@ -1977,7 +1977,7 @@ vips_image_print_field(const VipsImage *image, const char *name) * existence of a piece of metadata. * * ::: seealso - * [method@Image.get] or [method@Image.set_image] + * [method@Image.get], [method@Image.set_image] * * Returns: 0 on success, -1 otherwise. */ @@ -2005,7 +2005,7 @@ vips_image_get_image(const VipsImage *image, * A convenience function over [method@Image.set]. * * ::: seealso - * [method@Image.get_image] or [method@Image.set]. + * [method@Image.get_image], [method@Image.set]. */ void vips_image_set_image(VipsImage *image, const char *name, VipsImage *im) @@ -2034,7 +2034,7 @@ vips_image_set_image(VipsImage *image, const char *name, VipsImage *im) * existence of a piece of metadata. * * ::: seealso - * [method@Image.get] or [method@Image.set_image] + * [method@Image.get], [method@Image.set_image] * * Returns: 0 on success, -1 otherwise. */ @@ -2063,7 +2063,7 @@ vips_image_get_array_int(VipsImage *image, const char *name, * A convenience function over [method@Image.set]. * * ::: seealso - * [method@Image.get_image] or [method@Image.set]. + * [method@Image.get_image], [method@Image.set]. */ void vips_image_set_array_int(VipsImage *image, const char *name, @@ -2093,7 +2093,7 @@ vips_image_set_array_int(VipsImage *image, const char *name, * existence of a piece of metadata. * * ::: seealso - * [method@Image.get] or [method@Image.set_image] + * [method@Image.get], [method@Image.set_image] * * Returns: 0 on success, -1 otherwise. */ @@ -2122,7 +2122,7 @@ vips_image_get_array_double(VipsImage *image, const char *name, * A convenience function over [method@Image.set]. * * ::: seealso - * [method@Image.get_image] or [method@Image.set]. + * [method@Image.get_image], [method@Image.set]. */ void vips_image_set_array_double(VipsImage *image, const char *name, diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 10098640d6..a0d4b1cff8 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -247,7 +247,7 @@ * The format used for each band element. * * Each corresponds to a native C type for the current machine. For example, - * [enum@Vips.BandFormat.USHORT] is unsigned short. + * [enum@Vips.BandFormat.USHORT] is `unsigned short`. */ /** diff --git a/libvips/mosaicing/merge.c b/libvips/mosaicing/merge.c index 5d0cd43a71..dbbba076c2 100644 --- a/libvips/mosaicing/merge.c +++ b/libvips/mosaicing/merge.c @@ -195,7 +195,7 @@ vips_merge_init(VipsMerge *merge) * * The two input images are cast up to the smallest common type (see table * Smallest common format in - * arithmetic). + * [arithmetic](libvips-arithmetic.html)). * * @dx and @dy give the displacement of @sec relative to @ref, in other words, * the vector to get from the origin of @sec to the origin of @ref, in other diff --git a/libvips/mosaicing/mosaic1.c b/libvips/mosaicing/mosaic1.c index 357ee65da5..a0871c4c5b 100644 --- a/libvips/mosaicing/mosaic1.c +++ b/libvips/mosaicing/mosaic1.c @@ -673,7 +673,7 @@ vips_mosaic1_init(VipsMosaic1 *mosaic1) * * The two input images are cast up to the smallest common type (see table * Smallest common format in - * arithmetic). + * [arithmetic](libvips-arithmetic.html)). * * See also: vips_merge(), vips_insert(), vips_globalbalance(). * From e8cdbe3d50880b679b04ca3a83eb6cee744a277a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 18 Apr 2025 13:32:10 +0100 Subject: [PATCH 131/174] revise docs in convolution --- doc/rename.sed | 26 ++-------------- libvips/arithmetic/relational.c | 7 +++-- libvips/convolution/canny.c | 8 ++--- libvips/convolution/compass.c | 22 ++++++------- libvips/convolution/conv.c | 51 +++++++++++++++---------------- libvips/convolution/conva.c | 18 +++++------ libvips/convolution/convasep.c | 14 ++++----- libvips/convolution/convf.c | 9 +++--- libvips/convolution/convi.c | 11 ++++--- libvips/convolution/convolution.c | 2 +- libvips/convolution/convsep.c | 16 +++++----- libvips/convolution/edge.c | 12 ++++++-- libvips/convolution/fastcor.c | 3 +- libvips/convolution/gaussblur.c | 14 +++++---- libvips/convolution/sharpen.c | 30 +++++++++--------- libvips/convolution/spcor.c | 3 +- 16 files changed, 118 insertions(+), 128 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index b33181aae3..1d802c0024 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -121,7 +121,6 @@ s/vips_\(cos\)()/[method@Image.\1]/g s/vips_\(countlines\)()/[method@Image.\1]/g s/vips_\(crop\)()/[method@Image.\1]/g s/vips_\(cross_phase\)()/[method@Image.\1]/g -s/vips_\(csvload\)()/[ctor@Image.\1]/g s/vips_\(csvsave\)()/[method@Image.\1]/g s/vips_\(csvsave_target\)()/[method@Image.\1]/g s/vips_\(dE00\)()/[method@Image.\1]/g @@ -200,7 +199,6 @@ s/vips_\(HSV2sRGB\)()/[method@Image.\1]/g s/vips_\(icc_export\)()/[method@Image.\1]/g s/vips_\(icc_import\)()/[method@Image.\1]/g s/vips_\(icc_transform\)()/[method@Image.\1]/g -s/vips_\(identity\)()/[ctor@Image.\1]/g s/vips_\(ifthenelse\)()/[method@Image.\1]/g s/vips_image_\(get_typeof\)()/[method@Image.\1]/g s/vips_\(imag\)()/[method@Image.\1]/g @@ -212,7 +210,6 @@ s/vips_\(join\)()/[method@Image.\1]/g s/vips_\(jp2ksave_buffer\)()/[method@Image.\1]/g s/vips_\(jp2ksave\)()/[method@Image.\1]/g s/vips_\(jp2ksave_target\)()/[method@Image.\1]/g -s/vips_\(jpegload\)()/[ctor@Image.\1]/g s/vips_\(jpegsave_buffer\)()/[method@Image.\1]/g s/vips_\(jpegsave\)()/[method@Image.\1]/g s/vips_\(jpegsave_mime\)()/[method@Image.\1]/g @@ -288,13 +285,10 @@ s/vips_\(orimage_const\)()/[method@Image.\1]/g s/vips_\(orimage\)()/[method@Image.\1]/g s/vips_\(percent\)()/[method@Image.\1]/g s/vips_\(phasecor\)()/[method@Image.\1]/g -s/vips_\(pngload\)()/[ctor@Image.\1]/g s/vips_\(pngsave_buffer\)()/[method@Image.\1]/g s/vips_\(pngsave\)()/[method@Image.\1]/g s/vips_\(pngsave_target\)()/[method@Image.\1]/g s/vips_\(polar\)()/[method@Image.\1]/g -s/vips_\(pow_const1\)()/[method@Image.\1]/g -s/vips_\(pow_const\)()/[method@Image.\1]/g s/vips_\(pow\)()/[method@Image.\1]/g s/vips_\(ppmsave\)()/[method@Image.\1]/g s/vips_\(ppmsave_target\)()/[method@Image.\1]/g @@ -308,7 +302,6 @@ s/vips_\(radsave_buffer\)()/[method@Image.\1]/g s/vips_\(radsave\)()/[method@Image.\1]/g s/vips_\(radsave_target\)()/[method@Image.\1]/g s/vips_\(rank\)()/[method@Image.\1]/g -s/vips_\(rawload\)()/[ctor@Image.\1]/g s/vips_\(rawsave_buffer\)()/[method@Image.\1]/g s/vips_\(rawsave_fd\)()/[method@Image.\1]/g s/vips_\(rawsave\)()/[method@Image.\1]/g @@ -388,29 +381,15 @@ s/vips_\(XYZ2Yxy\)()/[method@Image.\1]/g s/vips_\(Yxy2XYZ\)()/[method@Image.\1]/g s/vips_\(zoom\)()/[method@Image.\1]/g -s/vips_\(arrayjoin\)()/[func@Image.\1]/g -s/vips_\(bandjoin\)()/[func@Image.\1]/g -s/vips_\(bandrank\)()/[func@Image.\1]/g -s/vips_\(composite\)()/[func@Image.\1]/g -s/vips_\(sum\)()/[func@Image.\1]/g -s/vips_\(switch\)()/[func@Image.\1]/g - s/vips_\([^(]*\)()/[func@\1]/g -s/#Vips\(Extend\)/[enum@\1]/g -s/#Vips\(Angle45\)/[enum@\1]/g -s/#Vips\(Interesting\)/[enum@\1]/g s/#Vips\(Access\)/[enum@\1]/g -s/#Vips\(Align\)/[enum@\1]/g -s/#Vips\(Angle\)/[enum@\1]/g -s/#Vips\(ArgumentFlags\)/[flags@\1]/g s/#Vips\(BandFormat\)/[enum@\1]/g +s/#Vips\(Interpretation\)/[enum@\1]/g s/#Vips\(Coding\)/[enum@\1]/g s/#Vips\(DemandStyle\)/[enum@\1]/g -s/#Vips\(Intent\)/[enum@\1]/g -s/#Vips\(Interpretation\)/[enum@\1]/g -s/#Vips\(PCS\)/[enum@\1]/g s/#Vips\(Precision\)/[enum@\1]/g +s/#Vips\(ArgumentFlags\)/[flags@\1]/g s/#Vips\(Rect\)/[struct@\1]/g s/#Vips\(Progress\)/[struct@\1]/g @@ -441,7 +420,6 @@ s/#Vips\(ThreadpoolWorkFn\)/[callback@\1]/g s/#Vips\(ThreadpoolProgressFn\)/[callback@\1]/g s/#VIPS_OPERATION_MATH_\([^ ,.]*\)/[enum@Vips.OperationMath.\1]/g -s/#VIPS_PCS_\([^ ,.]*\)/[enum@Vips.PCS.\1]/g s/#VIPS_OPERATION_MATH2_\([^ ,.]*\)/[enum@Vips.OperationMath2.\1]/g s/#VIPS_OPERATION_RELATIONAL_\([^ ,.]*\)/[enum@Vips.OperationRelational.\1]/g s/#VIPS_OPERATION_BOOLEAN_\([^ ,.]*\)/[enum@Vips.OperationBoolean.\1]/g diff --git a/libvips/arithmetic/relational.c b/libvips/arithmetic/relational.c index a04481b684..7a30e32b3a 100644 --- a/libvips/arithmetic/relational.c +++ b/libvips/arithmetic/relational.c @@ -291,11 +291,12 @@ vips_relationalv(VipsImage *left, VipsImage *right, VipsImage **out, * [arithmetic](libvips-arithmetic.html)). * * To decide if pixels match exactly, that is have the same value in every - * band, use [method@Image.bandbool] after this operation to AND or OR image bands - * together. + * band, use [method@Image.bandbool] after this operation to AND or OR image + * bands together. * * ::: seealso - * [method@Image.boolean], [method@Image.bandbool], [method@Image.relational_const]. + * [method@Image.boolean], [method@Image.bandbool], + * [method@Image.relational_const]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/convolution/canny.c b/libvips/convolution/canny.c index f2e1457290..67fe6395e8 100644 --- a/libvips/convolution/canny.c +++ b/libvips/convolution/canny.c @@ -478,10 +478,6 @@ vips_canny_init(VipsCanny *canny) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * ::: note "Optional arguments" - * * @sigma: %gdouble, sigma for gaussian blur - * * @precision: [enum@Precision], calculation accuracy - * * Find edges by Canny's method: The maximum of the derivative of the gradient * in the direction of the gradient. Output is float, except for uchar input, * where output is uchar, and double input, where output is double. Non-complex @@ -497,6 +493,10 @@ vips_canny_init(VipsCanny *canny) * You will probably need to process the output further to eliminate weak * edges. * + * ::: tip "Optional arguments" + * * @sigma: %gdouble, sigma for gaussian blur + * * @precision: [enum@Precision], calculation accuracy + * * ::: seealso * [method@Image.sobel]. * diff --git a/libvips/convolution/compass.c b/libvips/convolution/compass.c index 989d1ce050..103c6f3e3f 100644 --- a/libvips/convolution/compass.c +++ b/libvips/convolution/compass.c @@ -1,7 +1,7 @@ /* repeatedly convolve with a rotating mask * * 23/10/13 - * - from vips_conv() + * - from [method@Image.conv] * 8/5/17 * - default to float ... int will often lose precision and should not be * the default @@ -220,20 +220,20 @@ vips_compass_init(VipsCompass *compass) * @mask: convolve with this mask * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @times: %gint, how many times to rotate and convolve - * * @angle: #VipsAngle45, rotate mask by this much between colvolutions - * * @combine: #VipsCombine, combine results like this - * * @precision: #VipsPrecision, precision for blur, default float - * * @layers: %gint, number of layers for approximation - * * @cluster: %gint, cluster lines closer than this distance - * * This convolves @in with @mask @times times, rotating @mask by @angle * each time. By default, it comvolves twice, rotating by 90 degrees, taking * the maximum result. * - * See also: vips_conv(). + * ::: tip "Optional arguments" + * * @times: %gint, how many times to rotate and convolve + * * @angle: [enum@Angle45], rotate mask by this much between colvolutions + * * @combine: #VipsCombine, combine results like this + * * @precision: [enum@Precision], precision for blur, default float + * * @layers: %gint, number of layers for approximation + * * @cluster: %gint, cluster lines closer than this distance + * + * ::: seealso + * [method@Image.conv]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/convolution/conv.c b/libvips/convolution/conv.c index 3779a2ae6d..9f02b022af 100644 --- a/libvips/convolution/conv.c +++ b/libvips/convolution/conv.c @@ -167,44 +167,37 @@ vips_conv_init(VipsConv *conv) * @mask: convolve with this mask * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @precision: #VipsPrecision, calculation accuracy - * * @layers: %gint, number of layers for approximation - * * @cluster: %gint, cluster lines closer than this distance - * - * Convolution. - * * Perform a convolution of @in with @mask. + * * Each output pixel is calculated as: * - * |[ + * ``` * sigma[i]{pixel[i] * mask[i]} / scale + offset - * ]| + * ``` * * where scale and offset are part of @mask. * * By default, @precision is - * #VIPS_PRECISION_FLOAT. The output image - * is always #VIPS_FORMAT_FLOAT unless @in is #VIPS_FORMAT_DOUBLE, in which case - * @out is also #VIPS_FORMAT_DOUBLE. + * [enum@Vips.Precision.FLOAT]. The output image + * is always [enum@Vips.BandFormat.FLOAT] unless @in is + * [enum@Vips.BandFormat.DOUBLE], in which case @out is also + * [enum@Vips.BandFormat.DOUBLE]. * - * If @precision is #VIPS_PRECISION_INTEGER, then - * elements of @mask are converted to - * integers before convolution, using rint(), - * and the output image - * always has the same #VipsBandFormat as the input image. + * If @precision is [enum@Vips.Precision.INTEGER], then elements of @mask + * are converted to integers before convolution, using rint(), + * and the output image always has the same [enum@BandFormat] as the input + * image. * - * For #VIPS_FORMAT_UCHAR images and #VIPS_PRECISION_INTEGER @precision, - * vips_conv() uses a fast vector path based on + * For [enum@Vips.BandFormat.UCHAR] images and [enum@Vips.Precision.INTEGER] + * @precision, [method@Image.conv] uses a fast vector path based on * half-float arithmetic. This can produce slightly different results. * Disable the vector path with `--vips-novector` or `VIPS_NOVECTOR` or - * vips_vector_set_enabled(). + * [func@vector_set_enabled]. * - * If @precision is #VIPS_PRECISION_APPROXIMATE then, like - * #VIPS_PRECISION_INTEGER, @mask is converted to int before convolution, and - * the output image - * always has the same #VipsBandFormat as the input image. + * If @precision is [enum@Vips.Precision.APPROXIMATE] then, like + * [enum@Vips.Precision.INTEGER], @mask is converted to int before + * convolution, and the output image + * always has the same [enum@BandFormat] as the input image. * * Larger values for @layers give more accurate * results, but are slower. As @layers approaches the mask radius, the @@ -215,7 +208,13 @@ vips_conv_init(VipsConv *conv) * Smaller values of @cluster will give more accurate results, but be slower * and use more memory. 10% of the mask radius is a good rule of thumb. * - * See also: vips_convsep(). + * ::: tip "Optional arguments" + * * @precision: [enum@Precision], calculation accuracy + * * @layers: %gint, number of layers for approximation + * * @cluster: %gint, cluster lines closer than this distance + * + * ::: seealso + * [method@Image.convsep]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/convolution/conva.c b/libvips/convolution/conva.c index 463e91f7e1..dd54135141 100644 --- a/libvips/convolution/conva.c +++ b/libvips/convolution/conva.c @@ -1348,17 +1348,12 @@ vips_conva_init(VipsConva *conva) * @mask: convolution mask * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @layers: %gint, number of layers for approximation - * * @cluster: %gint, cluster lines closer than this distance - * * Perform an approximate integer convolution of @in with @mask. - * This is a low-level operation, see - * vips_conv() for something more convenient. + * This is a low-level operation, see [method@Image.conv] for something more + * convenient. * * The output image - * always has the same #VipsBandFormat as the input image. + * always has the same [enum@BandFormat] as the input image. * Elements of @mask are converted to * integers before convolution. * @@ -1371,7 +1366,12 @@ vips_conva_init(VipsConva *conva) * Smaller values of @cluster will give more accurate results, but be slower * and use more memory. 10% of the mask radius is a good rule of thumb. * - * See also: vips_conv(). + * ::: tip "Optional arguments" + * * @layers: %gint, number of layers for approximation + * * @cluster: %gint, cluster lines closer than this distance + * + * ::: seealso + * [method@Image.conv]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/convolution/convasep.c b/libvips/convolution/convasep.c index a43d219c7c..50f3bfb893 100644 --- a/libvips/convolution/convasep.c +++ b/libvips/convolution/convasep.c @@ -936,12 +936,8 @@ vips_convasep_init(VipsConvasep *convasep) * @mask: convolve with this mask * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @layers: %gint, number of layers for approximation - * * Approximate separable integer convolution. This is a low-level operation, see - * vips_convsep() for something more convenient. + * [method@Image.convsep] for something more convenient. * * The image is convolved twice: once with @mask and then again with @mask * rotated by 90 degrees. @@ -956,9 +952,13 @@ vips_convasep_init(VipsConvasep *convasep) * this value and accuracy will still be good. * * The output image - * always has the same #VipsBandFormat as the input image. + * always has the same [enum@BandFormat] as the input image. + * + * ::: tip "Optional arguments" + * * @layers: %gint, number of layers for approximation * - * See also: vips_convsep(). + * ::: seealso + * [method@Image.convsep]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/convolution/convf.c b/libvips/convolution/convf.c index 48188122ee..0da198bfd8 100644 --- a/libvips/convolution/convf.c +++ b/libvips/convolution/convf.c @@ -390,7 +390,7 @@ vips_convf_init(VipsConvf *convf) * @mask: convolve with this mask * @...: %NULL-terminated list of optional named arguments * - * Convolution. This is a low-level operation, see vips_conv() for something + * Convolution. This is a low-level operation, see [method@Image.conv] for something * more convenient. * * Perform a convolution of @in with @mask. @@ -399,10 +399,11 @@ vips_convf_init(VipsConvf *convf) * and offset are part of @mask. * * The convolution is performed with floating-point arithmetic. The output image - * is always #VIPS_FORMAT_FLOAT unless @in is #VIPS_FORMAT_DOUBLE, in which case - * @out is also #VIPS_FORMAT_DOUBLE. + * is always [enum@Vips.BandFormat.FLOAT] unless @in is [enum@Vips.BandFormat.DOUBLE], in which case + * @out is also [enum@Vips.BandFormat.DOUBLE]. * - * See also: vips_conv(). + * ::: seealso + * [method@Image.conv]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/convolution/convi.c b/libvips/convolution/convi.c index bfa36ffa20..f0834ec0ed 100644 --- a/libvips/convolution/convi.c +++ b/libvips/convolution/convi.c @@ -1264,7 +1264,7 @@ vips_convi_init(VipsConvi *convi) * @mask: convolve with this mask * @...: %NULL-terminated list of optional named arguments * - * Integer convolution. This is a low-level operation, see vips_conv() for + * Integer convolution. This is a low-level operation, see [method@Image.conv] for * something more convenient. * * @mask is converted to an integer mask with rint() of each element, rint of @@ -1274,14 +1274,15 @@ vips_convi_init(VipsConvi *convi) * sigma[i]{pixel[i] * mask[i]} / scale + offset * ]| * - * The output image always has the same #VipsBandFormat as the input image. + * The output image always has the same [enum@BandFormat] as the input image. * - * For #VIPS_FORMAT_UCHAR images, vips_convi() uses a fast vector path based on + * For [enum@Vips.BandFormat.UCHAR] images, [method@Image.convi] uses a fast vector path based on * half-float arithmetic. This can produce slightly different results. * Disable the vector path with `--vips-novector` or `VIPS_NOVECTOR` or - * vips_vector_set_enabled(). + * [func@vector_set_enabled]. * - * See also: vips_conv(). + * ::: seealso + * [method@Image.conv]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/convolution/convolution.c b/libvips/convolution/convolution.c index 70a60a2546..26c8fa29c4 100644 --- a/libvips/convolution/convolution.c +++ b/libvips/convolution/convolution.c @@ -66,7 +66,7 @@ * @VIPS_COMBINE_SUM: sum all the values * @VIPS_COMBINE_MIN: take the minimum value * - * How to combine values. See vips_compass(), for example. + * How to combine values. See [method@Image.compass], for example. */ G_DEFINE_ABSTRACT_TYPE(VipsConvolution, vips_convolution, diff --git a/libvips/convolution/convsep.c b/libvips/convolution/convsep.c index 435ab8317f..43968548c7 100644 --- a/libvips/convolution/convsep.c +++ b/libvips/convolution/convsep.c @@ -163,14 +163,8 @@ vips_convsep_init(VipsConvsep *convsep) * @mask: convolution mask * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @precision: calculation accuracy - * * @layers: number of layers for approximation - * * @cluster: cluster lines closer than this distance - * * Perform a separable convolution of @in with @mask. - * See vips_conv() for a detailed description. + * See [method@Image.conv] for a detailed description. * * The mask must be 1xn or nx1 elements. * @@ -178,7 +172,13 @@ vips_convsep_init(VipsConvsep *convsep) * rotated by 90 degrees. This is much faster for certain types of mask * (gaussian blur, for example) than doing a full 2D convolution. * - * See also: vips_conv(), vips_gaussmat(). + * ::: tip "Optional arguments" + * * @precision: [enum@Precision], calculation accuracy + * * @layers: %gint, number of layers for approximation + * * @cluster: %gint, cluster lines closer than this distance + * + * ::: seealso + * [method@Image.conv], [ctor@Image.gaussmat]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/convolution/edge.c b/libvips/convolution/edge.c index c72fedfeaa..36b2f2572f 100644 --- a/libvips/convolution/edge.c +++ b/libvips/convolution/edge.c @@ -341,7 +341,9 @@ vips_prewitt_init(VipsPrewitt *prewitt) * uchar images are computed using a fast, low-precision path. Cast to float * for a high-precision implementation. * - * See also: vips_canny(), vips_sobel(), vips_prewitt(), vips_scharr(). + * ::: seealso + * [method@Image.canny], [method@Image.sobel], [method@Image.prewitt], + * [method@Image.scharr]. * * Returns: 0 on success, -1 on error. */ @@ -369,7 +371,9 @@ vips_sobel(VipsImage *in, VipsImage **out, ...) * uchar images are computed using a fast, low-precision path. Cast to float * for a high-precision implementation. * - * See also: vips_canny(), vips_sobel(), vips_prewitt(), vips_scharr(). + * ::: seealso + * [method@Image.canny], [method@Image.sobel], [method@Image.prewitt], + * [method@Image.scharr]. * * Returns: 0 on success, -1 on error. */ @@ -397,7 +401,9 @@ vips_scharr(VipsImage *in, VipsImage **out, ...) * uchar images are computed using a fast, low-precision path. Cast to float * for a high-precision implementation. * - * See also: vips_canny(), vips_sobel(), vips_prewitt(), vips_scharr(). + * ::: seealso + * [method@Image.canny], [method@Image.sobel], [method@Image.prewitt], + * [method@Image.scharr]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/convolution/fastcor.c b/libvips/convolution/fastcor.c index f1b740b5b3..8ee047686c 100644 --- a/libvips/convolution/fastcor.c +++ b/libvips/convolution/fastcor.c @@ -252,7 +252,8 @@ vips_fastcor_init(VipsFastcor *fastcor) * In other words, the output type is just large enough to hold the whole * range of possible values. * - * See also: vips_spcor(). + * ::: seealso + * [method@Image.spcor]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/convolution/gaussblur.c b/libvips/convolution/gaussblur.c index 40eeda7c20..90e488f350 100644 --- a/libvips/convolution/gaussblur.c +++ b/libvips/convolution/gaussblur.c @@ -177,16 +177,18 @@ vips_gaussblur_init(VipsGaussblur *gaussblur) * @sigma: how large a mask to use * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * This operator runs [ctor@Image.gaussmat] and [method@Image.convsep] for + * you on an image. * - * * @precision: #VipsPrecision, precision for blur, default int - * * @min_ampl: minimum amplitude, default 0.2 - * - * This operator runs vips_gaussmat() and vips_convsep() for you on an image. * Set @min_ampl smaller to generate a larger, more accurate mask. Set @sigma * larger to make the blur more blurry. * - * See also: vips_gaussmat(), vips_convsep(). + * ::: tip "Optional arguments" + * * @precision: [enum@Precision], precision for blur, default int + * * @min_ampl: minimum amplitude, default 0.2 + * + * ::: seealso + * [ctor@Image.gaussmat], [method@Image.convsep]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/convolution/sharpen.c b/libvips/convolution/sharpen.c index 87e6f2dfdb..618b67daec 100644 --- a/libvips/convolution/sharpen.c +++ b/libvips/convolution/sharpen.c @@ -399,17 +399,8 @@ vips_sharpen_init(VipsSharpen *sharpen) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @sigma: sigma of gaussian - * * @x1: flat/jaggy threshold - * * @y2: maximum amount of brightening - * * @y3: maximum amount of darkening - * * @m1: slope for flat areas - * * @m2: slope for jaggy areas - * * Selectively sharpen the L channel of a LAB image. The input image is - * transformed to #VIPS_INTERPRETATION_LABS. + * transformed to [enum@Vips.Interpretation.LABS]. * * The operation performs a gaussian blur and subtracts from @in to generate a * high-frequency signal. This signal is passed through a lookup table formed @@ -417,7 +408,7 @@ vips_sharpen_init(VipsSharpen *sharpen) * * The lookup table is formed like this: * - * |[ + * ``` * . ^ * . y2 |- - - - - ----------- * . | / @@ -435,18 +426,18 @@ vips_sharpen_init(VipsSharpen *sharpen) * . / | * . ______/ _ _ _ _ _ _ | -y3 * . | - * ]| + * ``` * * For screen output, we suggest the following settings (the defaults): * - * |[ + * ``` * sigma == 0.5 * x1 == 2 * y2 == 10 (don't brighten by more than 10 L*) * y3 == 20 (can darken by up to 20 L*) * m1 == 0 (no sharpening in flat areas) * m2 == 3 (some sharpening in jaggy areas) - * ]| + * ``` * * If you want more or less sharpening, we suggest you just change the * m2 parameter. @@ -458,7 +449,16 @@ vips_sharpen_init(VipsSharpen *sharpen) * pixels/mm). These figures refer to the image raster, not the half-tone * resolution. * - * See also: vips_conv(). + * ::: tip "Optional arguments" + * * @sigma: %gdouble, sigma of gaussian + * * @x1: %gdouble, flat/jaggy threshold + * * @y2: %gdouble, maximum amount of brightening + * * @y3: %gdouble, maximum amount of darkening + * * @m1: %gdouble, slope for flat areas + * * @m2: %gdouble, slope for jaggy areas + * + * ::: seealso + * [method@Image.conv]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/convolution/spcor.c b/libvips/convolution/spcor.c index bef10b7aea..8a52dfe8c6 100644 --- a/libvips/convolution/spcor.c +++ b/libvips/convolution/spcor.c @@ -365,7 +365,8 @@ vips_spcor_init(VipsSpcor *spcor) * The output image is always float, unless either of the two inputs is * double, in which case the output is also double. * - * See also: vips_fastcor(). + * ::: seealso + * [method@Image.fastcor]. * * Returns: 0 on success, -1 on error */ From 54963d5ba104bebe95eca3e7dee721e6e8a11c27 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 21 Apr 2025 17:41:04 +0100 Subject: [PATCH 132/174] revise docs in create --- doc/rename.sed | 23 +++++++++++++++++++++++ libvips/create/black.c | 3 ++- libvips/create/buildlut.c | 8 +++++--- libvips/create/create.c | 10 +++++++--- libvips/create/eye.c | 3 ++- libvips/create/fractsurf.c | 3 ++- libvips/create/gaussmat.c | 9 +++++---- libvips/create/gaussnoise.c | 3 ++- libvips/create/grey.c | 3 ++- libvips/create/identity.c | 5 +++-- libvips/create/invertlut.c | 3 ++- libvips/create/logmat.c | 11 ++++++----- libvips/create/mask_butterworth.c | 3 ++- libvips/create/mask_butterworth_band.c | 3 ++- libvips/create/mask_butterworth_ring.c | 3 ++- libvips/create/mask_fractal.c | 5 +++-- libvips/create/mask_gaussian.c | 3 ++- libvips/create/mask_gaussian_band.c | 3 ++- libvips/create/mask_gaussian_ring.c | 3 ++- libvips/create/mask_ideal.c | 13 +++++++------ libvips/create/mask_ideal_band.c | 3 ++- libvips/create/mask_ideal_ring.c | 3 ++- libvips/create/perlin.c | 5 +++-- libvips/create/sdf.c | 9 +++++---- libvips/create/sines.c | 3 ++- libvips/create/text.c | 9 +++++---- libvips/create/tonelut.c | 2 +- libvips/create/worley.c | 3 ++- libvips/create/xyz.c | 5 +++-- libvips/create/zone.c | 3 ++- 30 files changed, 110 insertions(+), 55 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index 1d802c0024..d4e2d23409 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -156,6 +156,7 @@ s/vips_\(exp10\)()/[method@Image.\1]/g s/vips_\(exp\)()/[method@Image.\1]/g s/vips_\(extract_area\)()/[method@Image.\1]/g s/vips_\(extract_band\)()/[method@Image.\1]/g +s/vips_\(eye\)()/[ctor@Image.\1]/g s/vips_\(falsecolour\)()/[method@Image.\1]/g s/vips_\(fastcor\)()/[method@Image.\1]/g s/vips_\(fill_nearest\)()/[method@Image.\1]/g @@ -167,10 +168,13 @@ s/vips_\(flatten\)()/[method@Image.\1]/g s/vips_\(flip\)()/[method@Image.\1]/g s/vips_\(float2rad\)()/[method@Image.\1]/g s/vips_\(floor\)()/[method@Image.\1]/g +s/vips_\(fractsurf\)()/[ctor@Image.\1]/g s/vips_\(freqmult\)()/[method@Image.\1]/g s/vips_\(fwfft\)()/[method@Image.\1]/g s/vips_\(gamma\)()/[method@Image.\1]/g s/vips_\(gaussblur\)()/[method@Image.\1]/g +s/vips_\(gaussmat\)()/[ctor@Image.\1]/g +s/vips_\(gaussnoise\)()/[ctor@Image.\1]/g s/vips_\(getpoint\)()/[method@Image.\1]/g s/vips_\(get_tile_size\)()/[method@Image.\1]/g s/vips_\(gifsave_buffer\)()/[method@Image.\1]/g @@ -178,6 +182,7 @@ s/vips_\(gifsave\)()/[method@Image.\1]/g s/vips_\(gifsave_target\)()/[method@Image.\1]/g s/vips_\(globalbalance\)()/[method@Image.\1]/g s/vips_\(gravity\)()/[method@Image.\1]/g +s/vips_\(grey\)()/[ctor@Image.\1]/g s/vips_\(grid\)()/[method@Image.\1]/g s/vips_\(heifsave_buffer\)()/[method@Image.\1]/g s/vips_\(heifsave\)()/[method@Image.\1]/g @@ -199,6 +204,7 @@ s/vips_\(HSV2sRGB\)()/[method@Image.\1]/g s/vips_\(icc_export\)()/[method@Image.\1]/g s/vips_\(icc_import\)()/[method@Image.\1]/g s/vips_\(icc_transform\)()/[method@Image.\1]/g +s/vips_\(identity\)()/[ctor@Image.\1]/g s/vips_\(ifthenelse\)()/[method@Image.\1]/g s/vips_image_\(get_typeof\)()/[method@Image.\1]/g s/vips_\(imag\)()/[method@Image.\1]/g @@ -240,6 +246,7 @@ s/vips_\(linear1\)()/[method@Image.\1]/g s/vips_\(linear\)()/[method@Image.\1]/g s/vips_\(linecache\)()/[method@Image.\1]/g s/vips_\(log10\)()/[method@Image.\1]/g +s/vips_\(logmat\)()/[ctor@Image.\1]/g s/vips_\(log\)()/[method@Image.\1]/g s/vips_\(lshift_const1\)()/[method@Image.\1]/g s/vips_\(lshift_const\)()/[method@Image.\1]/g @@ -248,6 +255,16 @@ s/vips_\(magicksave_buffer\)()/[method@Image.\1]/g s/vips_\(magicksave\)()/[method@Image.\1]/g s/vips_\(mapim\)()/[method@Image.\1]/g s/vips_\(maplut\)()/[method@Image.\1]/g +s/vips_\(mask_butterworth_band\)()/[ctor@Image.\1]/g +s/vips_\(mask_butterworth\)()/[ctor@Image.\1]/g +s/vips_\(mask_butterworth_ring\)()/[ctor@Image.\1]/g +s/vips_\(mask_fractal\)()/[ctor@Image.\1]/g +s/vips_\(mask_gaussian_band\)()/[ctor@Image.\1]/g +s/vips_\(mask_gaussian\)()/[ctor@Image.\1]/g +s/vips_\(mask_gaussian_ring\)()/[ctor@Image.\1]/g +s/vips_\(mask_ideal_band\)()/[ctor@Image.\1]/g +s/vips_\(mask_ideal\)()/[ctor@Image.\1]/g +s/vips_\(mask_ideal_ring\)()/[ctor@Image.\1]/g s/vips_\(match\)()/[method@Image.\1]/g s/vips_\(math2_const1\)()/[method@Image.\1]/g s/vips_\(math2_const\)()/[method@Image.\1]/g @@ -284,6 +301,7 @@ s/vips_\(orimage_const1\)()/[method@Image.\1]/g s/vips_\(orimage_const\)()/[method@Image.\1]/g s/vips_\(orimage\)()/[method@Image.\1]/g s/vips_\(percent\)()/[method@Image.\1]/g +s/vips_\(perlin\)()/[ctor@Image.\1]/g s/vips_\(phasecor\)()/[method@Image.\1]/g s/vips_\(pngsave_buffer\)()/[method@Image.\1]/g s/vips_\(pngsave\)()/[method@Image.\1]/g @@ -359,11 +377,13 @@ s/vips_\(subsample\)()/[method@Image.\1]/g s/vips_\(subtract\)()/[method@Image.\1]/g s/vips_\(tanh\)()/[method@Image.\1]/g s/vips_\(tan\)()/[method@Image.\1]/g +s/vips_\(text\)()/[ctor@Image.\1]/g s/vips_\(thumbnail_image\)()/[method@Image.\1]/g s/vips_\(tiffsave_buffer\)()/[method@Image.\1]/g s/vips_\(tiffsave\)()/[method@Image.\1]/g s/vips_\(tiffsave_target\)()/[method@Image.\1]/g s/vips_\(tilecache\)()/[method@Image.\1]/g +s/vips_\(tonelut\)()/[ctor@Image.\1]/g s/vips_\(transpose3d\)()/[method@Image.\1]/g s/vips_\(unpremultiply\)()/[method@Image.\1]/g s/vips_\(vipssave\)()/[method@Image.\1]/g @@ -373,12 +393,15 @@ s/vips_\(webpsave\)()/[method@Image.\1]/g s/vips_\(webpsave_mime\)()/[method@Image.\1]/g s/vips_\(webpsave_target\)()/[method@Image.\1]/g s/vips_\(wop\)()/[method@Image.\1]/g +s/vips_\(worley\)()/[ctor@Image.\1]/g s/vips_\(wrap\)()/[method@Image.\1]/g s/vips_\(XYZ2CMYK\)()/[method@Image.\1]/g s/vips_\(XYZ2Lab\)()/[method@Image.\1]/g s/vips_\(XYZ2scRGB\)()/[method@Image.\1]/g s/vips_\(XYZ2Yxy\)()/[method@Image.\1]/g +s/vips_\(xyz\)()/[ctor@Image.\1]/g s/vips_\(Yxy2XYZ\)()/[method@Image.\1]/g +s/vips_\(zone\)()/[ctor@Image.\1]/g s/vips_\(zoom\)()/[method@Image.\1]/g s/vips_\([^(]*\)()/[func@\1]/g diff --git a/libvips/create/black.c b/libvips/create/black.c index 17bc312e75..fabb5df455 100644 --- a/libvips/create/black.c +++ b/libvips/create/black.c @@ -177,7 +177,8 @@ vips_black_init(VipsBlack *black) * * Make a black unsigned char image of a specified size. * - * See also: vips_xyz(), vips_text(), vips_gaussnoise(). + * ::: seealso + * [ctor@Image.xyz], [ctor@Image.text], [ctor@Image.gaussnoise]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/buildlut.c b/libvips/create/buildlut.c index efaaefc37e..9d2155f3bf 100644 --- a/libvips/create/buildlut.c +++ b/libvips/create/buildlut.c @@ -279,8 +279,8 @@ vips_buildlut_init(VipsBuildlut *lut) * * This operation builds a lookup table from a set of points. Intermediate * values are generated by piecewise linear interpolation. The lookup table is - * always of type #VIPS_FORMAT_DOUBLE, use vips_cast() to change it to the - * type you need. + * always of type [enum@Vips.BandFormat.DOUBLE], use [method@Image.cast] to + * change it to the type you need. * * For example, consider this 2 x 2 matrix of (x, y) coordinates: * @@ -306,7 +306,9 @@ vips_buildlut_init(VipsBuildlut *lut) * several Ys, each becomes a band in the output LUT. You don't need to * start at zero, any integer will do, including negatives. * - * See also: vips_identity(), vips_invertlut(), vips_cast(), vips_maplut(). + * ::: seealso + * [ctor@Image.identity], [method@Image.invertlut], [method@Image.cast], + * [method@Image.maplut]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/create.c b/libvips/create/create.c index 427a1199ad..e9e46861a8 100644 --- a/libvips/create/create.c +++ b/libvips/create/create.c @@ -58,10 +58,11 @@ * @VIPS_TEXT_WRAP_WORD_CHAR: wrap at word boundaries, but fall back to character boundaries if there is not enough space for a full word * @VIPS_TEXT_WRAP_NONE: no wrapping * - * Sets the word wrapping style for vips_text() when used with a maximum + * Sets the word wrapping style for [ctor@Image.text] when used with a maximum * width. * - * See also: vips_text(). + * ::: seealso + * [ctor@Image.text]. */ /** @@ -73,7 +74,8 @@ * * The SDF to generate, * - * See also: vips_sdf(). + * ::: seealso + * [ctor@Image.sdf]. */ G_DEFINE_ABSTRACT_TYPE(VipsCreate, vips_create, VIPS_TYPE_OPERATION); @@ -160,9 +162,11 @@ vips_create_operation_init(void) vips_gaussmat_get_type(); vips_logmat_get_type(); vips_gaussnoise_get_type(); + #ifdef HAVE_PANGOCAIRO vips_text_get_type(); #endif /*HAVE_PANGOCAIRO*/ + vips_xyz_get_type(); vips_sdf_get_type(); vips_eye_get_type(); diff --git a/libvips/create/eye.c b/libvips/create/eye.c index 091c75a070..2f0f69157c 100644 --- a/libvips/create/eye.c +++ b/libvips/create/eye.c @@ -136,7 +136,8 @@ vips_eye_init(VipsEye *eye) * * Set @uchar to output a uchar image. * - * See also: vips_zone(). + * ::: seealso + * [ctor@Image.zone]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/fractsurf.c b/libvips/create/fractsurf.c index 2d3ad96412..d1c09e0945 100644 --- a/libvips/create/fractsurf.c +++ b/libvips/create/fractsurf.c @@ -141,7 +141,8 @@ vips_fractsurf_init(VipsFractsurf *fractsurf) * Generate an image of size @width by @height and fractal dimension * @fractal_dimension. The dimension should be between 2 and 3. * - * See also: vips_gaussnoise(), vips_mask_fractal(). + * ::: seealso + * [ctor@Image.gaussnoise], [ctor@Image.mask_fractal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/gaussmat.c b/libvips/create/gaussmat.c index 0fd167c45c..b9a6237411 100644 --- a/libvips/create/gaussmat.c +++ b/libvips/create/gaussmat.c @@ -235,7 +235,7 @@ vips_gaussmat_init(VipsGaussmat *gaussmat) * Optional arguments: * * * @separable: generate a separable gaussian - * * @precision: #VipsPrecision for @out + * * @precision: [enum@Precision] for @out * * Creates a circularly symmetric Gaussian image of radius * @sigma. The size of the mask is determined by the variable @min_ampl; @@ -247,17 +247,18 @@ vips_gaussmat_init(VipsGaussmat *gaussmat) * H(r) = exp(-(r * r) / (2 * @sigma * @sigma)) * * The generated image has odd size and its maximum value is normalised to - * 1.0, unless @precision is #VIPS_PRECISION_INTEGER. + * 1.0, unless @precision is [enum@Vips.Precision.INTEGER]. * * If @separable is set, only the centre horizontal is generated. This is * useful for separable convolutions. * - * If @precision is #VIPS_PRECISION_INTEGER, an integer gaussian is generated. + * If @precision is [enum@Vips.Precision.INTEGER], an integer gaussian is generated. * This is useful for integer convolutions. * * "scale" is set to the sum of all the mask elements. * - * See also: vips_logmat(), vips_conv(). + * ::: seealso + * [ctor@Image.logmat], [method@Image.conv]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/gaussnoise.c b/libvips/create/gaussnoise.c index 7a94764462..500df796f8 100644 --- a/libvips/create/gaussnoise.c +++ b/libvips/create/gaussnoise.c @@ -224,7 +224,8 @@ vips_gaussnoise_init(VipsGaussnoise *gaussnoise) * distribution. The noise distribution is created by averaging 12 random * numbers with the appropriate weights. * - * See also: vips_black(), vips_xyz(), vips_text(). + * ::: seealso + * [ctor@Image.black], [ctor@Image.xyz], [ctor@Image.text]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/grey.c b/libvips/create/grey.c index 6ee420fa89..675f9cbae3 100644 --- a/libvips/create/grey.c +++ b/libvips/create/grey.c @@ -115,7 +115,8 @@ vips_grey_init(VipsGrey *grey) * Set @uchar to output a uchar image with the leftmost pixel 0 and the * rightmost 255. * - * See also: vips_xyz(), vips_identity(). + * ::: seealso + * [ctor@Image.xyz], [ctor@Image.identity]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/identity.c b/libvips/create/identity.c index 42e0024c07..95409d30df 100644 --- a/libvips/create/identity.c +++ b/libvips/create/identity.c @@ -181,7 +181,7 @@ vips_identity_init(VipsIdentity *identity) * * @size: number of LUT elements for a ushort image * * Creates an identity lookup table, ie. one which will leave an image - * unchanged when applied with vips_maplut(). Each entry in the table has a + * unchanged when applied with [method@Image.maplut]. Each entry in the table has a * value equal to its position. * * Use the arithmetic operations on these tables to make LUTs representing @@ -192,7 +192,8 @@ vips_identity_init(VipsIdentity *identity) * Normally 16-bit tables have 65536 entries. You can set this smaller with * @size. * - * See also: vips_xyz(), vips_maplut(). + * ::: seealso + * [ctor@Image.xyz], [method@Image.maplut]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/invertlut.c b/libvips/create/invertlut.c index 507fc634f5..ac24fc067a 100644 --- a/libvips/create/invertlut.c +++ b/libvips/create/invertlut.c @@ -338,7 +338,8 @@ vips_invertlut_init(VipsInvertlut *lut) * (we should fix this). Interpolation is simple piecewise linear; we ought to * do something better really. * - * See also: vips_buildlut(). + * ::: seealso + * [method@Image.buildlut]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/logmat.c b/libvips/create/logmat.c index 909ab9aebb..31b986604b 100644 --- a/libvips/create/logmat.c +++ b/libvips/create/logmat.c @@ -15,7 +15,7 @@ * 20/10/13 * - redone as a class from logmat.c * 16/12/14 - * - default to int output to match vips_conv() + * - default to int output to match [method@Image.conv] * - use @precision, not @integer */ @@ -251,7 +251,7 @@ vips_logmat_init(VipsLogmat *logmat) * Optional arguments: * * * @separable: generate a separable mask - * * @precision: #VipsPrecision for @out + * * @precision: [enum@Precision] for @out * * Creates a circularly symmetric Laplacian of Gaussian mask * of radius @@ -270,17 +270,18 @@ vips_logmat_init(VipsLogmat *logmat) * where s2 = @sigma * @sigma, s4 = s2 * s2, r2 = r * r. * * The generated mask has odd size and its maximum value is normalised to - * 1.0, unless @precision is #VIPS_PRECISION_INTEGER. + * 1.0, unless @precision is [enum@Vips.Precision.INTEGER]. * * If @separable is set, only the centre horizontal is generated. This is * useful for separable convolutions. * - * If @precision is #VIPS_PRECISION_INTEGER, an integer mask is generated. + * If @precision is [enum@Vips.Precision.INTEGER], an integer mask is generated. * This is useful for integer convolutions. * * "scale" is set to the sum of all the mask elements. * - * See also: vips_gaussmat(), vips_conv(). + * ::: seealso + * [ctor@Image.gaussmat], [method@Image.conv]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/mask_butterworth.c b/libvips/create/mask_butterworth.c index 293e374e52..70c02d6e3c 100644 --- a/libvips/create/mask_butterworth.c +++ b/libvips/create/mask_butterworth.c @@ -141,7 +141,8 @@ vips_mask_butterworth_init(VipsMaskButterworth *butterworth) * @order --- higher values give a sharper transition. See Gonzalez and Wintz, * Digital Image Processing, 1987. * - * See also: vips_mask_ideal(). + * ::: seealso + * [ctor@Image.mask_ideal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/mask_butterworth_band.c b/libvips/create/mask_butterworth_band.c index 80ee78ece8..4f9e1f467c 100644 --- a/libvips/create/mask_butterworth_band.c +++ b/libvips/create/mask_butterworth_band.c @@ -184,7 +184,8 @@ vips_mask_butterworth_band_init( * @order --- higher values give a sharper transition. See Gonzalez and Wintz, * Digital Image Processing, 1987. * - * See also: vips_mask_ideal(). + * ::: seealso + * [ctor@Image.mask_ideal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/mask_butterworth_ring.c b/libvips/create/mask_butterworth_ring.c index 22b3515340..1b8d9d19cb 100644 --- a/libvips/create/mask_butterworth_ring.c +++ b/libvips/create/mask_butterworth_ring.c @@ -143,7 +143,8 @@ vips_mask_butterworth_ring_init( * @order --- higher values give a sharper transition. See Gonzalez and Wintz, * Digital Image Processing, 1987. * - * See also: vips_mask_ideal(). + * ::: seealso + * [ctor@Image.mask_ideal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/mask_fractal.c b/libvips/create/mask_fractal.c index 7d0de0a39d..3a1c2aba0a 100644 --- a/libvips/create/mask_fractal.c +++ b/libvips/create/mask_fractal.c @@ -119,9 +119,10 @@ vips_mask_fractal_init(VipsMaskFractal *fractal) * * @uchar: output a uchar image * * This operation should be used to create fractal images by filtering the - * power spectrum of Gaussian white noise. See vips_gaussnoise(). + * power spectrum of Gaussian white noise. See [ctor@Image.gaussnoise]. * - * See also: vips_mask_ideal(). + * ::: seealso + * [ctor@Image.mask_ideal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/mask_gaussian.c b/libvips/create/mask_gaussian.c index 15a31377e1..535c5cbf48 100644 --- a/libvips/create/mask_gaussian.c +++ b/libvips/create/mask_gaussian.c @@ -123,7 +123,8 @@ vips_mask_gaussian_init(VipsMaskGaussian *gaussian) * Make a gaussian high- or low-pass filter, that is, one with a variable, * smooth transition positioned at @frequency_cutoff. * - * See also: vips_mask_ideal(). + * ::: seealso + * [ctor@Image.mask_ideal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/mask_gaussian_band.c b/libvips/create/mask_gaussian_band.c index fac2bd5f09..ee3e77cf83 100644 --- a/libvips/create/mask_gaussian_band.c +++ b/libvips/create/mask_gaussian_band.c @@ -163,7 +163,8 @@ vips_mask_gaussian_band_init(VipsMaskGaussianBand *gaussian_band) * variable, smooth transition positioned at @frequency_cutoff_x, * @frequency_cutoff_y, of radius @radius. * - * See also: vips_mask_ideal(). + * ::: seealso + * [ctor@Image.mask_ideal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/mask_gaussian_ring.c b/libvips/create/mask_gaussian_ring.c index b037801cf9..4f235f56c7 100644 --- a/libvips/create/mask_gaussian_ring.c +++ b/libvips/create/mask_gaussian_ring.c @@ -132,7 +132,8 @@ vips_mask_gaussian_ring_init(VipsMaskGaussianRing *gaussian_ring) * variable, smooth transition positioned at @frequency_cutoff of width * @ringwidth. * - * See also: vips_mask_ideal(). + * ::: seealso + * [ctor@Image.mask_ideal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/mask_ideal.c b/libvips/create/mask_ideal.c index 0e8453a304..af3dff6465 100644 --- a/libvips/create/mask_ideal.c +++ b/libvips/create/mask_ideal.c @@ -124,7 +124,7 @@ vips_mask_ideal_init(VipsMaskIdeal *ideal) * * Set @optical to position the DC component in the centre of the image. This * makes the mask suitable for multiplying against optical Fourier transforms. - * See vips_wrap(). + * See [method@Image.wrap]. * * Set @reject to invert the sense of * the filter. For example, low-pass becomes low-reject. @@ -132,11 +132,12 @@ vips_mask_ideal_init(VipsMaskIdeal *ideal) * Set @uchar to output an 8-bit unsigned char image rather than a * float image. In this case, pixels are in the range [0 - 255]. * - * See also: vips_mask_ideal(), vips_mask_ideal_ring(), - * vips_mask_ideal_band(), vips_mask_butterworth(), - * vips_mask_butterworth_ring(), vips_mask_butterworth_band(), - * vips_mask_gaussian(), vips_mask_gaussian_ring(), - * vips_mask_gaussian_band(). + * ::: seealso + * [ctor@Image.mask_ideal], [ctor@Image.mask_ideal_ring], + * [ctor@Image.mask_ideal_band], [ctor@Image.mask_butterworth], + * [ctor@Image.mask_butterworth_ring], [ctor@Image.mask_butterworth_band], + * [ctor@Image.mask_gaussian], [ctor@Image.mask_gaussian_ring], + * [ctor@Image.mask_gaussian_band]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/mask_ideal_band.c b/libvips/create/mask_ideal_band.c index 810275767a..5ff4cbe4e7 100644 --- a/libvips/create/mask_ideal_band.c +++ b/libvips/create/mask_ideal_band.c @@ -145,7 +145,8 @@ vips_mask_ideal_band_init(VipsMaskIdealBand *ideal_band) * sharp cutoff around the point @frequency_cutoff_x, @frequency_cutoff_y, * of size @radius. * - * See also: vips_mask_ideal(). + * ::: seealso + * [ctor@Image.mask_ideal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/mask_ideal_ring.c b/libvips/create/mask_ideal_ring.c index 37ff4cc4c0..3f09864c68 100644 --- a/libvips/create/mask_ideal_ring.c +++ b/libvips/create/mask_ideal_ring.c @@ -128,7 +128,8 @@ vips_mask_ideal_ring_init(VipsMaskIdealRing *ideal_ring) * ring positioned at @frequency_cutoff of width @width, where * @frequency_cutoff and @width are expressed as the range 0 - 1. * - * See also: vips_mask_ideal(). + * ::: seealso + * [ctor@Image.mask_ideal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/perlin.c b/libvips/create/perlin.c index 4435d6cb04..5ca1a9c632 100644 --- a/libvips/create/perlin.c +++ b/libvips/create/perlin.c @@ -355,10 +355,11 @@ vips_perlin_init(VipsPerlin *perlin) * * If @width and @height are multiples of @cell_size, the image will tessellate. * - * Normally, output pixels are #VIPS_FORMAT_FLOAT in the range [-1, +1]. Set + * Normally, output pixels are [enum@Vips.BandFormat.FLOAT] in the range [-1, +1]. Set * @uchar to output a uchar image with pixels in [0, 255]. * - * See also: vips_worley(), vips_fractsurf(), vips_gaussnoise(). + * ::: seealso + * [ctor@Image.worley], [ctor@Image.fractsurf], [ctor@Image.gaussnoise]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/sdf.c b/libvips/create/sdf.c index c5e09d82d3..6ff8048c07 100644 --- a/libvips/create/sdf.c +++ b/libvips/create/sdf.c @@ -367,10 +367,10 @@ vips_sdf_init(VipsSdf *sdf) * * Optional arguments: * - * * @a: #VipsArrayDouble, first point - * * @b: #VipsArrayDouble, second point + * * @a: [struct@ArrayDouble], first point + * * @b: [struct@ArrayDouble], second point * * @r: %gfloat, radius - * * @corners: #VipsArrayDouble, corner radii + * * @corners: [struct@ArrayDouble], corner radii * * Create a signed distance field (SDF) image of the given shape. Different * shapes use different combinations of the optional arguments, see below. @@ -387,7 +387,8 @@ vips_sdf_init(VipsSdf *sdf) * * @shape #VIPS_SDF_SHAPE_LINE: draw a line from @a to @b. * - * See also: vips_grey(), vips_grid(), vips_xyz(). + * ::: seealso + * [ctor@Image.grey], [method@Image.grid], [ctor@Image.xyz]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/sines.c b/libvips/create/sines.c index aa13efbc59..489bcf8b24 100644 --- a/libvips/create/sines.c +++ b/libvips/create/sines.c @@ -172,7 +172,8 @@ vips_sines_init(VipsSines *sines) * * Pixels are normally in [-1, +1], set @uchar to output [0, 255]. * - * See also: vips_grey(), vips_xyz(). + * ::: seealso + * [ctor@Image.grey], [ctor@Image.xyz]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/text.c b/libvips/create/text.c index 9ee75cb7d9..2d6ba23b9b 100644 --- a/libvips/create/text.c +++ b/libvips/create/text.c @@ -381,7 +381,7 @@ vips_text_autofit(VipsText *text) static void * vips_text_init_once(void *client) { - vips_text_fontmap = pango_cairo_font_map_new(); + vips_text_fontmap = pango_cairo_font_map_new();; vips_text_fontfiles = g_hash_table_new(g_str_hash, g_str_equal); return NULL; @@ -700,7 +700,7 @@ vips_text_init(VipsText *text) * * @height is the maximum number of pixels high the generated text can be. This * only takes effect when @dpi is not set, and @width is set, making a box. - * In this case, vips_text() will search for a @dpi and set of line breaks + * In this case, [ctor@Image.text] will search for a @dpi and set of line breaks * which will just fit the text into @width and @height. * * You can use @autofit_dpi to read out the DPI selected by auto fit. @@ -713,9 +713,10 @@ vips_text_init(VipsText *text) * * You can read the coordinate of the top edge of the character from `Xoffset` * / `Yoffset`. This can be helpful if you need to line up the output of - * several vips_text(). + * several [ctor@Image.text]. * - * See also: vips_bandjoin(), vips_composite(). + * ::: seealso + * [func@Image.bandjoin], [func@Image.composite]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/tonelut.c b/libvips/create/tonelut.c index d8cfd6fc18..e3e666f036 100644 --- a/libvips/create/tonelut.c +++ b/libvips/create/tonelut.c @@ -325,7 +325,7 @@ vips_tonelut_init(VipsTonelut *lut) * * @M: mid-tone adjustment (+/- 30) * * @H: highlight adjustment (+/- 30) * - * vips_tonelut() generates a tone curve for the adjustment of image + * [ctor@Image.tonelut] generates a tone curve for the adjustment of image * levels. It is mostly designed for adjusting the L* part of a LAB image in * a way suitable for print work, but you can use it for other things too. * diff --git a/libvips/create/worley.c b/libvips/create/worley.c index c0877be78c..0834f96776 100644 --- a/libvips/create/worley.c +++ b/libvips/create/worley.c @@ -360,7 +360,8 @@ vips_worley_init(VipsWorley *worley) * * If @width and @height are multiples of @cell_size, the image will tessellate. * - * See also: vips_perlin(), vips_fractsurf(), vips_gaussnoise(). + * ::: seealso + * [ctor@Image.perlin], [ctor@Image.fractsurf], [ctor@Image.gaussnoise]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/xyz.c b/libvips/create/xyz.c index f5046f3053..528f95bda0 100644 --- a/libvips/create/xyz.c +++ b/libvips/create/xyz.c @@ -256,9 +256,10 @@ vips_xyz_init(VipsXyz *xyz) * * Set @csize, @dsize, @esize to generate higher dimensions and add more * bands. The extra dimensions are placed down the vertical axis. Use - * vips_grid() to change the layout. + * [method@Image.grid] to change the layout. * - * See also: vips_grey(), vips_grid(), vips_identity(). + * ::: seealso + * [ctor@Image.grey], [method@Image.grid], [ctor@Image.identity]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/zone.c b/libvips/create/zone.c index 81ceeb2c12..f943a7d248 100644 --- a/libvips/create/zone.c +++ b/libvips/create/zone.c @@ -112,7 +112,8 @@ vips_zone_init(VipsZone *zone) * * Pixels are normally in [-1, +1], set @uchar to output [0, 255]. * - * See also: vips_eye(), vips_xyz(). + * ::: seealso + * [ctor@Image.eye], [ctor@Image.xyz]. * * Returns: 0 on success, -1 on error */ From 8d05856e3c9cdec168745bd6cba8e34ed35024a0 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 22 Apr 2025 13:28:08 +0100 Subject: [PATCH 133/174] reformat "optional arg" blocks in create --- doc/rename.sed | 4 ++++ libvips/create/black.c | 7 +++---- libvips/create/eye.c | 13 ++++++------ libvips/create/gaussmat.c | 21 +++++++++++-------- libvips/create/gaussnoise.c | 13 ++++++------ libvips/create/grey.c | 11 +++++----- libvips/create/identity.c | 15 +++++++------ libvips/create/invertlut.c | 15 ++++++------- libvips/create/logmat.c | 28 +++++++++++++++---------- libvips/create/mask_butterworth.c | 17 ++++++++------- libvips/create/mask_butterworth_band.c | 14 ++++++------- libvips/create/mask_butterworth_ring.c | 17 ++++++++------- libvips/create/mask_fractal.c | 15 ++++++------- libvips/create/mask_gaussian.c | 13 ++++++------ libvips/create/mask_gaussian_band.c | 13 ++++++------ libvips/create/mask_gaussian_ring.c | 13 ++++++------ libvips/create/mask_ideal.c | 13 ++++++------ libvips/create/mask_ideal_band.c | 13 ++++++------ libvips/create/mask_ideal_ring.c | 13 ++++++------ libvips/create/perlin.c | 15 ++++++------- libvips/create/sdf.c | 23 ++++++++++---------- libvips/create/sines.c | 11 +++++----- libvips/create/text.c | 29 +++++++++++++------------- libvips/create/tonelut.c | 29 +++++++++++++------------- libvips/create/worley.c | 9 ++++---- libvips/create/xyz.c | 11 +++++----- libvips/create/zone.c | 7 +++---- 27 files changed, 208 insertions(+), 194 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index d4e2d23409..fb5c70a87f 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -73,6 +73,7 @@ s/vips_\(bandfold\)()/[method@Image.\1]/g s/vips_\(bandjoin2\)()/[method@Image.\1]/g s/vips_\(bandjoin_const1\)()/[method@Image.\1]/g s/vips_\(bandjoin_const\)()/[method@Image.\1]/g +s/vips_\(bandjoin\)()/[func@Image.\1]/g s/vips_\(bandmean\)()/[method@Image.\1]/g s/vips_\(bandor\)()/[method@Image.\1]/g s/vips_\(bandunfold\)()/[method@Image.\1]/g @@ -111,6 +112,7 @@ s/vips_\(composite2\)()/[method@Image.\1]/g s/vips_\(conj\)()/[method@Image.\1]/g s/vips_\(conva\)()/[method@Image.\1]/g s/vips_\(convasep\)()/[method@Image.\1]/g +s/vips_\(conversion\)()/[func@Image.\1]/g s/vips_\(convf\)()/[method@Image.\1]/g s/vips_\(convi\)()/[method@Image.\1]/g s/vips_\(conv\)()/[method@Image.\1]/g @@ -406,6 +408,7 @@ s/vips_\(zoom\)()/[method@Image.\1]/g s/vips_\([^(]*\)()/[func@\1]/g +s/#Vips\(SdfShape\)/[enum@\1]/g s/#Vips\(Access\)/[enum@\1]/g s/#Vips\(BandFormat\)/[enum@\1]/g s/#Vips\(Interpretation\)/[enum@\1]/g @@ -442,6 +445,7 @@ s/#Vips\(ThreadpoolAllocateFn\)/[callback@\1]/g s/#Vips\(ThreadpoolWorkFn\)/[callback@\1]/g s/#Vips\(ThreadpoolProgressFn\)/[callback@\1]/g +s/#VIPS_SDF_SHAPE_\([^ ,.]*\)/[enum@Vips.SdfShape.\1]/g s/#VIPS_OPERATION_MATH_\([^ ,.]*\)/[enum@Vips.OperationMath.\1]/g s/#VIPS_OPERATION_MATH2_\([^ ,.]*\)/[enum@Vips.OperationMath2.\1]/g s/#VIPS_OPERATION_RELATIONAL_\([^ ,.]*\)/[enum@Vips.OperationRelational.\1]/g diff --git a/libvips/create/black.c b/libvips/create/black.c index fabb5df455..e8d22b9642 100644 --- a/libvips/create/black.c +++ b/libvips/create/black.c @@ -171,12 +171,11 @@ vips_black_init(VipsBlack *black) * @height: output height * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @bands: output bands - * * Make a black unsigned char image of a specified size. * + * ::: tip "Optional arguments" + * * @bands: %gint, output bands + * * ::: seealso * [ctor@Image.xyz], [ctor@Image.text], [ctor@Image.gaussnoise]. * diff --git a/libvips/create/eye.c b/libvips/create/eye.c index 2f0f69157c..8e337b26f8 100644 --- a/libvips/create/eye.c +++ b/libvips/create/eye.c @@ -125,17 +125,18 @@ vips_eye_init(VipsEye *eye) * @height: image size * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @factor: %gdouble, maximum spatial frequency - * * @uchar: %gboolean, output a uchar image - * * Create a test pattern with increasing spatial frequency in X and - * amplitude in Y. @factor should be between 0 and 1 and determines the + * amplitude in Y. + * + * @factor should be between 0 and 1 and determines the * maximum spatial frequency. * * Set @uchar to output a uchar image. * + * ::: tip "Optional arguments" + * * @factor: %gdouble, maximum spatial frequency + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.zone]. * diff --git a/libvips/create/gaussmat.c b/libvips/create/gaussmat.c index b9a6237411..2b643072d3 100644 --- a/libvips/create/gaussmat.c +++ b/libvips/create/gaussmat.c @@ -232,19 +232,18 @@ vips_gaussmat_init(VipsGaussmat *gaussmat) * @min_ampl: minimum amplitude * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @separable: generate a separable gaussian - * * @precision: [enum@Precision] for @out - * * Creates a circularly symmetric Gaussian image of radius - * @sigma. The size of the mask is determined by the variable @min_ampl; + * @sigma. + * + * The size of the mask is determined by the variable @min_ampl; * if for instance the value .1 is entered this means that the produced mask * is clipped at values less than 10 percent of the maximum amplitude. * * The program uses the following equation: * - * H(r) = exp(-(r * r) / (2 * @sigma * @sigma)) + * ``` + * H(r) = exp(-(r * r) / (2 * @sigma * @sigma)) + * ``` * * The generated image has odd size and its maximum value is normalised to * 1.0, unless @precision is [enum@Vips.Precision.INTEGER]. @@ -252,11 +251,15 @@ vips_gaussmat_init(VipsGaussmat *gaussmat) * If @separable is set, only the centre horizontal is generated. This is * useful for separable convolutions. * - * If @precision is [enum@Vips.Precision.INTEGER], an integer gaussian is generated. - * This is useful for integer convolutions. + * If @precision is [enum@Vips.Precision.INTEGER], an integer gaussian is + * generated. This is useful for integer convolutions. * * "scale" is set to the sum of all the mask elements. * + * ::: tip "Optional arguments" + * * @separable: %gboolean, generate a separable gaussian + * * @precision: [enum@Precision] for @out + * * ::: seealso * [ctor@Image.logmat], [method@Image.conv]. * diff --git a/libvips/create/gaussnoise.c b/libvips/create/gaussnoise.c index 500df796f8..7b1dc887d6 100644 --- a/libvips/create/gaussnoise.c +++ b/libvips/create/gaussnoise.c @@ -215,14 +215,15 @@ vips_gaussnoise_init(VipsGaussnoise *gaussnoise) * @height: output height * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Make a one band float image of gaussian noise with the specified + * distribution. * - * * @mean: mean of generated pixels - * * @sigma: standard deviation of generated pixels + * The gaussian distribution is created by averaging 12 random numbers from a + * linear generator, then weighting appropriately with @mean and @sigma. * - * Make a one band float image of gaussian noise with the specified - * distribution. The noise distribution is created by averaging 12 random - * numbers with the appropriate weights. + * ::: tip "Optional arguments" + * * @mean: %gdouble, mean of generated pixels + * * @sigma: %gdouble, standard deviation of generated pixels * * ::: seealso * [ctor@Image.black], [ctor@Image.xyz], [ctor@Image.text]. diff --git a/libvips/create/grey.c b/libvips/create/grey.c index 675f9cbae3..51f800258f 100644 --- a/libvips/create/grey.c +++ b/libvips/create/grey.c @@ -105,16 +105,17 @@ vips_grey_init(VipsGrey *grey) * @height: image size * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @uchar: output a uchar image - * * Create a one-band float image with the left-most column zero and the - * right-most 1. Intermediate pixels are a linear ramp. + * right-most 1. + * + * Intermediate pixels are a linear ramp. * * Set @uchar to output a uchar image with the leftmost pixel 0 and the * rightmost 255. * + * ::: tip "Optional arguments" + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.xyz], [ctor@Image.identity]. * diff --git a/libvips/create/identity.c b/libvips/create/identity.c index 95409d30df..67073aba07 100644 --- a/libvips/create/identity.c +++ b/libvips/create/identity.c @@ -174,15 +174,9 @@ vips_identity_init(VipsIdentity *identity) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @bands: number of bands to create - * * @ushort: %TRUE for an unsigned short identity - * * @size: number of LUT elements for a ushort image - * * Creates an identity lookup table, ie. one which will leave an image - * unchanged when applied with [method@Image.maplut]. Each entry in the table has a - * value equal to its position. + * unchanged when applied with [method@Image.maplut]. Each entry in the table + * has a value equal to its position. * * Use the arithmetic operations on these tables to make LUTs representing * arbitrary functions. @@ -192,6 +186,11 @@ vips_identity_init(VipsIdentity *identity) * Normally 16-bit tables have 65536 entries. You can set this smaller with * @size. * + * ::: tip "Optional arguments" + * * @bands: %gint, number of bands to create + * * @ushort: %gboolean, %TRUE for an unsigned short identity + * * @size: %gint, number of LUT elements for a ushort image + * * ::: seealso * [ctor@Image.xyz], [method@Image.maplut]. * diff --git a/libvips/create/invertlut.c b/libvips/create/invertlut.c index ac24fc067a..208f4ad561 100644 --- a/libvips/create/invertlut.c +++ b/libvips/create/invertlut.c @@ -310,14 +310,12 @@ vips_invertlut_init(VipsInvertlut *lut) * @out: (out): output LUT * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @size: generate this much - * * Given a mask of target values and real values, generate a LUT which - * will map reals to targets. Handy for linearising images from - * measurements of a colour chart. All values in [0,1]. Piecewise linear - * interpolation, extrapolate head and tail to 0 and 1. + * will map reals to targets. + * + * Handy for linearising images from measurements of a colour chart. All + * values in [0,1]. Piecewise linear interpolation, extrapolate head and tail + * to 0 and 1. * * Eg. input like this: * @@ -338,6 +336,9 @@ vips_invertlut_init(VipsInvertlut *lut) * (we should fix this). Interpolation is simple piecewise linear; we ought to * do something better really. * + * ::: tip "Optional arguments" + * * @size: %gint, generate this much + * * ::: seealso * [method@Image.buildlut]. * diff --git a/libvips/create/logmat.c b/libvips/create/logmat.c index 31b986604b..0f5aeb8880 100644 --- a/libvips/create/logmat.c +++ b/libvips/create/logmat.c @@ -248,14 +248,10 @@ vips_logmat_init(VipsLogmat *logmat) * @min_ampl: minimum amplitude * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Create a circularly symmetric Laplacian of Gaussian mask of radius + * @sigma. * - * * @separable: generate a separable mask - * * @precision: [enum@Precision] for @out - * - * Creates a circularly symmetric Laplacian of Gaussian mask - * of radius - * @sigma. The size of the mask is determined by the variable @min_ampl; + * The size of the mask is determined by the variable @min_ampl; * if for instance the value .1 is entered this means that the produced mask * is clipped at values within 10 percent of zero, and where the change * between mask elements is less than 10%. @@ -263,11 +259,17 @@ vips_logmat_init(VipsLogmat *logmat) * The program uses the following equation: (from Handbook of Pattern * Recognition and image processing by Young and Fu, AP 1986 pages 220-221): * - * H(r) = (1 / (2 * M_PI * s4)) * - * (2 - (r2 / s2)) * - * exp(-r2 / (2 * s2)) + * ``` + * H(r) = (1 / (2 * M_PI * s4)) * (2 - (r2 / s2)) * exp(-r2 / (2 * s2)) + * ``` + * + * where: * - * where s2 = @sigma * @sigma, s4 = s2 * s2, r2 = r * r. + * ``` + * 2 = @sigma * @sigma, + * s4 = s2 * s2 + * r2 = r * r. + * ``` * * The generated mask has odd size and its maximum value is normalised to * 1.0, unless @precision is [enum@Vips.Precision.INTEGER]. @@ -280,6 +282,10 @@ vips_logmat_init(VipsLogmat *logmat) * * "scale" is set to the sum of all the mask elements. * + * ::: tip "Optional arguments" + * * @separable: %gboolean, generate a separable mask + * * @precision: [enum@Precision] for @out + * * ::: seealso * [ctor@Image.gaussmat], [method@Image.conv]. * diff --git a/libvips/create/mask_butterworth.c b/libvips/create/mask_butterworth.c index 70c02d6e3c..71a50e7f17 100644 --- a/libvips/create/mask_butterworth.c +++ b/libvips/create/mask_butterworth.c @@ -127,20 +127,21 @@ vips_mask_butterworth_init(VipsMaskButterworth *butterworth) * @amplitude_cutoff: amplitude threshold * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @nodc: don't set the DC pixel - * * @reject: invert the filter sense - * * @optical: coordinates in optical space - * * @uchar: output a uchar image - * * Make an butterworth high- or low-pass filter, that is, one with a variable, * smooth transition * positioned at @frequency_cutoff, where @frequency_cutoff is in - * range 0 - 1. The shape of the curve is controlled by + * range 0 - 1. + * + * The shape of the curve is controlled by * @order --- higher values give a sharper transition. See Gonzalez and Wintz, * Digital Image Processing, 1987. * + * ::: tip "Optional arguments" + * * @nodc: %gboolean, don't set the DC pixel + * * @reject: %gboolean, invert the filter sense + * * @optical: %gboolean, coordinates in optical space + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.mask_ideal]. * diff --git a/libvips/create/mask_butterworth_band.c b/libvips/create/mask_butterworth_band.c index 4f9e1f467c..b2e443544c 100644 --- a/libvips/create/mask_butterworth_band.c +++ b/libvips/create/mask_butterworth_band.c @@ -170,20 +170,20 @@ vips_mask_butterworth_band_init( * @amplitude_cutoff: amplitude threshold * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @nodc: don't set the DC pixel - * * @reject: invert the filter sense - * * @optical: coordinates in optical space - * * @uchar: output a uchar image - * * Make an butterworth band-pass or band-reject filter, that is, one with a * variable, smooth transition positioned at @frequency_cutoff_x, * @frequency_cutoff_y, of radius @radius. + * * The shape of the curve is controlled by * @order --- higher values give a sharper transition. See Gonzalez and Wintz, * Digital Image Processing, 1987. * + * ::: tip "Optional arguments" + * * @nodc: %gboolean, don't set the DC pixel + * * @reject: %gboolean, invert the filter sense + * * @optical: %gboolean, coordinates in optical space + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.mask_ideal]. * diff --git a/libvips/create/mask_butterworth_ring.c b/libvips/create/mask_butterworth_ring.c index 1b8d9d19cb..9372d456b4 100644 --- a/libvips/create/mask_butterworth_ring.c +++ b/libvips/create/mask_butterworth_ring.c @@ -128,21 +128,22 @@ vips_mask_butterworth_ring_init( * @ringwidth: ringwidth * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @nodc: don't set the DC pixel - * * @reject: invert the filter sense - * * @optical: coordinates in optical space - * * @uchar: output a uchar image - * * Make a butterworth ring-pass or ring-reject filter, that is, one with a * variable, * smooth transition * positioned at @frequency_cutoff of width @width, where @frequency_cutoff is - * in the range 0 - 1. The shape of the curve is controlled by + * in the range 0 - 1. + * + * The shape of the curve is controlled by * @order --- higher values give a sharper transition. See Gonzalez and Wintz, * Digital Image Processing, 1987. * + * ::: tip "Optional arguments" + * * @nodc: %gboolean, don't set the DC pixel + * * @reject: %gboolean, invert the filter sense + * * @optical: %gboolean, coordinates in optical space + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.mask_ideal]. * diff --git a/libvips/create/mask_fractal.c b/libvips/create/mask_fractal.c index 3a1c2aba0a..b0a48a1637 100644 --- a/libvips/create/mask_fractal.c +++ b/libvips/create/mask_fractal.c @@ -111,15 +111,16 @@ vips_mask_fractal_init(VipsMaskFractal *fractal) * @fractal_dimension: fractal dimension * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * This operation should be used to create fractal images by filtering the + * power spectrum of Gaussian white noise. * - * * @nodc: don't set the DC pixel - * * @reject: invert the filter sense - * * @optical: coordinates in optical space - * * @uchar: output a uchar image + * See [ctor@Image.gaussnoise]. * - * This operation should be used to create fractal images by filtering the - * power spectrum of Gaussian white noise. See [ctor@Image.gaussnoise]. + * ::: tip "Optional arguments" + * * @nodc: %gboolean, don't set the DC pixel + * * @reject: %gboolean, invert the filter sense + * * @optical: %gboolean, coordinates in optical space + * * @uchar: %gboolean, output a uchar image * * ::: seealso * [ctor@Image.mask_ideal]. diff --git a/libvips/create/mask_gaussian.c b/libvips/create/mask_gaussian.c index 535c5cbf48..d0c74898c3 100644 --- a/libvips/create/mask_gaussian.c +++ b/libvips/create/mask_gaussian.c @@ -113,16 +113,15 @@ vips_mask_gaussian_init(VipsMaskGaussian *gaussian) * @amplitude_cutoff: amplitude threshold * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @nodc: don't set the DC pixel - * * @reject: invert the filter sense - * * @optical: coordinates in optical space - * * @uchar: output a uchar image - * * Make a gaussian high- or low-pass filter, that is, one with a variable, * smooth transition positioned at @frequency_cutoff. * + * ::: tip "Optional arguments" + * * @nodc: %gboolean, don't set the DC pixel + * * @reject: %gboolean, invert the filter sense + * * @optical: %gboolean, coordinates in optical space + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.mask_ideal]. * diff --git a/libvips/create/mask_gaussian_band.c b/libvips/create/mask_gaussian_band.c index ee3e77cf83..6d3139b287 100644 --- a/libvips/create/mask_gaussian_band.c +++ b/libvips/create/mask_gaussian_band.c @@ -152,17 +152,16 @@ vips_mask_gaussian_band_init(VipsMaskGaussianBand *gaussian_band) * @amplitude_cutoff: amplitude threshold * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @nodc: don't set the DC pixel - * * @reject: invert the filter sense - * * @optical: coordinates in optical space - * * @uchar: output a uchar image - * * Make a gaussian band-pass or band-reject filter, that is, one with a * variable, smooth transition positioned at @frequency_cutoff_x, * @frequency_cutoff_y, of radius @radius. * + * ::: tip "Optional arguments" + * * @nodc: %gboolean, don't set the DC pixel + * * @reject: %gboolean, invert the filter sense + * * @optical: %gboolean, coordinates in optical space + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.mask_ideal]. * diff --git a/libvips/create/mask_gaussian_ring.c b/libvips/create/mask_gaussian_ring.c index 4f235f56c7..c665f620ee 100644 --- a/libvips/create/mask_gaussian_ring.c +++ b/libvips/create/mask_gaussian_ring.c @@ -121,17 +121,16 @@ vips_mask_gaussian_ring_init(VipsMaskGaussianRing *gaussian_ring) * @ringwidth: ringwidth * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @nodc: don't set the DC pixel - * * @reject: invert the filter sense - * * @optical: coordinates in optical space - * * @uchar: output a uchar image - * * Make a gaussian ring-pass or ring-reject filter, that is, one with a * variable, smooth transition positioned at @frequency_cutoff of width * @ringwidth. * + * ::: tip "Optional arguments" + * * @nodc: %gboolean, don't set the DC pixel + * * @reject: %gboolean, invert the filter sense + * * @optical: %gboolean, coordinates in optical space + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.mask_ideal]. * diff --git a/libvips/create/mask_ideal.c b/libvips/create/mask_ideal.c index af3dff6465..4815d41f97 100644 --- a/libvips/create/mask_ideal.c +++ b/libvips/create/mask_ideal.c @@ -102,13 +102,6 @@ vips_mask_ideal_init(VipsMaskIdeal *ideal) * @frequency_cutoff: threshold at which filter ends * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @nodc: don't set the DC pixel - * * @reject: invert the filter sense - * * @optical: coordinates in optical space - * * @uchar: output a uchar image - * * Make an ideal high- or low-pass filter, that is, one with a sharp cutoff * positioned at @frequency_cutoff, where @frequency_cutoff is in * the range 0 - 1. @@ -132,6 +125,12 @@ vips_mask_ideal_init(VipsMaskIdeal *ideal) * Set @uchar to output an 8-bit unsigned char image rather than a * float image. In this case, pixels are in the range [0 - 255]. * + * ::: tip "Optional arguments" + * * @nodc: %gboolean, don't set the DC pixel + * * @reject: %gboolean, invert the filter sense + * * @optical: %gboolean, coordinates in optical space + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.mask_ideal], [ctor@Image.mask_ideal_ring], * [ctor@Image.mask_ideal_band], [ctor@Image.mask_butterworth], diff --git a/libvips/create/mask_ideal_band.c b/libvips/create/mask_ideal_band.c index 5ff4cbe4e7..1b97a7f706 100644 --- a/libvips/create/mask_ideal_band.c +++ b/libvips/create/mask_ideal_band.c @@ -134,17 +134,16 @@ vips_mask_ideal_band_init(VipsMaskIdealBand *ideal_band) * @radius: size of band * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @nodc: don't set the DC pixel - * * @reject: invert the filter sense - * * @optical: coordinates in optical space - * * @uchar: output a uchar image - * * Make an ideal band-pass or band-reject filter, that is, one with a * sharp cutoff around the point @frequency_cutoff_x, @frequency_cutoff_y, * of size @radius. * + * ::: tip "Optional arguments" + * * @nodc: %gboolean, don't set the DC pixel + * * @reject: %gboolean, invert the filter sense + * * @optical: %gboolean, coordinates in optical space + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.mask_ideal]. * diff --git a/libvips/create/mask_ideal_ring.c b/libvips/create/mask_ideal_ring.c index 3f09864c68..3573802238 100644 --- a/libvips/create/mask_ideal_ring.c +++ b/libvips/create/mask_ideal_ring.c @@ -117,17 +117,16 @@ vips_mask_ideal_ring_init(VipsMaskIdealRing *ideal_ring) * @ringwidth: ring width * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @nodc: don't set the DC pixel - * * @reject: invert the filter sense - * * @optical: coordinates in optical space - * * @uchar: output a uchar image - * * Make an ideal ring-pass or ring-reject filter, that is, one with a sharp * ring positioned at @frequency_cutoff of width @width, where * @frequency_cutoff and @width are expressed as the range 0 - 1. * + * ::: tip "Optional arguments" + * * @nodc: %gboolean, don't set the DC pixel + * * @reject: %gboolean, invert the filter sense + * * @optical: %gboolean, coordinates in optical space + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.mask_ideal]. * diff --git a/libvips/create/perlin.c b/libvips/create/perlin.c index 5ca1a9c632..1a24f3eda9 100644 --- a/libvips/create/perlin.c +++ b/libvips/create/perlin.c @@ -341,12 +341,9 @@ vips_perlin_init(VipsPerlin *perlin) * @height: vertical size * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Create a one-band float image of Perlin noise. * - * * @cell_size: %gint, size of Perlin cells - * * @uchar: output a uchar image - * - * Create a one-band float image of Perlin noise. See: + * See: * * https://en.wikipedia.org/wiki/Perlin_noise * @@ -355,8 +352,12 @@ vips_perlin_init(VipsPerlin *perlin) * * If @width and @height are multiples of @cell_size, the image will tessellate. * - * Normally, output pixels are [enum@Vips.BandFormat.FLOAT] in the range [-1, +1]. Set - * @uchar to output a uchar image with pixels in [0, 255]. + * Normally, output pixels are [enum@Vips.BandFormat.FLOAT] in the range + * [-1, +1]. Set @uchar to output a uchar image with pixels in [0, 255]. + * + * ::: tip "Optional arguments" + * * @cell_size: %gint, size of Perlin cells + * * @uchar: %gboolean, output a uchar image * * ::: seealso * [ctor@Image.worley], [ctor@Image.fractsurf], [ctor@Image.gaussnoise]. diff --git a/libvips/create/sdf.c b/libvips/create/sdf.c index 6ff8048c07..e3fbbfd74f 100644 --- a/libvips/create/sdf.c +++ b/libvips/create/sdf.c @@ -365,27 +365,28 @@ vips_sdf_init(VipsSdf *sdf) * @shape: SDF to create * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Create a signed distance field (SDF) image of the given @shape. * - * * @a: [struct@ArrayDouble], first point - * * @b: [struct@ArrayDouble], second point - * * @r: %gfloat, radius - * * @corners: [struct@ArrayDouble], corner radii - * - * Create a signed distance field (SDF) image of the given shape. Different + * Different * shapes use different combinations of the optional arguments, see below. * - * @shape #VIPS_SDF_SHAPE_CIRCLE: create a circle centred on @a, radius @r. + * @shape [enum@Vips.SdfShape.CIRCLE]: create a circle centred on @a, radius @r. * - * @shape #VIPS_SDF_SHAPE_BOX: create a box with top-left corner @a and + * @shape [enum@Vips.SdfShape.BOX]: create a box with top-left corner @a and * bottom-right corner @b. * - * @shape #VIPS_SDF_SHAPE_ROUNDED_BOX: create a box with top-left corner @a + * @shape [enum@Vips.SdfShape.ROUNDED_BOX]: create a box with top-left corner @a * and bottom-right corner @b, whose four corners are * rounded by the four-element float array @corners. @corners will default to * 0.0. * - * @shape #VIPS_SDF_SHAPE_LINE: draw a line from @a to @b. + * @shape [enum@Vips.SdfShape.LINE]: draw a line from @a to @b. + * + * ::: tip "Optional arguments" + * * @a: [struct@ArrayDouble], first point + * * @b: [struct@ArrayDouble], second point + * * @r: %gfloat, radius + * * @corners: [struct@ArrayDouble], corner radii * * ::: seealso * [ctor@Image.grey], [method@Image.grid], [ctor@Image.xyz]. diff --git a/libvips/create/sines.c b/libvips/create/sines.c index 489bcf8b24..f7c3fb9e8e 100644 --- a/libvips/create/sines.c +++ b/libvips/create/sines.c @@ -153,12 +153,6 @@ vips_sines_init(VipsSines *sines) * @height: image size * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @hfreq: horizontal frequency - * * @vreq: vertical frequency - * * @uchar: output a uchar image - * * Creates a float one band image of the a sine waveform in two * dimensions. * @@ -172,6 +166,11 @@ vips_sines_init(VipsSines *sines) * * Pixels are normally in [-1, +1], set @uchar to output [0, 255]. * + * ::: tip "Optional arguments" + * * @hfreq: %gdouble, horizontal frequency + * * @vreq: %gdouble, vertical frequency + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.grey], [ctor@Image.xyz]. * diff --git a/libvips/create/text.c b/libvips/create/text.c index 2d6ba23b9b..51ec614c44 100644 --- a/libvips/create/text.c +++ b/libvips/create/text.c @@ -656,21 +656,9 @@ vips_text_init(VipsText *text) * @text: utf-8 text string to render * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Draw the string @text to an image. * - * * @font: %gchararray, font to render with - * * @fontfile: %gchararray, load this font file - * * @width: %gint, image should be no wider than this many pixels - * * @height: %gint, image should be no higher than this many pixels - * * @align: #VipsAlign, set justification alignment - * * @justify: %gboolean, justify lines - * * @dpi: %gint, render at this resolution - * * @autofit_dpi: %gint, read out auto-fitted DPI - * * @rgba: %gboolean, enable RGBA output - * * @spacing: %gint, space lines by this in points - * * @wrap: #VipsTextWrap, wrap lines on characters or words - * - * Draw the string @text to an image. @out is normally a one-band 8-bit + * @out is normally a one-band 8-bit * unsigned char image, with 0 for no text and 255 for text. Values between * are used for anti-aliasing. * @@ -715,6 +703,19 @@ vips_text_init(VipsText *text) * / `Yoffset`. This can be helpful if you need to line up the output of * several [ctor@Image.text]. * + * ::: tip "Optional arguments" + * * @font: %gchararray, font to render with + * * @fontfile: %gchararray, load this font file + * * @width: %gint, image should be no wider than this many pixels + * * @height: %gint, image should be no higher than this many pixels + * * @align: #VipsAlign, set justification alignment + * * @justify: %gboolean, justify lines + * * @dpi: %gint, render at this resolution + * * @autofit_dpi: %gint, read out auto-fitted DPI + * * @rgba: %gboolean, enable RGBA output + * * @spacing: %gint, space lines by this in points + * * @wrap: #VipsTextWrap, wrap lines on characters or words + * * ::: seealso * [func@Image.bandjoin], [func@Image.composite]. * diff --git a/libvips/create/tonelut.c b/libvips/create/tonelut.c index e3e666f036..281ea225c4 100644 --- a/libvips/create/tonelut.c +++ b/libvips/create/tonelut.c @@ -312,21 +312,10 @@ vips_tonelut_init(VipsTonelut *lut) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @in_max: input range - * * @out_max: output range - * * @Lb: black-point [0-100] - * * @Lw: white-point [0-100] - * * @Ps: shadow point (eg. 0.2) - * * @Pm: mid-tone point (eg. 0.5) - * * @Ph: highlight point (eg. 0.8) - * * @S: shadow adjustment (+/- 30) - * * @M: mid-tone adjustment (+/- 30) - * * @H: highlight adjustment (+/- 30) - * * [ctor@Image.tonelut] generates a tone curve for the adjustment of image - * levels. It is mostly designed for adjusting the L* part of a LAB image in + * levels. + * + * This is mostly designed for adjusting the L* part of a LAB image in * a way suitable for print work, but you can use it for other things too. * * The curve is an unsigned 16-bit image with (@in_max + 1) entries, @@ -336,6 +325,18 @@ vips_tonelut_init(VipsTonelut *lut) * specify the scaling for the input and output images with the @in_max and * @out_max parameters. * + * ::: tip "Optional arguments" + * * @in_max: %gint, input range + * * @out_max: %gint, output range + * * @Lb: %gdouble, black-point [0-100] + * * @Lw: %gdouble, white-point [0-100] + * * @Ps: %gdouble, shadow point (eg. 0.2) + * * @Pm: %gdouble, mid-tone point (eg. 0.5) + * * @Ph: %gdouble, highlight point (eg. 0.8) + * * @S: %gdouble, shadow adjustment (+/- 30) + * * @M: %gdouble, mid-tone adjustment (+/- 30) + * * @H: %gdouble, highlight adjustment (+/- 30) + * * Returns: 0 on success, -1 on error */ int diff --git a/libvips/create/worley.c b/libvips/create/worley.c index 0834f96776..0442b60964 100644 --- a/libvips/create/worley.c +++ b/libvips/create/worley.c @@ -347,11 +347,9 @@ vips_worley_init(VipsWorley *worley) * @height: vertical size * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Create a one-band float image of Worley noise. * - * * @cell_size: %gint, size of Worley cells - * - * Create a one-band float image of Worley noise. See: + * See: * * https://en.wikipedia.org/wiki/Worley_noise * @@ -360,6 +358,9 @@ vips_worley_init(VipsWorley *worley) * * If @width and @height are multiples of @cell_size, the image will tessellate. * + * ::: tip "Optional arguments" + * * @cell_size: %gint, size of Worley cells + * * ::: seealso * [ctor@Image.perlin], [ctor@Image.fractsurf], [ctor@Image.gaussnoise]. * diff --git a/libvips/create/xyz.c b/libvips/create/xyz.c index 528f95bda0..f647fc414b 100644 --- a/libvips/create/xyz.c +++ b/libvips/create/xyz.c @@ -241,12 +241,6 @@ vips_xyz_init(VipsXyz *xyz) * @height: vertical size * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @csize: %gint, size for third dimension - * * @dsize: %gint, size for fourth dimension - * * @esize: %gint, size for fifth dimension - * * Create a two-band uint32 image where the elements in the first band have the * value of their x coordinate and elements in the second band have their y * coordinate. @@ -258,6 +252,11 @@ vips_xyz_init(VipsXyz *xyz) * bands. The extra dimensions are placed down the vertical axis. Use * [method@Image.grid] to change the layout. * + * ::: tip "Optional arguments" + * * @csize: %gint, size for third dimension + * * @dsize: %gint, size for fourth dimension + * * @esize: %gint, size for fifth dimension + * * ::: seealso * [ctor@Image.grey], [method@Image.grid], [ctor@Image.identity]. * diff --git a/libvips/create/zone.c b/libvips/create/zone.c index f943a7d248..e2aa6653f6 100644 --- a/libvips/create/zone.c +++ b/libvips/create/zone.c @@ -104,14 +104,13 @@ vips_zone_init(VipsZone *zone) * @height: image size * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @uchar: output a uchar image - * * Create a one-band image of a zone plate. * * Pixels are normally in [-1, +1], set @uchar to output [0, 255]. * + * ::: tip "Optional arguments" + * * @uchar: %gboolean, output a uchar image + * * ::: seealso * [ctor@Image.eye], [ctor@Image.xyz]. * From b7cc42c423e1adb4a0340b5462122ef7f5908221 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 23 Apr 2025 08:43:25 +0100 Subject: [PATCH 134/174] try to fix a compiler warning on ubuntu 25.04 beta --- libvips/conversion/composite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvips/conversion/composite.cpp b/libvips/conversion/composite.cpp index bf0e87bd74..a2bae42fc8 100644 --- a/libvips/conversion/composite.cpp +++ b/libvips/conversion/composite.cpp @@ -958,7 +958,7 @@ vips_combine_pixels(VipsCompositeSequence *seq, VipsPel *q) T *restrict tq = (T *restrict) q; T **restrict tp = (T * *restrict) seq->p; - double B[MAX_BANDS + 1]; + double B[MAX_BANDS + 1] = { 0.0 }; double aB; /* Load and scale the base pixel to 0 - 1. From b3882e01c6689218ea645fff3d0fa46391f424ae Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 23 Apr 2025 10:13:25 +0100 Subject: [PATCH 135/174] revise doc comments in draw --- doc/rename.sed | 2 ++ libvips/draw/draw.c | 7 +++--- libvips/draw/draw_circle.c | 22 +++++++++-------- libvips/draw/draw_flood.c | 48 ++++++++++++++++++++------------------ libvips/draw/draw_image.c | 16 +++++++------ libvips/draw/draw_line.c | 8 ++++--- libvips/draw/draw_mask.c | 12 ++++++---- libvips/draw/draw_rect.c | 31 +++++++++++++----------- libvips/draw/draw_smudge.c | 3 ++- 9 files changed, 83 insertions(+), 66 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index fb5c70a87f..156e65c33d 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -409,6 +409,7 @@ s/vips_\(zoom\)()/[method@Image.\1]/g s/vips_\([^(]*\)()/[func@\1]/g s/#Vips\(SdfShape\)/[enum@\1]/g +s/#Vips\(CombineMode\)/[enum@\1]/g s/#Vips\(Access\)/[enum@\1]/g s/#Vips\(BandFormat\)/[enum@\1]/g s/#Vips\(Interpretation\)/[enum@\1]/g @@ -445,6 +446,7 @@ s/#Vips\(ThreadpoolAllocateFn\)/[callback@\1]/g s/#Vips\(ThreadpoolWorkFn\)/[callback@\1]/g s/#Vips\(ThreadpoolProgressFn\)/[callback@\1]/g +s/#VIPS_COMBINE_MODE_\([^ ,.]*\)/[enum@Vips.CombineMode.\1]/g s/#VIPS_SDF_SHAPE_\([^ ,.]*\)/[enum@Vips.SdfShape.\1]/g s/#VIPS_OPERATION_MATH_\([^ ,.]*\)/[enum@Vips.OperationMath.\1]/g s/#VIPS_OPERATION_MATH2_\([^ ,.]*\)/[enum@Vips.OperationMath2.\1]/g diff --git a/libvips/draw/draw.c b/libvips/draw/draw.c index 201e34ce56..8dc1127efa 100644 --- a/libvips/draw/draw.c +++ b/libvips/draw/draw.c @@ -50,12 +50,13 @@ * @VIPS_COMBINE_MODE_SET: set pixels to the new value * @VIPS_COMBINE_MODE_ADD: add pixels * - * See vips_draw_image() and so on. + * See [method@Image.draw_image] and so on. * - * Operations like vips_draw_image() need to be told how to combine images + * Operations like [method@Image.draw_image] need to be told how to combine images * from two sources. * - * See also: vips_join(). + * ::: seealso + * [method@Image.join]. */ G_DEFINE_ABSTRACT_TYPE(VipsDraw, vips_draw, VIPS_TYPE_OPERATION); diff --git a/libvips/draw/draw_circle.c b/libvips/draw/draw_circle.c index d319512e33..da2649c99d 100644 --- a/libvips/draw/draw_circle.c +++ b/libvips/draw/draw_circle.c @@ -290,16 +290,18 @@ vips_draw_circlev(VipsImage *image, * @radius: draw_circle radius * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Draws a circle on @image. * - * * @fill: fill the draw_circle - * - * Draws a circle on @image. If @fill is %TRUE then the circle is filled, + * If @fill is %TRUE then the circle is filled, * otherwise a 1-pixel-wide perimeter is drawn. * * @ink is an array of double containing values to draw. * - * See also: vips_draw_circle1(), vips_draw_line(). + * ::: tip "Optional arguments" + * * @fill: %gboolean, fill the draw_circle + * + * ::: seealso + * [method@Image.draw_circle1], [method@Image.draw_line]. * * Returns: 0 on success, or -1 on error. */ @@ -326,13 +328,13 @@ vips_draw_circle(VipsImage *image, * @radius: draw_circle radius * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @fill: fill the draw_circle + * As [method@Image.draw_circle], but just takes a single double for @ink. * - * As vips_draw_circle(), but just takes a single double for @ink. + * ::: tip "Optional arguments" + * * @fill: %gboolean, fill the draw_circle * - * See also: vips_draw_circle(). + * ::: seealso + * [method@Image.draw_circle]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/draw/draw_flood.c b/libvips/draw/draw_flood.c index 6717635327..02be8ffb17 100644 --- a/libvips/draw/draw_flood.c +++ b/libvips/draw/draw_flood.c @@ -103,8 +103,8 @@ typedef struct _Buffer { } Buffer; /* What we track during a flood. We have this in a separate struct so that we - * can support vips__draw_flood_direct() ... a fast path for - * vips_labelregions() that avoids all of the GObject call overhead. This + * can support [func@_draw_flood_direct] ... a fast path for + * [method@Image.labelregions] that avoids all of the GObject call overhead. This * gives a huge speedup, >x10 in many cases. */ typedef struct _Flood { @@ -623,7 +623,7 @@ vips_draw_flood_init(VipsDrawFlood *draw_flood) { } -/* Direct path to flood for vips_labelregions(). We need to avoid the function +/* Direct path to flood for [method@Image.labelregions]. We need to avoid the function * dispatch system for speed. * * Equivalent to: @@ -696,16 +696,9 @@ vips_draw_floodv(VipsImage *image, * @y: centre of circle * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Flood-fill @image with @ink, starting at position @x, @y. * - * * @test: test this image - * * @equal: fill while equal to edge - * * @left: output left edge of bounding box of modified area - * * @top: output top edge of bounding box of modified area - * * @width: output width of bounding box of modified area - * * @height: output height of bounding box of modified area - * - * Flood-fill @image with @ink, starting at position @x, @y. The filled area is + * The filled area is * bounded by pixels that are equal to the ink colour, in other words, it * searches for pixels enclosed by an edge of @ink. * @@ -719,9 +712,18 @@ vips_draw_floodv(VipsImage *image, * @left, @top, @width, @height output the bounding box of the modified * pixels. * + * ::: tip "Optional arguments" + * * @test: [class@Image], test this image + * * @equal: %gboolean, fill while equal to edge + * * @left: %gint, output left edge of bounding box of modified area + * * @top: %gint, output top edge of bounding box of modified area + * * @width: %gint, output width of bounding box of modified area + * * @height: %gint, output height of bounding box of modified area + * * @ink is an array of double containing values to draw. * - * See also: vips_draw_flood1(). + * ::: seealso + * [method@Image.draw_flood1]. * * Returns: 0 on success, or -1 on error. */ @@ -747,18 +749,18 @@ vips_draw_flood(VipsImage *image, * @y: centre of circle * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @test: test this image - * * @equal: fill while equal to edge - * * @left: output left edge of bounding box of modified area - * * @top: output top edge of bounding box of modified area - * * @width: output width of bounding box of modified area - * * @height: output height of bounding box of modified area + * As [method@Image.draw_flood], but just takes a single double for @ink. * - * As vips_draw_flood(), but just takes a single double for @ink. + * ::: tip "Optional arguments" + * * @test: [class@Image], test this image + * * @equal: %gboolean, fill while equal to edge + * * @left: %gint, output left edge of bounding box of modified area + * * @top: %gint, output top edge of bounding box of modified area + * * @width: %gint, output width of bounding box of modified area + * * @height: %gint, output height of bounding box of modified area * - * See also: vips_draw_flood(). + * ::: seealso + * [method@Image.draw_flood]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/draw/draw_image.c b/libvips/draw/draw_image.c index 00c73d5668..852cd07714 100644 --- a/libvips/draw/draw_image.c +++ b/libvips/draw/draw_image.c @@ -307,19 +307,21 @@ vips_draw_image_init(VipsDrawImage *draw_image) * @y: draw @sub here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Draw @sub on top of @image at position @x, @y. * - * * @mode: how to combine pixels - * - * Draw @sub on top of @image at position @x, @y. The two images must have the + * The two images must have the * same Coding. If @sub has 1 band, the bands will be duplicated to match the * number of bands in @image. @sub will be converted to @image's format, see - * vips_cast(). + * [method@Image.cast]. * * Use @mode to set how pixels are combined. If you use - * #VIPS_COMBINE_MODE_ADD, both images muct be uncoded. + * [enum@Vips.CombineMode.ADD], both images must be uncoded. + * + * ::: tip "Optional arguments" + * * @mode: [enum@CombineMode], how to combine pixels * - * See also: vips_draw_mask(), vips_insert(). + * ::: seealso + * [method@Image.draw_mask], [method@Image.insert]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/draw/draw_line.c b/libvips/draw/draw_line.c index df1c7a669c..673cac6f1f 100644 --- a/libvips/draw/draw_line.c +++ b/libvips/draw/draw_line.c @@ -344,7 +344,8 @@ vips_draw_linev(VipsImage *image, * * @ink is an array of double containing values to draw. * - * See also: vips_draw_line1(), vips_draw_circle(), vips_draw_mask(). + * ::: seealso + * [method@Image.draw_line1], [method@Image.draw_circle], [method@Image.draw_mask]. * * Returns: 0 on success, or -1 on error. */ @@ -372,9 +373,10 @@ vips_draw_line(VipsImage *image, * @y2: end of draw_line * @...: %NULL-terminated list of optional named arguments * - * As vips_draw_line(), but just take a single double for @ink. + * As [method@Image.draw_line], but just take a single double for @ink. * - * See also: vips_draw_line(). + * ::: seealso + * [method@Image.draw_line]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/draw/draw_mask.c b/libvips/draw/draw_mask.c index 98b6e8c81e..b6401fddd2 100644 --- a/libvips/draw/draw_mask.c +++ b/libvips/draw/draw_mask.c @@ -381,12 +381,13 @@ vips_draw_maskv(VipsImage *image, * * Draw @mask on the image. @mask is a monochrome 8-bit image with 0/255 * for transparent or @ink coloured points. Intermediate values blend the ink - * with the pixel. Use with vips_text() to draw text on an image. Use in a - * vips_draw_line() subclass to draw an object along a line. + * with the pixel. Use with [ctor@Image.text] to draw text on an image. Use in a + * [method@Image.draw_line] subclass to draw an object along a line. * * @ink is an array of double containing values to draw. * - * See also: vips_text(), vips_draw_line(). + * ::: seealso + * [ctor@Image.text], [method@Image.draw_line]. * * Returns: 0 on success, or -1 on error. */ @@ -413,9 +414,10 @@ vips_draw_mask(VipsImage *image, * @y: draw mask here * @...: %NULL-terminated list of optional named arguments * - * As vips_draw_mask(), but just takes a single double for @ink. + * As [method@Image.draw_mask], but just takes a single double for @ink. * - * See also: vips_draw_mask(). + * ::: seealso + * [method@Image.draw_mask]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/draw/draw_rect.c b/libvips/draw/draw_rect.c index f6af4ac08b..49e8c45def 100644 --- a/libvips/draw/draw_rect.c +++ b/libvips/draw/draw_rect.c @@ -237,14 +237,15 @@ vips_draw_rectv(VipsImage *image, * @height: area to paint * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Paint pixels within @left, @top, @width, @height in @image with @ink. * - * * @fill: fill the rect + * If @fill is zero, just paint a 1-pixel-wide outline. * - * Paint pixels within @left, @top, @width, @height in @image with @ink. If - * @fill is zero, just paint a 1-pixel-wide outline. + * ::: tip "Optional arguments" + * * @fill: %gboolean, fill the rect * - * See also: vips_draw_circle(). + * ::: seealso + * [method@Image.draw_circle]. * * Returns: 0 on success, or -1 on error. */ @@ -273,13 +274,13 @@ vips_draw_rect(VipsImage *image, * @height: area to paint * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * As [method@Image.draw_rect], but just take a single double for @ink. * - * * @fill: fill the rect + * ::: tip "Optional arguments" + * * @fill: %gboolean, fill the rect * - * As vips_draw_rect(), but just take a single double for @ink. - * - * See also: vips_draw_rect(). + * ::: seealso + * [method@Image.draw_rect]. * * Returns: 0 on success, or -1 on error. */ @@ -310,9 +311,10 @@ vips_draw_rect1(VipsImage *image, * @y: point to paint * @...: %NULL-terminated list of optional named arguments * - * As vips_draw_rect(), but draw a single pixel at @x, @y. + * As [method@Image.draw_rect], but draw a single pixel at @x, @y. * - * See also: vips_draw_rect(). + * ::: seealso + * [method@Image.draw_rect]. * * Returns: 0 on success, or -1 on error. */ @@ -337,9 +339,10 @@ vips_draw_point(VipsImage *image, double *ink, int n, int x, int y, ...) * @y: point to draw * @...: %NULL-terminated list of optional named arguments * - * As vips_draw_point(), but just take a single double for @ink. + * As [method@Image.draw_point], but just take a single double for @ink. * - * See also: vips_draw_point(). + * ::: seealso + * [method@Image.draw_point]. * * Returns: 0 on success, or -1 on error. */ diff --git a/libvips/draw/draw_smudge.c b/libvips/draw/draw_smudge.c index fb36269ea5..72a847df6b 100644 --- a/libvips/draw/draw_smudge.c +++ b/libvips/draw/draw_smudge.c @@ -257,7 +257,8 @@ vips_draw_smudge_init(VipsDrawSmudge *draw_smudge) * Smudge a section of @image. Each pixel in the area @left, @top, @width, * @height is replaced by the average of the surrounding 3x3 pixels. * - * See also: vips_draw_line(). + * ::: seealso + * [method@Image.draw_line]. * * Returns: 0 on success, or -1 on error. */ From f44fb49c3da0b063855a607e99b53ae0e24acb2d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 25 Apr 2025 13:00:49 +0100 Subject: [PATCH 136/174] fix some line breaks --- libvips/conversion/flatten.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libvips/conversion/flatten.c b/libvips/conversion/flatten.c index 1efbb59fb5..ae07b51915 100644 --- a/libvips/conversion/flatten.c +++ b/libvips/conversion/flatten.c @@ -336,8 +336,7 @@ vips_flatten_build(VipsObject *object) */ original_format = VIPS_FORMAT_NOTSET; if (vips_band_format_isint(in->BandFmt) && - flatten->max_alpha < - vips_image_get_format_max(in->BandFmt)) { + flatten->max_alpha < vips_image_get_format_max(in->BandFmt)) { original_format = in->BandFmt; if (vips_cast(in, &t[1], VIPS_FORMAT_DOUBLE, NULL)) return -1; @@ -345,8 +344,7 @@ vips_flatten_build(VipsObject *object) } t[2] = vips_image_new(); - if (vips_image_pipelinev(t[2], - VIPS_DEMAND_STYLE_THINSTRIP, in, NULL)) + if (vips_image_pipelinev(t[2], VIPS_DEMAND_STYLE_THINSTRIP, in, NULL)) return -1; t[2]->Bands -= 1; @@ -379,8 +377,7 @@ vips_flatten_build(VipsObject *object) return -1; if (vips_image_generate(t[2], - vips_start_one, vips_flatten_gen, vips_stop_one, - in, flatten)) + vips_start_one, vips_flatten_gen, vips_stop_one, in, flatten)) return -1; in = t[2]; } From 57baedd2195a4d6c446788efcc8ca05fc9ea0b49 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 25 Apr 2025 18:21:25 +0100 Subject: [PATCH 137/174] revise doc comments in foreign --- doc/rename.sed | 34 ++++ libvips/foreign/analyzeload.c | 3 +- libvips/foreign/cgifsave.c | 91 +++++----- libvips/foreign/csvload.c | 40 +++-- libvips/foreign/csvsave.c | 21 +-- libvips/foreign/dzsave.c | 129 ++++++------- libvips/foreign/fitsload.c | 5 +- libvips/foreign/fitssave.c | 3 +- libvips/foreign/foreign.c | 328 +++++++++++++++++----------------- libvips/foreign/heifsave.c | 2 +- libvips/foreign/jp2kload.c | 42 ++--- libvips/foreign/jp2ksave.c | 55 +++--- libvips/foreign/jpeg2vips.c | 26 +-- libvips/foreign/jpegload.c | 63 +++---- libvips/foreign/jpegsave.c | 118 ++++++------ libvips/foreign/jxlload.c | 6 +- libvips/foreign/jxlsave.c | 6 +- libvips/foreign/magick6load.c | 2 +- libvips/foreign/magickload.c | 39 ++-- libvips/foreign/magicksave.c | 48 ++--- libvips/foreign/matload.c | 3 +- libvips/foreign/matrixload.c | 8 +- libvips/foreign/matrixsave.c | 15 +- libvips/foreign/niftiload.c | 5 +- libvips/foreign/niftisave.c | 3 +- libvips/foreign/nsgifload.c | 48 ++--- libvips/foreign/openexrload.c | 3 +- libvips/foreign/pngload.c | 40 ++--- libvips/foreign/pngsave.c | 78 ++++---- libvips/foreign/ppmload.c | 8 +- libvips/foreign/ppmsave.c | 30 ++-- libvips/foreign/quantise.c | 6 +- libvips/foreign/quantise.h | 2 +- libvips/foreign/radload.c | 21 ++- libvips/foreign/radsave.c | 15 +- libvips/foreign/rawload.c | 18 +- libvips/foreign/rawsave.c | 15 +- libvips/foreign/svgload.c | 62 +++---- libvips/foreign/tiffload.c | 74 ++++---- libvips/foreign/tiffsave.c | 152 ++++++++-------- libvips/foreign/vips2jpeg.c | 2 +- libvips/foreign/vipsload.c | 5 +- libvips/foreign/vipssave.c | 5 +- libvips/foreign/webpload.c | 48 ++--- libvips/foreign/webpsave.c | 156 ++++++++-------- 45 files changed, 988 insertions(+), 895 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index 156e65c33d..a0fab00ddf 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -1,3 +1,11 @@ +s/vips_\(amiMSBfirst\)/apple_\1_apple/g +s/vips_\(error_freeze\)/apple_\1_apple/g +s/vips_\(error_thaw\)/apple_\1_apple/g +s/vips_\(error_buffer\)/apple_\1_apple/g +s/vips_\(image_new\)/apple_\1_apple/g +s/vips_\(target_new_to_memory\)/apple_\1_apple/g +s/vips_\(.*\)_get_type/apple_\1_get_type_apple/g + s/See also: \([^.]\)/::: seealso\n * \1/g s/#VipsImage::\(width\)/[property@Image:\1]/g @@ -163,6 +171,8 @@ s/vips_\(falsecolour\)()/[method@Image.\1]/g s/vips_\(fastcor\)()/[method@Image.\1]/g s/vips_\(fill_nearest\)()/[method@Image.\1]/g s/vips_\(find_trim\)()/[method@Image.\1]/g +s/vips_\(vipsload\)()/[ctor@Image.\1]/g +s/vips_\(radload\)()/[ctor@Image.\1]/g s/vips_\(fitsload\)()/[ctor@Image.\1]/g s/vips_\(fitsload_source\)()/[ctor@Image.\1]/g s/vips_\(fitssave\)()/[method@Image.\1]/g @@ -253,6 +263,15 @@ s/vips_\(log\)()/[method@Image.\1]/g s/vips_\(lshift_const1\)()/[method@Image.\1]/g s/vips_\(lshift_const\)()/[method@Image.\1]/g s/vips_\(lshift\)()/[method@Image.\1]/g +s/vips_\(pngload\)()/[ctor@Image.\1]/g +s/vips_\(ppmload\)()/[ctor@Image.\1]/g +s/vips_\(openslideload\)()/[ctor@Image.\1]/g +s/vips_\(tiffload\)()/[ctor@Image.\1]/g +s/vips_\(gifload\)()/[ctor@Image.\1]/g +s/vips_\(niftiload\)()/[ctor@Image.\1]/g +s/vips_\(matrixload\)()/[ctor@Image.\1]/g +s/vips_\(svgload\)()/[ctor@Image.\1]/g +s/vips_\(magickload\)()/[ctor@Image.\1]/g s/vips_\(magicksave_buffer\)()/[method@Image.\1]/g s/vips_\(magicksave\)()/[method@Image.\1]/g s/vips_\(mapim\)()/[method@Image.\1]/g @@ -390,6 +409,11 @@ s/vips_\(transpose3d\)()/[method@Image.\1]/g s/vips_\(unpremultiply\)()/[method@Image.\1]/g s/vips_\(vipssave\)()/[method@Image.\1]/g s/vips_\(vipssave_target\)()/[method@Image.\1]/g +s/vips_\(jpegload\)()/[ctor@Image.\1]/g +s/vips_\(jpegload_buffer\)()/[ctor@Image.\1]/g +s/vips_\(heifload\)()/[ctor@Image.\1]/g +s/vips_\(csvload\)()/[ctor@Image.\1]/g +s/vips_\(webpload\)()/[ctor@Image.\1]/g s/vips_\(webpsave_buffer\)()/[method@Image.\1]/g s/vips_\(webpsave\)()/[method@Image.\1]/g s/vips_\(webpsave_mime\)()/[method@Image.\1]/g @@ -411,12 +435,20 @@ s/vips_\([^(]*\)()/[func@\1]/g s/#Vips\(SdfShape\)/[enum@\1]/g s/#Vips\(CombineMode\)/[enum@\1]/g s/#Vips\(Access\)/[enum@\1]/g +s/#Vips\(RegionShrink\)/[enum@\1]/g s/#Vips\(BandFormat\)/[enum@\1]/g s/#Vips\(Interpretation\)/[enum@\1]/g s/#Vips\(Coding\)/[enum@\1]/g s/#Vips\(DemandStyle\)/[enum@\1]/g s/#Vips\(Precision\)/[enum@\1]/g s/#Vips\(ArgumentFlags\)/[flags@\1]/g +s/#Vips\(ForeignPngFilter\)/[flags@\1]/g +s/#Vips\(ForeignPpmFormat\)/[enum@\1]/g +s/#Vips\(ForeignTiffCompression\)/[enum@\1]/g +s/#Vips\(ForeignTiffPredictor\)/[enum@\1]/g +s/#Vips\(ForeignTiffResUnit\)/[enum@\1]/g +s/#Vips\(ForeignDzDepth\)/[enum@\1]/g +s/#Vips\(ForeignWebpPreset\)/[enum@\1]/g s/#Vips\(Rect\)/[struct@\1]/g s/#Vips\(Progress\)/[struct@\1]/g @@ -464,6 +496,8 @@ s/#VIPS_INTERPRETATION_\([^ ,.]*\)/[enum@Vips.Interpretation.\1]/g s/#VIPS_ACCESS_\([^ ,.]*\)/[enum@Vips.Access.\1]/g s/#VIPS_CODING_\([^ ,.]*\)/[enum@Vips.Coding.\1]/g +s/apple_\(.*\)_apple/vips_\1/g + s/g_\(assert_not_reached\)/banana_\1_banana/g s/g_thread_\([^(]*new\)()/[ctor@GLib.Thread.\1]/g diff --git a/libvips/foreign/analyzeload.c b/libvips/foreign/analyzeload.c index baa4b7b587..e6f4691ad1 100644 --- a/libvips/foreign/analyzeload.c +++ b/libvips/foreign/analyzeload.c @@ -166,7 +166,8 @@ vips_foreign_load_analyze_init(VipsForeignLoadAnalyze *analyze) * loaded lazilly and byte-swapped, if necessary. The Analyze metadata is read * and attached. * - * See also: vips_image_new_from_file(). + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/cgifsave.c b/libvips/foreign/cgifsave.c index fe7a96626c..fa2d03e2bb 100644 --- a/libvips/foreign/cgifsave.c +++ b/libvips/foreign/cgifsave.c @@ -1134,19 +1134,6 @@ vips_foreign_save_cgif_buffer_init(VipsForeignSaveCgifBuffer *buffer) * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @dither: %gdouble, quantisation dithering level - * * @effort: %gint, quantisation CPU effort - * * @bitdepth: %gint, number of bits per pixel - * * @interframe_maxerror: %gdouble, maximum inter-frame error for transparency - * * @reuse: %gboolean, reuse palette from input - * * @interlace: %gboolean, write an interlaced (progressive) GIF - * * @interpalette_maxerror: %gdouble, maximum inter-palette error for palette - * reusage - * * @keep_duplicate_frames: %boolean, keep duplicate frames in the output - * instead of combining them - * * Write to a file in GIF format. * * Use @dither to set the degree of Floyd-Steinberg dithering @@ -1177,7 +1164,21 @@ vips_foreign_save_cgif_buffer_init(VipsForeignSaveCgifBuffer *buffer) * If @keep_duplicate_frames is TRUE, duplicate frames in the input will be * kept in the output instead of combining them. * - * See also: vips_image_new_from_file(). + * ::: tip "Optional arguments" + * * @dither: %gdouble, quantisation dithering level + * * @effort: %gint, quantisation CPU effort + * * @bitdepth: %gint, number of bits per pixel + * * @interframe_maxerror: %gdouble, maximum inter-frame error for + * transparency + * * @reuse: %gboolean, reuse palette from input + * * @interlace: %gboolean, write an interlaced (progressive) GIF + * * @interpalette_maxerror: %gdouble, maximum inter-palette error for + * palette * reusage + * * @keep_duplicate_frames: %boolean, keep duplicate frames in the output + * instead of combining them + * + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -1201,26 +1202,27 @@ vips_gifsave(VipsImage *in, const char *filename, ...) * @len: (type gsize): return output length here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @dither: %gdouble, quantisation dithering level - * * @effort: %gint, quantisation CPU effort - * * @bitdepth: %gint, number of bits per pixel - * * @interframe_maxerror: %gdouble, maximum inter-frame error for transparency - * * @reuse: %gboolean, reuse palette from input - * * @interlace: %gboolean, write an interlaced (progressive) GIF - * * @interpalette_maxerror: %gdouble, maximum inter-palette error for palette - * reusage - * * @keep_duplicate_frames: %boolean, keep duplicate frames in the output - * instead of combining them - * - * As vips_gifsave(), but save to a memory buffer. + * As [method@Image.gifsave], but save to a memory buffer. * * The address of the buffer is returned in @buf, the length of the buffer in - * @len. You are responsible for freeing the buffer with g_free() when you + * @len. You are responsible for freeing the buffer with [func@GLib.free] when you * are done with it. * - * See also: vips_gifsave(), vips_image_write_to_file(). + * ::: tip "Optional arguments" + * * @dither: %gdouble, quantisation dithering level + * * @effort: %gint, quantisation CPU effort + * * @bitdepth: %gint, number of bits per pixel + * * @interframe_maxerror: %gdouble, maximum inter-frame error for + * transparency + * * @reuse: %gboolean, reuse palette from input + * * @interlace: %gboolean, write an interlaced (progressive) GIF + * * @interpalette_maxerror: %gdouble, maximum inter-palette error for + * palette * reusage + * * @keep_duplicate_frames: %boolean, keep duplicate frames in the output + * instead of combining them + * + * ::: seealso + * [method@Image.gifsave], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -1258,22 +1260,23 @@ vips_gifsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @dither: %gdouble, quantisation dithering level - * * @effort: %gint, quantisation CPU effort - * * @bitdepth: %gint, number of bits per pixel - * * @interframe_maxerror: %gdouble, maximum inter-frame error for transparency - * * @reuse: %gboolean, reuse palette from input - * * @interlace: %gboolean, write an interlaced (progressive) GIF - * * @interpalette_maxerror: %gdouble, maximum inter-palette error for palette - * reusage - * * @keep_duplicate_frames: %boolean, keep duplicate frames in the output - * instead of combining them + * As [method@Image.gifsave], but save to a target. * - * As vips_gifsave(), but save to a target. + * ::: tip "Optional arguments" + * * @dither: %gdouble, quantisation dithering level + * * @effort: %gint, quantisation CPU effort + * * @bitdepth: %gint, number of bits per pixel + * * @interframe_maxerror: %gdouble, maximum inter-frame error for + * transparency + * * @reuse: %gboolean, reuse palette from input + * * @interlace: %gboolean, write an interlaced (progressive) GIF + * * @interpalette_maxerror: %gdouble, maximum inter-palette error for + * palette * reusage + * * @keep_duplicate_frames: %boolean, keep duplicate frames in the output + * instead of combining them * - * See also: vips_gifsave(), vips_image_write_to_target(). + * ::: seealso + * [method@Image.gifsave], [method@Image.write_to_target]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/csvload.c b/libvips/foreign/csvload.c index 6193ea3841..f6f2769409 100644 --- a/libvips/foreign/csvload.c +++ b/libvips/foreign/csvload.c @@ -676,16 +676,10 @@ vips_foreign_load_csv_source_init(VipsForeignLoadCsvSource *source) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Load a CSV (comma-separated values) file. * - * * @skip: skip this many lines at start of file - * * @lines: read this many lines from file - * * @whitespace: set of whitespace characters - * * @separator: set of separator characters - * * @fail_on: #VipsFailOn, types of read error to fail on - * - * Load a CSV (comma-separated values) file. The output image is always 1 - * band (monochrome), #VIPS_FORMAT_DOUBLE. Use vips_bandfold() to turn + * The output image is always 1 band (monochrome), + * [enum@Vips.BandFormat.DOUBLE]. Use [method@Image.bandfold] to turn * RGBRGBRGB mono images into colour images. * * Items in lines can be either floating point numbers in the C locale, or @@ -709,7 +703,15 @@ vips_foreign_load_csv_source_init(VipsForeignLoadCsvSource *source) * Use @fail_on to set the type of error that will cause load to fail. By * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. * - * See also: vips_image_new_from_file(), vips_bandfold(). + * ::: tip "Optional arguments" + * * @skip: %gint, skip this many lines at start of file + * * @lines: %gint, read this many lines from file + * * @whitespace: %gchararray, set of whitespace characters + * * @separator: %gchararray, set of separator characters + * * @fail_on: [enum@FailOn], types of read error to fail on + * + * ::: seealso + * vips_image_new_from_file(), [method@Image.bandfold]. * * Returns: 0 on success, -1 on error. */ @@ -732,17 +734,17 @@ vips_csvload(const char *filename, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @skip: skip this many lines at start of file - * * @lines: read this many lines from file - * * @whitespace: set of whitespace characters - * * @separator: set of separator characters - * * @fail_on: #VipsFailOn, types of read error to fail on + * Exactly as [ctor@Image.csvload], but read from a source. * - * Exactly as vips_csvload(), but read from a source. + * ::: tip "Optional arguments" + * * @skip: %gint, skip this many lines at start of file + * * @lines: %gint, read this many lines from file + * * @whitespace: %gchararray, set of whitespace characters + * * @separator: %gchararray, set of separator characters + * * @fail_on: [enum@FailOn], types of read error to fail on * - * See also: vips_csvload(). + * ::: seealso + * [ctor@Image.csvload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/csvsave.c b/libvips/foreign/csvsave.c index 40bf031b56..69e273db1e 100644 --- a/libvips/foreign/csvsave.c +++ b/libvips/foreign/csvsave.c @@ -340,11 +340,8 @@ vips_foreign_save_csv_target_init(VipsForeignSaveCsvTarget *target) * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @separator: separator string - * * Writes the pixels in @in to the @filename as CSV (comma-separated values). + * * The image is written * one line of text per scanline. Complex numbers are written as * "(real,imaginary)" and will need extra parsing I guess. Only the first band @@ -353,7 +350,11 @@ vips_foreign_save_csv_target_init(VipsForeignSaveCsvTarget *target) * @separator gives the string to use to separate numbers in the output. * The default is "\\t" (tab). * - * See also: vips_image_write_to_file(). + * ::: tip "Optional arguments" + * * @separator: separator string + * + * ::: seealso + * [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -376,13 +377,13 @@ vips_csvsave(VipsImage *in, const char *filename, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @separator: separator string + * As [method@Image.csvsave], but save to a target. * - * As vips_csvsave(), but save to a target. + * ::: tip "Optional arguments" + * * @separator: separator string * - * See also: vips_csvsave(). + * ::: seealso + * [method@Image.csvsave]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index b331c5dd1c..8235da46e1 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -2678,30 +2678,12 @@ vips_foreign_save_dz_buffer_init(VipsForeignSaveDzBuffer *buffer) * @name: name to save to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @basename: %gchar base part of name - * * @layout: #VipsForeignDzLayout directory layout convention - * * @suffix: %gchar suffix for tiles - * * @overlap: %gint set tile overlap - * * @tile_size: %gint set tile size - * * @background: #VipsArrayDouble background colour - * * @depth: #VipsForeignDzDepth how deep to make the pyramid - * * @centre: %gboolean centre the tiles - * * @angle: #VipsAngle rotate the image by this much - * * @container: #VipsForeignDzContainer set container type - * * @compression: %gint zip deflate compression level - * * @region_shrink: #VipsRegionShrink how to shrink each 2x2 region - * * @skip_blanks: %gint skip tiles which are nearly equal to the background - * * @id: %gchar id for IIIF properties - * * @Q: %gint, quality factor - * * Save an image as a set of tiles at various resolutions. By default dzsave * uses DeepZoom layout -- use @layout to pick other conventions. * - * vips_dzsave() creates a directory called @name to hold the tiles. If @name - * ends `.zip`, vips_dzsave() will create a zip file called @name to hold the - * tiles. You can use @container to force zip file output. + * [method@Image.dzsave] creates a directory called @name to hold the tiles. + * If @name ends `.zip`, [method@Image.dzsave] will create a zip file called + * @name to hold the tiles. You can use @container to force zip file output. * * Use @basename to set the name of the image we are creating. The * default value is set from @name. @@ -2728,7 +2710,7 @@ vips_foreign_save_dz_buffer_init(VipsForeignSaveDzBuffer *buffer) * You can rotate the image during write with the @angle argument. However, * this will only work for images which support random access, like openslide, * and not for things like JPEG. You'll need to rotate those images - * yourself with vips_rot(). Note that the `autorotate` option to the loader + * yourself with [method@Image.rot]. Note that the `autorotate` option to the loader * may do what you need. * * By default, all tiles are stripped since usually you do not want a copy of @@ -2752,7 +2734,26 @@ vips_foreign_save_dz_buffer_init(VipsForeignSaveDzBuffer *buffer) * * Use @layout #VIPS_FOREIGN_DZ_LAYOUT_IIIF3 for IIIF v3 layout. * - * See also: vips_tiffsave(). + * ::: tip "Optional arguments" + * * @basename: %gchararray, base part of name + * * @layout: [enum@ForeignDzLayout], directory layout convention + * * @suffix: %gchararray, suffix for tiles + * * @overlap: %gint, set tile overlap + * * @tile_size: %gint, set tile size + * * @background: [struct@ArrayDouble], background colour + * * @depth: [enum@ForeignDzDepth], how deep to make the pyramid + * * @centre: %gboolean, centre the tiles + * * @angle: [enum@Angle], rotate the image by this much + * * @container: [enum@ForeignDzContainer], set container type + * * @compression: %gint, zip deflate compression level + * * @region_shrink: [enum@RegionShrink], how to shrink each 2x2 region + * * @skip_blanks: %gint, skip tiles which are nearly equal to the + * background + * * @id: %gchararray, id for IIIF properties + * * @Q: %gint, quality factor + * + * ::: seealso + * [method@Image.tiffsave]. * * Returns: 0 on success, -1 on error. */ @@ -2776,34 +2777,35 @@ vips_dzsave(VipsImage *in, const char *name, ...) * @len: (type gsize): return output length here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @basename: %gchar base part of name - * * @layout: #VipsForeignDzLayout directory layout convention - * * @suffix: %gchar suffix for tiles - * * @overlap: %gint set tile overlap - * * @tile_size: %gint set tile size - * * @background: #VipsArrayDouble background colour - * * @depth: #VipsForeignDzDepth how deep to make the pyramid - * * @centre: %gboolean centre the tiles - * * @angle: #VipsAngle rotate the image by this much - * * @container: #VipsForeignDzContainer set container type - * * @compression: %gint zip deflate compression level - * * @region_shrink: #VipsRegionShrink how to shrink each 2x2 region. - * * @skip_blanks: %gint skip tiles which are nearly equal to the background - * * @id: %gchar id for IIIF properties - * * @Q: %gint, quality factor - * - * As vips_dzsave(), but save to a memory buffer. + * As [method@Image.dzsave], but save to a memory buffer. * * Output is always in a zip container. Use @basename to set the name of the * directory that the zip will create when unzipped. * * The address of the buffer is returned in @buf, the length of the buffer in - * @len. You are responsible for freeing the buffer with g_free() when you + * @len. You are responsible for freeing the buffer with [func@GLib.free] when you * are done with it. * - * See also: vips_dzsave(), vips_image_write_to_file(). + * ::: tip "Optional arguments" + * * @basename: %gchararray, base part of name + * * @layout: [enum@ForeignDzLayout], directory layout convention + * * @suffix: %gchararray, suffix for tiles + * * @overlap: %gint, set tile overlap + * * @tile_size: %gint, set tile size + * * @background: [struct@ArrayDouble], background colour + * * @depth: [enum@ForeignDzDepth], how deep to make the pyramid + * * @centre: %gboolean, centre the tiles + * * @angle: [enum@Angle], rotate the image by this much + * * @container: [enum@ForeignDzContainer], set container type + * * @compression: %gint, zip deflate compression level + * * @region_shrink: [enum@RegionShrink], how to shrink each 2x2 region + * * @skip_blanks: %gint, skip tiles which are nearly equal to the + * background + * * @id: %gchararray, id for IIIF properties + * * @Q: %gint, quality factor + * + * ::: seealso + * [method@Image.dzsave], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -2841,27 +2843,28 @@ vips_dzsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @basename: %gchar base part of name - * * @layout: #VipsForeignDzLayout directory layout convention - * * @suffix: %gchar suffix for tiles - * * @overlap: %gint set tile overlap - * * @tile_size: %gint set tile size - * * @background: #VipsArrayDouble background colour - * * @depth: #VipsForeignDzDepth how deep to make the pyramid - * * @centre: %gboolean centre the tiles - * * @angle: #VipsAngle rotate the image by this much - * * @container: #VipsForeignDzContainer set container type - * * @compression: %gint zip deflate compression level - * * @region_shrink: #VipsRegionShrink how to shrink each 2x2 region. - * * @skip_blanks: %gint skip tiles which are nearly equal to the background - * * @id: %gchar id for IIIF properties - * * @Q: %gint, quality factor + * As [method@Image.dzsave], but save to a target. * - * As vips_dzsave(), but save to a target. + * ::: tip "Optional arguments" + * * @basename: %gchararray, base part of name + * * @layout: [enum@ForeignDzLayout], directory layout convention + * * @suffix: %gchararray, suffix for tiles + * * @overlap: %gint, set tile overlap + * * @tile_size: %gint, set tile size + * * @background: [struct@ArrayDouble], background colour + * * @depth: [enum@ForeignDzDepth], how deep to make the pyramid + * * @centre: %gboolean, centre the tiles + * * @angle: [enum@Angle], rotate the image by this much + * * @container: [enum@ForeignDzContainer], set container type + * * @compression: %gint, zip deflate compression level + * * @region_shrink: [enum@RegionShrink], how to shrink each 2x2 region + * * @skip_blanks: %gint, skip tiles which are nearly equal to the + * background + * * @id: %gchararray, id for IIIF properties + * * @Q: %gint, quality factor * - * See also: vips_dzsave(), vips_image_write_to_target(). + * ::: seealso + * [method@Image.dzsave], [method@Image.write_to_target]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/fitsload.c b/libvips/foreign/fitsload.c index 28472df327..44314b0872 100644 --- a/libvips/foreign/fitsload.c +++ b/libvips/foreign/fitsload.c @@ -365,7 +365,8 @@ vips_foreign_load_fits_source_init(VipsForeignLoadFitsSource *fits) * * FITS metadata is attached with the "fits-" prefix. * - * See also: vips_image_new_from_file(). + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -388,7 +389,7 @@ vips_fitsload(const char *filename, VipsImage **out, ...) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Exactly as vips_fitsload(), but read from a source. + * Exactly as [ctor@Image.fitsload], but read from a source. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/fitssave.c b/libvips/foreign/fitssave.c index 6017bfcfd7..427f9d4e56 100644 --- a/libvips/foreign/fitssave.c +++ b/libvips/foreign/fitssave.c @@ -162,7 +162,8 @@ vips_foreign_save_fits_init(VipsForeignSaveFits *fits) * * Write a VIPS image to a file in FITS format. * - * See also: vips_image_write_to_file(). + * ::: seealso + * [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index a064b7989b..57a2da8035 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -369,7 +369,7 @@ static GQuark vips__foreign_load_operation = 0; * * #VIPS_FOREIGN_BIGENDIAN means that image pixels are most-significant byte * first. Depending on the native byte order of the host machine, you may - * need to swap bytes. See vips_copy(). + * need to swap bytes. See [method@Image.copy]. */ G_DEFINE_ABSTRACT_TYPE(VipsForeign, vips_foreign, VIPS_TYPE_OPERATION); @@ -457,18 +457,19 @@ file_compare(VipsForeignClass *a, VipsForeignClass *b, void *user_data) /** * vips_foreign_map: * @base: base class to search below (eg. "VipsForeignLoad") - * @fn: (scope call): function to apply to each #VipsForeignClass + * @fn: (scope call): function to apply to each [class@Foreign]Class * @a: user data * @b: user data * - * Apply a function to every #VipsForeignClass that VIPS knows about. Foreigns + * Apply a function to every [class@Foreign]Class that VIPS knows about. Foreigns * are presented to the function in priority order. * * Like all VIPS map functions, if @fn returns %NULL, iteration continues. If * it returns non-%NULL, iteration terminates and that value is returned. The * map function returns %NULL if all calls return %NULL. * - * See also: vips_slist_map(). + * ::: seealso + * [func@slist_map2]. * * Returns: (transfer none): the result of iteration */ @@ -596,7 +597,8 @@ vips_foreign_find_load_sub(VipsForeignLoadClass *load_class, * Searches for an operation you could use to load @filename. Any trailing * options on @filename are stripped and ignored. * - * See also: vips_foreign_find_load_buffer(), vips_image_new_from_file(). + * ::: seealso + * [func@Foreign.find_load_buffer], vips_image_new_from_file(). * * Returns: the name of an operation on success, %NULL on error */ @@ -699,7 +701,8 @@ vips_foreign_find_load_buffer_sub(VipsForeignLoadClass *load_class, * * vips -l | grep load_buffer * - * See also: vips_image_new_from_buffer(). + * ::: seealso + * vips_image_new_from_buffer(). * * Returns: (transfer none): the name of an operation on success, %NULL on * error. @@ -760,7 +763,8 @@ vips_foreign_find_load_source_sub(void *item, void *a, void *b) * * vips -l | grep load_source * - * See also: vips_image_new_from_source(). + * ::: seealso + * vips_image_new_from_source(). * * Returns: (transfer none): the name of an operation on success, %NULL on * error. @@ -955,7 +959,7 @@ vips_foreign_load_temp(VipsForeignLoad *load) } /* We open via disc if the uncompressed image will be larger than - * vips_get_disc_threshold() + * vips_get_disc_threshold(). */ if (image_size > disc_threshold) { #ifdef DEBUG @@ -1011,7 +1015,7 @@ vips_foreign_load_start(VipsImage *out, void *a, void *b) return NULL; #ifdef DEBUG - printf("vips_foreign_load_start: triggering ->load()\n"); + printf("vips_foreign_load_start: triggering ->load\n"); #endif /*DEBUG*/ /* Read the image in. This may involve a long computation and @@ -1138,7 +1142,7 @@ vips_foreign_load_build(VipsObject *object) VIPS_META_LOADER, class->nickname); #ifdef DEBUG - printf("vips_foreign_load_build: triggering ->header()\n"); + printf("vips_foreign_load_build: triggering ->header\n"); #endif /*DEBUG*/ /* Read the header into @out. @@ -1991,7 +1995,8 @@ vips_foreign_find_save_sub(VipsForeignSaveClass *save_class, * Searches for an operation you could use to write to @filename. * Any trailing options on @filename are stripped and ignored. * - * See also: vips_foreign_find_save_buffer(), vips_image_write_to_file(). + * ::: seealso + * [func@Foreign.find_save_buffer], [method@Image.write_to_file]. * * Returns: (nullable): the name of an operation on success, %NULL on error */ @@ -2059,9 +2064,9 @@ vips_foreign_get_suffixes_add_cb(VipsForeignSaveClass *save_class, * This is not the same as all the supported file types, since libvips * detects image format for load by testing the first few bytes. * - * Use vips_foreign_find_load() to detect type for a specific file. + * Use [func@Foreign.find_load] to detect type for a specific file. * - * Free the return result with g_strfreev(). + * Free the return result with [func@GLib.strfreev]. * * Returns: (transfer full) (array): all supported file extensions, as a * %NULL-terminated array. @@ -2146,7 +2151,8 @@ vips_foreign_find_save_target_sub(VipsForeignSaveClass *save_class, * Searches for an operation you could use to write to a target in @suffix * format. * - * See also: vips_image_write_to_buffer(). + * ::: seealso + * [method@Image.write_to_buffer]. * * Returns: (nullable): the name of an operation on success, %NULL on error */ @@ -2204,7 +2210,8 @@ vips_foreign_find_save_buffer_sub(VipsForeignSaveClass *save_class, * Searches for an operation you could use to write to a buffer in @suffix * format. * - * See also: vips_image_write_to_buffer(). + * ::: seealso + * [method@Image.write_to_buffer]. * * Returns: (nullable): the name of an operation on success, %NULL on error */ @@ -2239,13 +2246,6 @@ vips_foreign_find_save_buffer(const char *name) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, page (top-level image number) to read - * * @n: %gint, load this many pages - * * @thumbnail: %gboolean, fetch thumbnail instead of image - * * @unlimited: %gboolean, remove all denial of service limits - * * Read a HEIF image file into a VIPS image. * * Use @page to select a page to render, numbering from zero. If neither @n @@ -2253,7 +2253,7 @@ vips_foreign_find_save_buffer(const char *name) * * Use @n to select the number of pages to render. The default is 1. Pages are * rendered in a vertical column. Set to -1 to mean "until the end of the - * document". Use vips_grid() to reorganise pages. + * document". Use [method@Image.grid] to reorganise pages. * * HEIF images have a primary image. The metadata item `heif-primary` gives * the page number of the primary. @@ -2267,7 +2267,14 @@ vips_foreign_find_save_buffer(const char *name) * The bitdepth of the heic image is recorded in the metadata item * `heif-bitdepth`. * - * See also: vips_image_new_from_file(). + * ::: tip "Optional arguments" + * * @page: %gint, page (top-level image number) to read + * * @n: %gint, load this many pages + * * @thumbnail: %gboolean, fetch thumbnail instead of image + * * @unlimited: %gboolean, remove all denial of service limits + * + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -2291,20 +2298,20 @@ vips_heifload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, page (top-level image number) to read - * * @n: %gint, load this many pages - * * @thumbnail: %gboolean, fetch thumbnail instead of image - * * @unlimited: %gboolean, remove all denial of service limits - * * Read a HEIF image file into a VIPS image. - * Exactly as vips_heifload(), but read from a memory buffer. + * Exactly as [ctor@Image.heifload], but read from a memory buffer. * * You must not free the buffer while @out is active. The - * #VipsObject::postclose signal on @out is a good place to free. + * [signal@Object::postclose] signal on @out is a good place to free. + * + * ::: tip "Optional arguments" + * * @page: %gint, page (top-level image number) to read + * * @n: %gint, load this many pages + * * @thumbnail: %gboolean, fetch thumbnail instead of image + * * @unlimited: %gboolean, remove all denial of service limits * - * See also: vips_heifload(). + * ::: seealso + * [ctor@Image.heifload]. * * Returns: 0 on success, -1 on error. */ @@ -2334,16 +2341,16 @@ vips_heifload_buffer(void *buf, size_t len, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Exactly as [ctor@Image.heifload], but read from a source. * - * * @page: %gint, page (top-level image number) to read - * * @n: %gint, load this many pages - * * @thumbnail: %gboolean, fetch thumbnail instead of image - * * @unlimited: %gboolean, remove all denial of service limits + * ::: tip "Optional arguments" + * * @page: %gint, page (top-level image number) to read + * * @n: %gint, load this many pages + * * @thumbnail: %gboolean, fetch thumbnail instead of image + * * @unlimited: %gboolean, remove all denial of service limits * - * Exactly as vips_heifload(), but read from a source. - * - * See also: vips_heifload(). + * ::: seealso + * [ctor@Image.heifload]. * * Returns: 0 on success, -1 on error. */ @@ -2366,16 +2373,6 @@ vips_heifload_source(VipsSource *source, VipsImage **out, ...) * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @bitdepth: %gint, set write bit depth to 8, 10, or 12 bits - * * @lossless: %gboolean, enable lossless encoding - * * @compression: #VipsForeignHeifCompression, write with this compression - * * @effort: %gint, encoding effort - * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode - * * @encoder: #VipsForeignHeifEncoder, select encoder to use - * * Write a VIPS image to a file in HEIF format. * * Use @Q to set the compression factor. Default 50, which seems to be roughly @@ -2398,7 +2395,18 @@ vips_heifload_source(VipsSource *source, VipsImage **out, ...) * * Use @encoder to set the encode library to use, e.g. aom, SVT-AV1, rav1e etc. * - * See also: vips_image_write_to_file(), vips_heifload(). + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @bitdepth: %gint, set write bit depth to 8, 10, or 12 bits + * * @lossless: %gboolean, enable lossless encoding + * * @compression: [enum@ForeignHeifCompression], write with this + * compression + * * @effort: %gint, encoding effort + * * @subsample_mode: [class@Foreign]Subsample, chroma subsampling mode + * * @encoder: [class@Foreign]HeifEncoder, select encoder to use + * + * ::: seealso + * [method@Image.write_to_file], [ctor@Image.heifload]. * * Returns: 0 on success, -1 on error. */ @@ -2422,23 +2430,24 @@ vips_heifsave(VipsImage *in, const char *filename, ...) * @len: (type gsize): return output length here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @bitdepth: %gint, set write bit depth to 8, 10, or 12 bits - * * @lossless: %gboolean, enable lossless encoding - * * @compression: #VipsForeignHeifCompression, write with this compression - * * @effort: %gint, encoding effort - * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode - * * @encoder: #VipsForeignHeifEncoder, select encoder to use - * - * As vips_heifsave(), but save to a memory buffer. + * As [method@Image.heifsave], but save to a memory buffer. * * The address of the buffer is returned in @obuf, the length of the buffer in - * @olen. You are responsible for freeing the buffer with g_free() when you - * are done with it. - * - * See also: vips_heifsave(), vips_image_write_to_file(). + * @olen. You are responsible for freeing the buffer with [func@GLib.free] + * when you are done with it. + * + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @bitdepth: %gint, set write bit depth to 8, 10, or 12 bits + * * @lossless: %gboolean, enable lossless encoding + * * @compression: [enum@ForeignHeifCompression], write with this + * compression + * * @effort: %gint, encoding effort + * * @subsample_mode: [class@Foreign]Subsample, chroma subsampling mode + * * @encoder: [class@Foreign]HeifEncoder, select encoder to use + * + * ::: seealso + * [method@Image.heifsave], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -2476,19 +2485,20 @@ vips_heifsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @bitdepth: %gint, set write bit depth to 8, 10, or 12 bits - * * @lossless: %gboolean, enable lossless encoding - * * @compression: #VipsForeignHeifCompression, write with this compression - * * @effort: %gint, encoding effort - * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode - * * @encoder: #VipsForeignHeifEncoder, select encoder to use + * As [method@Image.heifsave], but save to a target. * - * As vips_heifsave(), but save to a target. + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @bitdepth: %gint, set write bit depth to 8, 10, or 12 bits + * * @lossless: %gboolean, enable lossless encoding + * * @compression: [enum@ForeignHeifCompression], write with this + * compression + * * @effort: %gint, encoding effort + * * @subsample_mode: [class@Foreign]Subsample, chroma subsampling mode + * * @encoder: [class@Foreign]HeifEncoder, select encoder to use * - * See also: vips_heifsave(), vips_image_write_to_target(). + * ::: seealso + * [method@Image.heifsave], [method@Image.write_to_target]. * * Returns: 0 on success, -1 on error. */ @@ -2516,7 +2526,8 @@ vips_heifsave_target(VipsImage *in, VipsTarget *target, ...) * The JPEG-XL loader and saver are experimental features and may change * in future libvips versions. * - * See also: vips_image_new_from_file(). + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -2540,7 +2551,7 @@ vips_jxlload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Exactly as vips_jxlload(), but read from a buffer. + * Exactly as [ctor@Image.jxlload], but read from a buffer. * * Returns: 0 on success, -1 on error. */ @@ -2570,7 +2581,7 @@ vips_jxlload_buffer(void *buf, size_t len, VipsImage **out, ...) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Exactly as vips_jxlload(), but read from a source. + * Exactly as [ctor@Image.jxlload], but read from a source. * * Returns: 0 on success, -1 on error. */ @@ -2593,14 +2604,6 @@ vips_jxlload_source(VipsSource *source, VipsImage **out, ...) * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @tier: %gint, decode speed tier - * * @distance: %gdouble, maximum encoding error - * * @effort: %gint, encoding effort - * * @lossless: %gboolean, enables lossless compression - * * @Q: %gint, quality setting - * * Write a VIPS image to a file in JPEG-XL format. * * The JPEG-XL loader and saver are experimental features and may change @@ -2618,6 +2621,13 @@ vips_jxlload_source(VipsSource *source, VipsImage **out, ...) * * Set @lossless to enable lossless compression. * + * ::: tip "Optional arguments" + * * @tier: %gint, decode speed tier + * * @distance: %gdouble, maximum encoding error + * * @effort: %gint, encoding effort + * * @lossless: %gboolean, enables lossless compression + * * @Q: %gint, quality setting + * * Returns: 0 on success, -1 on error. */ int @@ -2640,17 +2650,17 @@ vips_jxlsave(VipsImage *in, const char *filename, ...) * @len: (type gsize): return output length here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * As [method@Image.jxlsave], but save to a memory buffer. * - * * @tier: %gint, decode speed tier - * * @distance: %gdouble, maximum encoding error - * * @effort: %gint, encoding effort - * * @lossless: %gboolean, enables lossless compression - * * @Q: %gint, quality setting + * ::: tip "Optional arguments" + * * @tier: %gint, decode speed tier + * * @distance: %gdouble, maximum encoding error + * * @effort: %gint, encoding effort + * * @lossless: %gboolean, enables lossless compression + * * @Q: %gint, quality setting * - * As vips_jxlsave(), but save to a memory buffer. - * - * See also: vips_jxlsave(), vips_image_write_to_target(). + * ::: seealso + * [method@Image.jxlsave], [method@Image.write_to_target]. * * Returns: 0 on success, -1 on error. */ @@ -2688,17 +2698,17 @@ vips_jxlsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @tier: %gint, decode speed tier - * * @distance: %gdouble, maximum encoding error - * * @effort: %gint, encoding effort - * * @lossless: %gboolean, enables lossless compression - * * @Q: %gint, quality setting + * As [method@Image.jxlsave], but save to a target. * - * As vips_jxlsave(), but save to a target. + * ::: tip "Optional arguments" + * * @tier: %gint, decode speed tier + * * @distance: %gdouble, maximum encoding error + * * @effort: %gint, encoding effort + * * @lossless: %gboolean, enables lossless compression + * * @Q: %gint, quality setting * - * See also: vips_jxlsave(), vips_image_write_to_target(). + * ::: seealso + * [method@Image.jxlsave], [method@Image.write_to_target]. * * Returns: 0 on success, -1 on error. */ @@ -2721,26 +2731,17 @@ vips_jxlsave_target(VipsImage *in, VipsTarget *target, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, load this page, numbered from zero - * * @n: %gint, load this many pages - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor - * * @background: #VipsArrayDouble background colour - * * @password: %gchararray PDF password - * * Render a PDF file into a VIPS image. * * The output image is always RGBA --- CMYK PDFs will be - * converted. If you need CMYK bitmaps, you should use vips_magickload() + * converted. If you need CMYK bitmaps, you should use [ctor@Image.magickload] * instead. * * Use @page to select a page to render, numbering from zero. * * Use @n to select the number of pages to render. The default is 1. Pages are * rendered in a vertical column, with each individual page aligned to the - * left. Set to -1 to mean "until the end of the document". Use vips_grid() + * left. Set to -1 to mean "until the end of the document". Use [method@Image.grid] * to change page layout. * * Use @dpi to set the rendering resolution. The default is 72. Additionally, @@ -2757,7 +2758,15 @@ vips_jxlsave_target(VipsImage *in, VipsTarget *target, ...) * This function only reads the image header and does not render any pixel * data. Rendering occurs when pixels are accessed. * - * See also: vips_image_new_from_file(), vips_magickload(). + * ::: tip "Optional arguments" + * * @page: %gint, load this page, numbered from zero + * * @n: %gint, load this many pages + * * @dpi: %gdouble, render at this DPI + * * @scale: %gdouble, scale render by this factor + * * @background: [struct@ArrayDouble], background colour + * + * ::: seealso + * vips_image_new_from_file(), [ctor@Image.magickload]. * * Returns: 0 on success, -1 on error. */ @@ -2781,21 +2790,21 @@ vips_pdfload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, load this page, numbered from zero - * * @n: %gint, load this many pages - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor - * * @background: #VipsArrayDouble background colour - * * Read a PDF-formatted memory buffer into a VIPS image. Exactly as - * vips_pdfload(), but read from memory. + * [ctor@Image.pdfload], but read from memory. * * You must not free the buffer while @out is active. The - * #VipsObject::postclose signal on @out is a good place to free. + * [signal@Object::postclose] signal on @out is a good place to free. + * + * ::: tip "Optional arguments" + * * @page: %gint, load this page, numbered from zero + * * @n: %gint, load this many pages + * * @dpi: %gdouble, render at this DPI + * * @scale: %gdouble, scale render by this factor + * * @background: [struct@ArrayDouble], background colour * - * See also: vips_pdfload(). + * ::: seealso + * [ctor@Image.pdfload]. * * Returns: 0 on success, -1 on error. */ @@ -2825,17 +2834,17 @@ vips_pdfload_buffer(void *buf, size_t len, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Exactly as [ctor@Image.pdfload], but read from a source. * - * * @page: %gint, load this page, numbered from zero - * * @n: %gint, load this many pages - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor - * * @background: #VipsArrayDouble background colour + * ::: tip "Optional arguments" + * * @page: %gint, load this page, numbered from zero + * * @n: %gint, load this many pages + * * @dpi: %gdouble, render at this DPI + * * @scale: %gdouble, scale render by this factor + * * @background: [struct@ArrayDouble], background colour * - * Exactly as vips_pdfload(), but read from a source. - * - * See also: vips_pdfload() + * ::: seealso + * [ctor@Image.pdfload] * * Returns: 0 on success, -1 on error. */ @@ -2858,22 +2867,14 @@ vips_pdfload_source(VipsSource *source, VipsImage **out, ...) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @level: %gint, load this level - * * @associated: %gchararray, load this associated image - * * @attach_associated: %gboolean, attach all associated images as metadata - * * @autocrop: %gboolean, crop to image bounds - * * @rgb: %gboolean, output RGB (not RGBA) pixels - * * Read a virtual slide supported by the OpenSlide library into a VIPS image. * OpenSlide supports images in Aperio, Hamamatsu, MIRAX, Sakura, Trestle, * and Ventana formats. * * To facilitate zooming, virtual slide formats include multiple scaled-down * versions of the high-resolution image. These are typically called - * "levels". By default, vips_openslideload() reads the highest-resolution - * level (level 0). Set @level to the level number you want. + * "levels". By default, [ctor@Image.openslideload] reads the + * highest-resolution level (level 0). Set @level to the level number you want. * * In addition to the slide image itself, virtual slide formats sometimes * include additional images, such as a scan of the slide's barcode. @@ -2883,14 +2884,22 @@ vips_pdfload_source(VipsSource *source, VipsImage **out, ...) * "slide-associated-images" metadata item. * * If you set @attach_associated, then all associated images are attached as - * metadata items. Use vips_image_get_image() on @out to retrieve them. Images + * metadata items. Use [method@Image.get_image] on @out to retrieve them. Images * are attached as "openslide-associated-XXXXX", where XXXXX is the name of the * associated image. * * By default, the output of this operator is RGBA. Set @rgb to enable RGB * output. * - * See also: vips_image_new_from_file(). + * ::: tip "Optional arguments" + * * @level: %gint, load this level + * * @associated: %gchararray, load this associated image + * * @attach_associated: %gboolean, attach all associated images as metadata + * * @autocrop: %gboolean, crop to image bounds + * * @rgb: %gboolean, output RGB (not RGBA) pixels + * + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -2913,15 +2922,14 @@ vips_openslideload(const char *filename, VipsImage **out, ...) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @level: %gint, load this level - * * @associated: %gchararray, load this associated image - * * @attach_associated: %gboolean, attach all associated images as metadata - * * @autocrop: %gboolean, crop to image bounds - * * @rgb: %gboolean, output RGB (not RGBA) pixels + * Exactly as [ctor@Image.openslideload], but read from a source. * - * Exactly as vips_openslideload(), but read from a source. + * ::: tip "Optional arguments" + * * @level: %gint, load this level + * * @associated: %gchararray, load this associated image + * * @attach_associated: %gboolean, attach all associated images as metadata + * * @autocrop: %gboolean, crop to image bounds + * * @rgb: %gboolean, output RGB (not RGBA) pixels * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index 27cd7fb9a6..91d0359c61 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -320,7 +320,7 @@ vips_foreign_save_heif_write_page(VipsForeignSaveHeif *heif, int page) #ifdef DEBUG { - GTimer *timer = g_timer_new(); + GTimer *timer = [func@GLib.timer_new]; printf("calling heif_context_encode_image() ...\n"); #endif /*DEBUG*/ diff --git a/libvips/foreign/jp2kload.c b/libvips/foreign/jp2kload.c index 752a92dd10..1313eb671e 100644 --- a/libvips/foreign/jp2kload.c +++ b/libvips/foreign/jp2kload.c @@ -1624,13 +1624,9 @@ vips__foreign_load_jp2k_decompress(VipsImage *out, * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Read a JPEG2000 image. * - * * @page: %gint, load this page - * * @oneshot: %gboolean, load pages in one-shot mode - * * @fail_on: #VipsFailOn, types of read error to fail on - * - * Read a JPEG2000 image. The loader supports 8, 16 and 32-bit int pixel + * The loader supports 8, 16 and 32-bit int pixel * values, signed and unsigned. It supports greyscale, RGB, YCC, CMYK and * multispectral colour spaces. It will read any ICC profile on the image. * @@ -1647,7 +1643,13 @@ vips__foreign_load_jp2k_decompress(VipsImage *out, * Use @fail_on to set the type of error that will cause load to fail. By * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. * - * See also: vips_image_new_from_file(). + * ::: tip "Optional arguments" + * * @page: %gint, load this page + * * @oneshot: %gboolean, load pages in one-shot mode + * * @fail_on: #VipsFailOn, types of read error to fail on + * + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -1671,16 +1673,15 @@ vips_jp2kload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, load this page - * * @oneshot: %gboolean, load pages in one-shot mode - * * @fail_on: #VipsFailOn, types of read error to fail on - * - * Exactly as vips_jp2kload(), but read from a buffer. + * Exactly as [ctor@Image.jp2kload], but read from a buffer. * * You must not free the buffer while @out is active. The - * #VipsObject::postclose signal on @out is a good place to free. + * [signal@Object::postclose] signal on @out is a good place to free. + * + * ::: tip "Optional arguments" + * * @page: %gint, load this page + * * @oneshot: %gboolean, load pages in one-shot mode + * * @fail_on: #VipsFailOn, types of read error to fail on * * Returns: 0 on success, -1 on error. */ @@ -1710,13 +1711,12 @@ vips_jp2kload_buffer(void *buf, size_t len, VipsImage **out, ...) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, load this page - * * @oneshot: %gboolean, load pages in one-shot mode - * * @fail_on: #VipsFailOn, types of read error to fail on + * Exactly as [ctor@Image.jp2kload], but read from a source. * - * Exactly as vips_jp2kload(), but read from a source. + * ::: tip "Optional arguments" + * * @page: %gint, load this page + * * @oneshot: %gboolean, load pages in one-shot mode + * * @fail_on: #VipsFailOn, types of read error to fail on * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/jp2ksave.c b/libvips/foreign/jp2ksave.c index 58205af906..e7eb432405 100644 --- a/libvips/foreign/jp2ksave.c +++ b/libvips/foreign/jp2ksave.c @@ -1443,15 +1443,8 @@ vips__foreign_save_jp2k_compress(VipsRegion *region, * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression - * * @tile_width: %gint for tile size - * * @tile_height: %gint for tile size - * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode - * * Write a VIPS image to a file in JPEG2000 format. + * * The saver supports 8, 16 and 32-bit int pixel * values, signed and unsigned. It supports greyscale, RGB, CMYK and * multispectral images. @@ -1470,7 +1463,15 @@ vips__foreign_save_jp2k_compress(VipsRegion *region, * * This operation always writes a pyramid. * - * See also: vips_image_write_to_file(), vips_jp2kload(). + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @lossless: %gboolean, enables lossless compression + * * @tile_width: %gint, tile width + * * @tile_height: %gint, tile width + * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode + * + * ::: seealso + * [method@Image.write_to_file], [ctor@Image.jp2kload]. * * Returns: 0 on success, -1 on error. */ @@ -1494,17 +1495,17 @@ vips_jp2ksave(VipsImage *in, const char *filename, ...) * @len: (type gsize): return output length here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression - * * @tile_width: %gint for tile size - * * @tile_height: %gint for tile size - * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode + * As [method@Image.jp2ksave], but save to a target. * - * As vips_jp2ksave(), but save to a target. + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @lossless: %gboolean, enables lossless compression + * * @tile_width: %gint, tile width + * * @tile_height: %gint, tile width + * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode * - * See also: vips_jp2ksave(), vips_image_write_to_target(). + * ::: seealso + * [method@Image.jp2ksave], [method@Image.write_to_target]. * * Returns: 0 on success, -1 on error. */ @@ -1542,17 +1543,17 @@ vips_jp2ksave_buffer(VipsImage *in, void **buf, size_t *len, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression - * * @tile_width: %gint for tile size - * * @tile_height: %gint for tile size - * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode + * As [method@Image.jp2ksave], but save to a target. * - * As vips_jp2ksave(), but save to a target. + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @lossless: %gboolean, enables lossless compression + * * @tile_width: %gint, tile width + * * @tile_height: %gint, tile width + * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode * - * See also: vips_jp2ksave(), vips_image_write_to_target(). + * ::: seealso + * [method@Image.jp2ksave], [method@Image.write_to_target]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/jpeg2vips.c b/libvips/foreign/jpeg2vips.c index 5fc88a79b5..cc5e5224f8 100644 --- a/libvips/foreign/jpeg2vips.c +++ b/libvips/foreign/jpeg2vips.c @@ -62,7 +62,7 @@ * 16/10/14 * - add "autorotate" option * 20/1/15 - * - don't call jpeg_finish_decompress(), all it does is read and check + * - don't call jpe[func@GLib.finish_decompress], all it does is read and check * the tail of the file * 26/2/15 * - close the jpeg read down early for a header read ... this saves an @@ -421,9 +421,9 @@ readjpeg_free(ReadJpeg *jpeg) jpeg->eman.pub.num_warnings = 0; } - /* Don't call jpeg_finish_decompress(). It just checks the tail of the + /* Don't call jpe[func@GLib.finish_decompress]. It just checks the tail of the * file and who cares about that. All mem is freed in - * jpeg_destroy_decompress(). + * jpe[func@GLib.destroy_decompress]. */ /* I don't think this can fail. It's harmless to call many times. @@ -474,8 +474,8 @@ readjpeg_new(VipsSource *source, VipsImage *out, jpeg->unlimited = unlimited; jpeg->cinfo.client_data = jpeg; - /* jpeg_create_decompress() can fail on some sanity checks. Don't - * readjpeg_free() since we don't want to jpeg_destroy_decompress(). + /* jpe[func@GLib.create_decompress] can fail on some sanity checks. Don't + * readjpe[func@GLib.free] since we don't want to jpe[func@GLib.destroy_decompress]. */ if (setjmp(jpeg->eman.jmp)) return NULL; @@ -879,7 +879,7 @@ read_jpeg_generate(VipsRegion *out_region, g_assert(r->height == VIPS_MIN(8, out_region->im->Ysize - r->top)); /* And check that the y position is correct. It should be, since we are - * inside a vips_sequential(). + * inside a [method@Image.sequential]. */ if (r->top != cinfo->output_scanline) { VIPS_GATE_STOP("read_jpeg_generate: work"); @@ -889,14 +889,14 @@ read_jpeg_generate(VipsRegion *out_region, return -1; } - /* Here for longjmp() from vips__new_error_exit() during - * jpeg_read_scanlines(). + /* Here for longjmp() from [func@_new_error_exit] during + * jpe[func@GLib.read_scanlines]. */ if (setjmp(jpeg->eman.jmp)) { VIPS_GATE_STOP("read_jpeg_generate: work"); #ifdef DEBUG - printf("read_jpeg_generate: longjmp() exit\n"); + printf("read_jpe[func@GLib.generate: longjmp] exit\n"); #endif /*DEBUG*/ return -1; @@ -945,8 +945,8 @@ read_jpeg_image(ReadJpeg *jpeg, VipsImage *out) VipsImage *im; - /* Here for longjmp() from vips__new_error_exit() during - * jpeg_read_header() or jpeg_start_decompress(). + /* Here for longjmp() from [func@_new_error_exit] during + * jpe[func@GLib.read_header] or jpe[func@GLib.start_decompress]. */ if (setjmp(jpeg->eman.jmp)) return -1; @@ -1058,8 +1058,8 @@ vips__jpeg_read_source(VipsSource *source, VipsImage *out, autorotate, unlimited))) return -1; - /* Here for longjmp() from vips__new_error_exit() during - * cinfo->mem->alloc_small() or jpeg_read_header(). + /* Here for longjmp() from [func@_new_error_exit] during + * cinfo->mem->alloc_small() or jpe[func@GLib.read_header]. */ if (setjmp(jpeg->eman.jmp)) return -1; diff --git a/libvips/foreign/jpegload.c b/libvips/foreign/jpegload.c index f42dfdf33b..951721b944 100644 --- a/libvips/foreign/jpegload.c +++ b/libvips/foreign/jpegload.c @@ -447,12 +447,6 @@ vips_foreign_load_jpeg_buffer_init(VipsForeignLoadJpegBuffer *buffer) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @shrink: %gint, shrink by this much on load - * * @fail_on: #VipsFailOn, types of read error to fail on - * * @autorotate: %gboolean, rotate image upright during load - * * Read a JPEG file into a VIPS image. It can read most 8-bit JPEG images, * including CMYK and YCbCr. * @@ -470,23 +464,23 @@ vips_foreign_load_jpeg_buffer_init(VipsForeignLoadJpegBuffer *buffer) * If @autorotate is %FALSE, the metadata field #VIPS_META_ORIENTATION is set * to the value of the orientation tag. Applications may read and interpret * this field - * as they wish later in processing. See vips_autorot(). Save + * as they wish later in processing. See [method@Image.autorot]. Save * operations will use #VIPS_META_ORIENTATION, if present, to set the * orientation of output images. * * Example: * - * |[ + * ```C * vips_jpegload("fred.jpg", &out, * "shrink", 8, * "fail_on", VIPS_FAIL_ON_TRUNCATED, * NULL); - * ]| + * ```C * * Any embedded ICC profiles are ignored: you always just get the RGB from * the file. Instead, the embedded profile will be attached to the image as * #VIPS_META_ICC_NAME. You need to use something like - * vips_icc_import() to get CIE values from the file. + * [method@Image.icc_import] to get CIE values from the file. * * EXIF metadata is attached as #VIPS_META_EXIF_NAME, IPTC as * #VIPS_META_IPTC_NAME, and XMP as #VIPS_META_XMP_NAME. @@ -502,9 +496,16 @@ vips_foreign_load_jpeg_buffer_init(VipsForeignLoadJpegBuffer *buffer) * image with no subsampling. * * The EXIF thumbnail, if present, is attached to the image as - * "jpeg-thumbnail-data". See vips_image_get_blob(). + * "jpeg-thumbnail-data". See [method@Image.get_blob]. + * + * ::: tip "Optional arguments" + * * @shrink: %gint, shrink by this much on load + * * @fail_on: [enum@FailOn], types of read error to fail on + * * @autorotate: %gboolean, use exif Orientation tag to rotate the image + * during load * - * See also: vips_jpegload_buffer(), vips_image_new_from_file(), vips_autorot(). + * ::: seealso + * [ctor@Image.jpegload_buffer], [method@Image.autorot]. * * Returns: 0 on success, -1 on error. */ @@ -528,20 +529,20 @@ vips_jpegload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @shrink: %gint, shrink by this much on load - * * @fail_on: #VipsFailOn, types of read error to fail on - * * @autorotate: %gboolean, use exif Orientation tag to rotate the image - * during load - * * Read a JPEG-formatted memory block into a VIPS image. Exactly as - * vips_jpegload(), but read from a memory buffer. + * [ctor@Image.jpegload], but read from a memory buffer. * * You must not free the buffer while @out is active. The - * #VipsObject::postclose signal on @out is a good place to free. + * [signal@Object::postclose] signal on @out is a good place to free. * - * See also: vips_jpegload(). + * ::: tip "Optional arguments" + * * @shrink: %gint, shrink by this much on load + * * @fail_on: [enum@FailOn], types of read error to fail on + * * @autorotate: %gboolean, use exif Orientation tag to rotate the image + * during load + * + * ::: seealso + * [ctor@Image.jpegload]. * * Returns: 0 on success, -1 on error. */ @@ -571,17 +572,17 @@ vips_jpegload_buffer(void *buf, size_t len, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @shrink: %gint, shrink by this much on load - * * @fail_on: #VipsFailOn, types of read error to fail on - * * @autorotate: %gboolean, use exif Orientation tag to rotate the image - * during load - * * Read a JPEG-formatted memory block into a VIPS image. Exactly as - * vips_jpegload(), but read from a source. + * [ctor@Image.jpegload], but read from a source. + * + * ::: tip "Optional arguments" + * * @shrink: %gint, shrink by this much on load + * * @fail_on: [enum@FailOn], types of read error to fail on + * * @autorotate: %gboolean, use exif Orientation tag to rotate the image + * during load * - * See also: vips_jpegload(). + * ::: seealso + * [ctor@Image.jpegload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/jpegsave.c b/libvips/foreign/jpegsave.c index 6446c79034..bd448ea9e8 100644 --- a/libvips/foreign/jpegsave.c +++ b/libvips/foreign/jpegsave.c @@ -155,7 +155,7 @@ vips_foreign_save_jpeg_class_init(VipsForeignSaveJpegClass *class) foreign_class->suffs = vips__jpeg_suffs; - /* See also vips_foreign_save_tiff_build() when saving JPEG in TIFF. + /* See also [func@Foreign.save_tiff_build] when saving JPEG in TIFF. */ save_class->saveable = VIPS_SAVEABLE_RGB_CMYK; save_class->format_table = bandfmt_jpeg; @@ -525,18 +525,6 @@ vips_foreign_save_jpeg_mime_init(VipsForeignSaveJpegMime *mime) * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @optimize_coding: %gboolean, compute optimal Huffman coding tables - * * @interlace: %gboolean, write an interlaced (progressive) jpeg - * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode - * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block - * * @overshoot_deringing: %gboolean, overshoot samples with extreme values - * * @optimize_scans: %gboolean, split DCT coefficients into separate scans - * * @quant_table: %gint, quantization table index - * * @restart_interval: %gint, restart interval in mcu - * * Write a VIPS image to a file as JPEG. * * Use @Q to set the JPEG compression factor. Default 75. @@ -612,7 +600,19 @@ vips_foreign_save_jpeg_mime_init(VipsForeignSaveJpegMime *mime) * IPTC as #VIPS_META_IPTC_NAME and XMP as #VIPS_META_XMP_NAME * are coded and attached. * - * See also: vips_jpegsave_buffer(), vips_image_write_to_file(). + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @optimize_coding: %gboolean, compute optimal Huffman coding tables + * * @interlace: %gboolean, write an interlaced (progressive) jpeg + * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode + * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block + * * @overshoot_deringing: %gboolean, overshoot samples with extreme values + * * @optimize_scans: %gboolean, split DCT coefficients into separate scans + * * @quant_table: %gint, quantization table index + * * @restart_interval: %gint, restart interval in mcu + * + * ::: seealso + * [method@Image.jpegsave_buffer], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -635,21 +635,21 @@ vips_jpegsave(VipsImage *in, const char *filename, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * As [method@Image.jpegsave], but save to a target. * - * * @Q: %gint, quality factor - * * @optimize_coding: %gboolean, compute optimal Huffman coding tables - * * @interlace: %gboolean, write an interlaced (progressive) jpeg - * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode - * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block - * * @overshoot_deringing: %gboolean, overshoot samples with extreme values - * * @optimize_scans: %gboolean, split DCT coefficients into separate scans - * * @quant_table: %gint, quantization table index - * * @restart_interval: %gint, restart interval in mcu + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @optimize_coding: %gboolean, compute optimal Huffman coding tables + * * @interlace: %gboolean, write an interlaced (progressive) jpeg + * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode + * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block + * * @overshoot_deringing: %gboolean, overshoot samples with extreme values + * * @optimize_scans: %gboolean, split DCT coefficients into separate scans + * * @quant_table: %gint, quantization table index + * * @restart_interval: %gint, restart interval in mcu * - * As vips_jpegsave(), but save to a target. - * - * See also: vips_jpegsave(), vips_image_write_to_target(). + * ::: seealso + * [method@Image.jpegsave], [method@Image.write_to_target]. * * Returns: 0 on success, -1 on error. */ @@ -673,25 +673,25 @@ vips_jpegsave_target(VipsImage *in, VipsTarget *target, ...) * @len: (type gsize): return output length here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @optimize_coding: %gboolean, compute optimal Huffman coding tables - * * @interlace: %gboolean, write an interlaced (progressive) jpeg - * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode - * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block - * * @overshoot_deringing: %gboolean, overshoot samples with extreme values - * * @optimize_scans: %gboolean, split DCT coefficients into separate scans - * * @quant_table: %gint, quantization table index - * * @restart_interval: %gint, restart interval in mcu - * - * As vips_jpegsave(), but save to a memory buffer. + * As [method@Image.jpegsave], but save to a memory buffer. * * The address of the buffer is returned in @obuf, the length of the buffer in - * @olen. You are responsible for freeing the buffer with g_free() when you - * are done with it. - * - * See also: vips_jpegsave(), vips_image_write_to_file(). + * @olen. You are responsible for freeing the buffer with [func@GLib.free] + * when you are done with it. + * + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @optimize_coding: %gboolean, compute optimal Huffman coding tables + * * @interlace: %gboolean, write an interlaced (progressive) jpeg + * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode + * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block + * * @overshoot_deringing: %gboolean, overshoot samples with extreme values + * * @optimize_scans: %gboolean, split DCT coefficients into separate scans + * * @quant_table: %gint, quantization table index + * * @restart_interval: %gint, restart interval in mcu + * + * ::: seealso + * [method@Image.jpegsave], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -728,21 +728,21 @@ vips_jpegsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * @in: image to save * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @optimize_coding: %gboolean, compute optimal Huffman coding tables - * * @interlace: %gboolean, write an interlaced (progressive) jpeg - * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode - * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block - * * @overshoot_deringing: %gboolean, overshoot samples with extreme values - * * @optimize_scans: %gboolean, split DCT coefficients into separate scans - * * @quant_table: %gint, quantization table index - * * @restart_interval: %gint, restart interval in mcu - * - * As vips_jpegsave(), but save as a mime jpeg on stdout. - * - * See also: vips_jpegsave(), vips_image_write_to_file(). + * As [method@Image.jpegsave], but save as a mime jpeg on stdout. + * + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @optimize_coding: %gboolean, compute optimal Huffman coding tables + * * @interlace: %gboolean, write an interlaced (progressive) jpeg + * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode + * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block + * * @overshoot_deringing: %gboolean, overshoot samples with extreme values + * * @optimize_scans: %gboolean, split DCT coefficients into separate scans + * * @quant_table: %gint, quantization table index + * * @restart_interval: %gint, restart interval in mcu + * + * ::: seealso + * [method@Image.jpegsave], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/jxlload.c b/libvips/foreign/jxlload.c index 0d30099c71..673fd3fb1d 100644 --- a/libvips/foreign/jxlload.c +++ b/libvips/foreign/jxlload.c @@ -196,14 +196,12 @@ vips_foreign_load_jxl_build(VipsObject *object) printf("vips_foreign_load_jxl_build:\n"); #endif /*DEBUG*/ - jxl->runner = JxlThreadParallelRunnerCreate(NULL, - vips_concurrency_get()); + jxl->runner = JxlThreadParallelRunnerCreate(NULL, vips_concurrency_get()); jxl->decoder = JxlDecoderCreate(NULL); if (JxlDecoderSetParallelRunner(jxl->decoder, JxlThreadParallelRunner, jxl->runner)) { - vips_foreign_load_jxl_error(jxl, - "JxlDecoderSetParallelRunner"); + vips_foreign_load_jxl_error(jxl, "JxlDecoderSetParallelRunner"); return -1; } diff --git a/libvips/foreign/jxlsave.c b/libvips/foreign/jxlsave.c index 83011cbd67..db046b0be3 100644 --- a/libvips/foreign/jxlsave.c +++ b/libvips/foreign/jxlsave.c @@ -504,14 +504,12 @@ vips_foreign_save_jxl_build(VipsObject *object) if (jxl->distance == 0) jxl->lossless = TRUE; - jxl->runner = JxlThreadParallelRunnerCreate(NULL, - vips_concurrency_get()); + jxl->runner = JxlThreadParallelRunnerCreate(NULL, vips_concurrency_get()); jxl->encoder = JxlEncoderCreate(NULL); if (JxlEncoderSetParallelRunner(jxl->encoder, JxlThreadParallelRunner, jxl->runner)) { - vips_foreign_save_jxl_error(jxl, - "JxlDecoderSetParallelRunner"); + vips_foreign_save_jxl_error(jxl, "JxlDecoderSetParallelRunner"); return -1; } diff --git a/libvips/foreign/magick6load.c b/libvips/foreign/magick6load.c index 61fcf7fba1..8f047dba58 100644 --- a/libvips/foreign/magick6load.c +++ b/libvips/foreign/magick6load.c @@ -5,7 +5,7 @@ * 3/2/03 JC * - some InitializeMagick() fail with NULL arg * 2/11/04 - * - im_magick2vips_header() also checks sensible width/height + * - im_magick2[func@header] also checks sensible width/height * 28/10/05 * - copy attributes to meta * - write many-frame images as a big column if all frames have identical diff --git a/libvips/foreign/magickload.c b/libvips/foreign/magickload.c index 48fc350a3e..27920634c9 100644 --- a/libvips/foreign/magickload.c +++ b/libvips/foreign/magickload.c @@ -66,15 +66,10 @@ * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Read in an image using libMagick, the ImageMagick library. * - * * @page: %gint, load from this page - * * @n: %gint, load this many pages - * * @density: string, canvas resolution for rendering vector formats like SVG - * - * Read in an image using libMagick, the ImageMagick library. This library can - * read more than 80 file formats, including SVG, BMP, EPS, DICOM and many - * others. + * This library can read more than 80 file formats, including BMP, EPS, + * DICOM and many others. * The reader can handle any ImageMagick image, including the float and double * formats. It will work with any quantum size, including HDR. Any metadata * attached to the libMagick image is copied on to the VIPS image. @@ -94,7 +89,14 @@ * docs](http://www.imagemagick.org/script/command-line-options.php#density) * on the imagemagick website. * - * See also: vips_image_new_from_file(). + * ::: tip "Optional arguments" + * * @page: %gint, load from this page + * * @n: %gint, load this many pages + * * @density: string, canvas resolution for rendering vector formats + * like SVG + * + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -118,19 +120,20 @@ vips_magickload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, load from this page - * * @n: %gint, load this many pages - * * @density: string, canvas resolution for rendering vector formats like SVG - * * Read an image memory block using libMagick into a VIPS image. Exactly as - * vips_magickload(), but read from a memory source. + * [ctor@Image.magickload], but read from a memory source. * * You must not free the buffer while @out is active. The - * #VipsObject::postclose signal on @out is a good place to free. + * [signal@Object::postclose] signal on @out is a good place to free. + * + * ::: tip "Optional arguments" + * * @page: %gint, load from this page + * * @n: %gint, load this many pages + * * @density: string, canvas resolution for rendering vector formats + * like SVG * - * See also: vips_magickload(). + * ::: seealso + * [ctor@Image.magickload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/magicksave.c b/libvips/foreign/magicksave.c index f92bd55a38..eda091b826 100644 --- a/libvips/foreign/magicksave.c +++ b/libvips/foreign/magicksave.c @@ -5,7 +5,7 @@ * - fix GraphicsMagick support * 17/2/19 * - support ICC, XMP, EXIF, IPTC metadata - * - write with a single call to vips_sink_disc() + * - write with a single call to [method@Image.sink_disc] * 29/6/19 * - support "strip" option * 6/7/19 [deftomat] @@ -60,14 +60,6 @@ * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @quality: %gint, quality factor - * * @format: %gchararray, format to save as - * * @optimize_gif_frames: %gboolean, apply GIF frames optimization - * * @optimize_gif_transparency: %gboolean, apply GIF transparency optimization - * * @bitdepth: %gint, number of bits per pixel - * * Write an image using libMagick. * * Use @quality to set the quality factor. Default 0. @@ -87,7 +79,16 @@ * @bitdepth specifies the number of bits per pixel. The image will be quantized * and dithered if the value is within the valid range (1 to 8). * - * See also: vips_magicksave_buffer(), vips_magickload(). + * ::: tip "Optional arguments" + * * @quality: %gint, quality factor + * * @format: %gchararray, format to save as + * * @optimize_gif_frames: %gboolean, apply GIF frames optimization + * * @optimize_gif_transparency: %gboolean, apply GIF transparency + * optimization + * * @bitdepth: %gint, number of bits per pixel + * + * ::: seealso + * [method@Image.magicksave_buffer], [ctor@Image.magickload]. * * Returns: 0 on success, -1 on error. */ @@ -111,21 +112,22 @@ vips_magicksave(VipsImage *in, const char *filename, ...) * @len: (type gsize): return output length here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @quality: %gint, quality factor - * * @format: %gchararray, format to save as - * * @optimize_gif_frames: %gboolean, apply GIF frames optimization - * * @optimize_gif_transparency: %gboolean, apply GIF transparency optimization - * * @bitdepth: %gint, number of bits per pixel - * - * As vips_magicksave(), but save to a memory buffer. + * As [method@Image.magicksave], but save to a memory buffer. * * The address of the buffer is returned in @obuf, the length of the buffer in - * @olen. You are responsible for freeing the buffer with g_free() when you - * are done with it. - * - * See also: vips_magicksave(), vips_image_write_to_file(). + * @olen. You are responsible for freeing the buffer with [func@GLib.free] + * when you are done with it. + * + * ::: tip "Optional arguments" + * * @quality: %gint, quality factor + * * @format: %gchararray, format to save as + * * @optimize_gif_frames: %gboolean, apply GIF frames optimization + * * @optimize_gif_transparency: %gboolean, apply GIF transparency + * optimization + * * @bitdepth: %gint, number of bits per pixel + * + * ::: seealso + * [method@Image.magicksave], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/matload.c b/libvips/foreign/matload.c index 5e3a9898eb..248433fc93 100644 --- a/libvips/foreign/matload.c +++ b/libvips/foreign/matload.c @@ -162,7 +162,8 @@ vips_foreign_load_mat_init(VipsForeignLoadMat *mat) * it as an image. It will not handle complex images. It does not handle * sparse matrices. * - * See also: vips_image_new_from_file(). + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/matrixload.c b/libvips/foreign/matrixload.c index 2a0ea56f28..99db8dc2ca 100644 --- a/libvips/foreign/matrixload.c +++ b/libvips/foreign/matrixload.c @@ -498,7 +498,8 @@ vips_foreign_load_matrix_source_init(VipsForeignLoadMatrixSource *source) * Extra characters at the ends of lines or at the end of the file are * ignored. * - * See also: vips_matrixload(). + * ::: seealso + * [ctor@Image.matrixload]. * * Returns: 0 on success, -1 on error. */ @@ -521,9 +522,10 @@ vips_matrixload(const char *filename, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Exactly as vips_matrixload(), but read from a source. + * Exactly as [ctor@Image.matrixload], but read from a source. * - * See also: vips_matrixload(). + * ::: seealso + * [ctor@Image.matrixload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/matrixsave.c b/libvips/foreign/matrixsave.c index b7cfe78ff9..3e3145baf9 100644 --- a/libvips/foreign/matrixsave.c +++ b/libvips/foreign/matrixsave.c @@ -335,10 +335,11 @@ vips_foreign_print_matrix_init(VipsForeignPrintMatrix *matrix) * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Write @in to @filename in matrix format. See vips_matrixload() for a + * Write @in to @filename in matrix format. See [ctor@Image.matrixload] for a * description of the format. * - * See also: vips_matrixload(). + * ::: seealso + * [ctor@Image.matrixload]. * * Returns: 0 on success, -1 on error. */ @@ -361,9 +362,10 @@ vips_matrixsave(VipsImage *in, const char *filename, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * As vips_matrixsave(), but save to a target. + * As [method@Image.matrixsave], but save to a target. * - * See also: vips_matrixsave(). + * ::: seealso + * [method@Image.matrixsave]. * * Returns: 0 on success, -1 on error. */ @@ -385,10 +387,11 @@ vips_matrixsave_target(VipsImage *in, VipsTarget *target, ...) * @in: image to print * @...: %NULL-terminated list of optional named arguments * - * Print @in to %stdout in matrix format. See vips_matrixload() for a + * Print @in to %stdout in matrix format. See [ctor@Image.matrixload] for a * description of the format. * - * See also: vips_matrixload(). + * ::: seealso + * [ctor@Image.matrixload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/niftiload.c b/libvips/foreign/niftiload.c index acff6484b1..2412ae68f9 100644 --- a/libvips/foreign/niftiload.c +++ b/libvips/foreign/niftiload.c @@ -814,7 +814,8 @@ vips_foreign_load_nifti_source_init( * * NIFTI metadata is attached with the "nifti-" prefix. * - * See also: vips_image_new_from_file(). + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -837,7 +838,7 @@ vips_niftiload(const char *filename, VipsImage **out, ...) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Exactly as vips_niftiload(), but read from a source. + * Exactly as [ctor@Image.niftiload], but read from a source. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/niftisave.c b/libvips/foreign/niftisave.c index de2f42cd3a..f92ca6b053 100644 --- a/libvips/foreign/niftisave.c +++ b/libvips/foreign/niftisave.c @@ -462,7 +462,8 @@ vips_foreign_save_nifti_init(VipsForeignSaveNifti *nifti) * * Use the various NIFTI suffixes to pick the nifti save format. * - * See also: vips_image_write_to_file(), vips_niftiload(). + * ::: seealso + * [method@Image.write_to_file], [ctor@Image.niftiload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/nsgifload.c b/libvips/foreign/nsgifload.c index 7a3f0f9f94..46a79d059a 100644 --- a/libvips/foreign/nsgifload.c +++ b/libvips/foreign/nsgifload.c @@ -926,19 +926,13 @@ vips_foreign_load_nsgif_source_init(VipsForeignLoadNsgifSource *source) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages - * * @fail_on: #VipsFailOn, types of read error to fail on - * * Read a GIF file into a libvips image. * * Use @page to select a page to render, numbering from zero. * * Use @n to select the number of pages to render. The default is 1. Pages are * rendered in a vertical column. Set to -1 to mean "until the end of the - * document". Use vips_grid() to change page layout. + * document". Use [method@Image.grid] to change page layout. * * Use @fail_on to set the type of error that will cause load to fail. By * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. @@ -946,7 +940,13 @@ vips_foreign_load_nsgif_source_init(VipsForeignLoadNsgifSource *source) * The output image is RGBA for GIFs containing transparent elements, RGB * otherwise. * - * See also: vips_image_new_from_file(). + * ::: tip "Optional arguments" + * * @page: %gint, page (frame) to read + * * @n: %gint, load this many pages + * * @fail_on: [enum@FailOn], types of read error to fail on + * + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -970,18 +970,18 @@ vips_gifload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages - * * @fail_on: #VipsFailOn, types of read error to fail on - * - * Exactly as vips_gifload(), but read from a memory buffer. + * Exactly as [ctor@Image.gifload], but read from a memory buffer. * * You must not free the buffer while @out is active. The - * #VipsObject::postclose signal on @out is a good place to free. + * [signal@Object::postclose] signal on @out is a good place to free. + * + * ::: tip "Optional arguments" + * * @page: %gint, page (frame) to read + * * @n: %gint, load this many pages + * * @fail_on: [enum@FailOn], types of read error to fail on * - * See also: vips_gifload(). + * ::: seealso + * [ctor@Image.gifload]. * * Returns: 0 on success, -1 on error. */ @@ -1011,15 +1011,15 @@ vips_gifload_buffer(void *buf, size_t len, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages - * * @fail_on: #VipsFailOn, types of read error to fail on + * Exactly as [ctor@Image.gifload], but read from a source. * - * Exactly as vips_gifload(), but read from a source. + * ::: tip "Optional arguments" + * * @page: %gint, page (frame) to read + * * @n: %gint, load this many pages + * * @fail_on: [enum@FailOn], types of read error to fail on * - * See also: vips_gifload(). + * ::: seealso + * [ctor@Image.gifload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/openexrload.c b/libvips/foreign/openexrload.c index 6ba9dad11c..00f5fbf259 100644 --- a/libvips/foreign/openexrload.c +++ b/libvips/foreign/openexrload.c @@ -175,7 +175,8 @@ vips_foreign_load_openexr_init(VipsForeignLoadOpenexr *openexr) * This reader uses the rather limited OpenEXR C API. It should really be * redone in C++. * - * See also: vips_image_new_from_file(). + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/pngload.c b/libvips/foreign/pngload.c index 1ecadb98cc..9124505dd6 100644 --- a/libvips/foreign/pngload.c +++ b/libvips/foreign/pngload.c @@ -411,11 +411,6 @@ vips_foreign_load_png_buffer_init(VipsForeignLoadPngBuffer *buffer) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @fail_on: #VipsFailOn, types of read error to fail on - * * @unlimited: %gboolean, remove all denial of service limits - * * Read a PNG file into a VIPS image. It can read all png images, including 8- * and 16-bit images, 1 and 3 channel, with and without an alpha channel. * @@ -429,7 +424,12 @@ vips_foreign_load_png_buffer_init(VipsForeignLoadPngBuffer *buffer) * block some denial of service attacks. Set @unlimited to disable these * limits. * - * See also: vips_image_new_from_file(). + * ::: tip "Optional arguments" + * * @fail_on: [enum@FailOn], types of read error to fail on + * * @unlimited: %gboolean, Remove all denial of service limits + * + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -453,17 +453,17 @@ vips_pngload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @fail_on: #VipsFailOn, types of read error to fail on - * * @unlimited: %gboolean, Remove all denial of service limits - * - * Exactly as vips_pngload(), but read from a PNG-formatted memory block. + * Exactly as [ctor@Image.pngload], but read from a PNG-formatted memory block. * * You must not free the buffer while @out is active. The - * #VipsObject::postclose signal on @out is a good place to free. + * [signal@Object::postclose] signal on @out is a good place to free. + * + * ::: tip "Optional arguments" + * * @fail_on: [enum@FailOn], types of read error to fail on + * * @unlimited: %gboolean, Remove all denial of service limits * - * See also: vips_pngload(). + * ::: seealso + * [ctor@Image.pngload]. * * Returns: 0 on success, -1 on error. */ @@ -493,14 +493,14 @@ vips_pngload_buffer(void *buf, size_t len, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @fail_on: #VipsFailOn, types of read error to fail on - * * @unlimited: %gboolean, Remove all denial of service limits + * Exactly as [ctor@Image.pngload], but read from a source. * - * Exactly as vips_pngload(), but read from a source. + * ::: tip "Optional arguments" + * * @fail_on: [enum@FailOn], types of read error to fail on + * * @unlimited: %gboolean, Remove all denial of service limits * - * See also: vips_pngload(). + * ::: seealso + * [ctor@Image.pngload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/pngsave.c b/libvips/foreign/pngsave.c index ab412ca68f..dc96ad9df1 100644 --- a/libvips/foreign/pngsave.c +++ b/libvips/foreign/pngsave.c @@ -454,17 +454,6 @@ vips_foreign_save_png_buffer_init(VipsForeignSavePngBuffer *buffer) * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @compression: %gint, compression level - * * @interlace: %gboolean, interlace image - * * @filter: #VipsForeignPngFilter row filter flag(s) - * * @palette: %gboolean, enable quantisation to 8bpp palette - * * @Q: %gint, quality for 8bpp quantisation - * * @dither: %gdouble, amount of dithering for 8bpp quantization - * * @bitdepth: %gint, set write bit depth to 1, 2, 4, 8 or 16 - * * @effort: %gint, quantisation CPU effort - * * Write a VIPS image to a file as PNG. * * @compression means compress with this much effort (0 - 9). Default 6. @@ -475,7 +464,7 @@ vips_foreign_save_png_buffer_init(VipsForeignSavePngBuffer *buffer) * non-interlaced image. * * Use @filter to specify one or more filters, defaults to none, - * see #VipsForeignPngFilter. + * see [flags@ForeignPngFilter]. * * The image is automatically converted to RGB, RGBA, Monochrome or Mono + * alpha before saving. Images with more than one byte per band element are @@ -495,7 +484,18 @@ vips_foreign_save_png_buffer_init(VipsForeignSavePngBuffer *buffer) * XMP metadata is written to the XMP chunk. PNG comments are written to * separate text chunks. * - * See also: vips_image_new_from_file(). + * ::: tip "Optional arguments" + * * @compression: %gint, compression level + * * @interlace: %gboolean, interlace image + * * @filter: [flags@ForeignPngFilter], row filter flag(s) + * * @palette: %gboolean, enable quantisation to 8bpp palette + * * @Q: %gint, quality for 8bpp quantisation + * * @dither: %gdouble, amount of dithering for 8bpp quantization + * * @bitdepth: %gint, set write bit depth to 1, 2, 4, 8 or 16 + * * @effort: %gint, quantisation CPU effort + * + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -519,24 +519,24 @@ vips_pngsave(VipsImage *in, const char *filename, ...) * @len: (type gsize): return output length here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @compression: %gint, compression level - * * @interlace: %gboolean, interlace image - * * @filter: #VipsForeignPngFilter row filter flag(s) - * * @palette: %gboolean, enable quantisation to 8bpp palette - * * @Q: %gint, quality for 8bpp quantisation - * * @dither: %gdouble, amount of dithering for 8bpp quantization - * * @bitdepth: %gint, set write bit depth to 1, 2, 4, 8 or 16 - * * @effort: %gint, quantisation CPU effort - * - * As vips_pngsave(), but save to a memory buffer. + * As [method@Image.pngsave], but save to a memory buffer. * * The address of the buffer is returned in @buf, the length of the buffer in - * @len. You are responsible for freeing the buffer with g_free() when you + * @len. You are responsible for freeing the buffer with [func@GLib.free] when you * are done with it. * - * See also: vips_pngsave(), vips_image_write_to_file(). + * ::: tip "Optional arguments" + * * @compression: %gint, compression level + * * @interlace: %gboolean, interlace image + * * @filter: [flags@ForeignPngFilter], row filter flag(s) + * * @palette: %gboolean, enable quantisation to 8bpp palette + * * @Q: %gint, quality for 8bpp quantisation + * * @dither: %gdouble, amount of dithering for 8bpp quantization + * * @bitdepth: %gint, set write bit depth to 1, 2, 4, 8 or 16 + * * @effort: %gint, quantisation CPU effort + * + * ::: seealso + * [method@Image.pngsave], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -574,20 +574,20 @@ vips_pngsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @compression: compression level - * * @interlace: interlace image - * * @filter: libpng row filter flag(s) - * * @palette: enable quantisation to 8bpp palette - * * @Q: quality for 8bpp quantisation - * * @dither: amount of dithering for 8bpp quantization - * * @bitdepth: %gint, set write bit depth to 1, 2, 4, 8 or 16 - * * @effort: %gint, quantisation CPU effort + * As [method@Image.pngsave], but save to a target. * - * As vips_pngsave(), but save to a target. + * ::: tip "Optional arguments" + * * @compression: %gint, compression level + * * @interlace: %gboolean, interlace image + * * @filter: [flags@ForeignPngFilter], row filter flag(s) + * * @palette: %gboolean, enable quantisation to 8bpp palette + * * @Q: %gint, quality for 8bpp quantisation + * * @dither: %gdouble, amount of dithering for 8bpp quantization + * * @bitdepth: %gint, set write bit depth to 1, 2, 4, 8 or 16 + * * @effort: %gint, quantisation CPU effort * - * See also: vips_pngsave(), vips_image_write_to_target(). + * ::: seealso + * [method@Image.pngsave], [method@Image.write_to_target]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/ppmload.c b/libvips/foreign/ppmload.c index 6292e9f14d..2aa01e0dbb 100644 --- a/libvips/foreign/ppmload.c +++ b/libvips/foreign/ppmload.c @@ -913,7 +913,8 @@ vips_foreign_load_ppm_source_init(VipsForeignLoadPpmSource *source) * stored in binary or in ASCII. One bit images become 8 bit VIPS images, * with 0 and 255 for 0 and 1. * - * See also: vips_image_new_from_file(). + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -936,9 +937,10 @@ vips_ppmload(const char *filename, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Exactly as vips_ppmload(), but read from a source. + * Exactly as [ctor@Image.ppmload], but read from a source. * - * See also: vips_ppmload(). + * ::: seealso + * [ctor@Image.ppmload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/ppmsave.c b/libvips/foreign/ppmsave.c index d4b979177f..9a4779db98 100644 --- a/libvips/foreign/ppmsave.c +++ b/libvips/foreign/ppmsave.c @@ -793,13 +793,9 @@ vips_foreign_save_pnm_target_init(VipsForeignSavePfmTarget *target) * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Write a VIPS image to a file as PPM. * - * * @format: #VipsForeignPpmFormat, format to save in - * * @ascii: %gboolean, save as ASCII rather than binary - * * @bitdepth: %gint, bitdepth to save at - * - * Write a VIPS image to a file as PPM. It can write 1, 8, 16 or + * It can write 1, 8, 16 or * 32 bit unsigned integer images, float images, colour or monochrome, * stored as binary or ASCII. * Integer images of more than 8 bits can only be stored in ASCII. @@ -814,7 +810,13 @@ vips_foreign_save_pnm_target_init(VipsForeignSavePfmTarget *target) * * @format defaults to the sub-type for this filename suffix. * - * See also: vips_image_write_to_file(). + * ::: tip "Optional arguments" + * * @format: [enum@ForeignPpmFormat], format to save in + * * @ascii: %gboolean, save as ASCII rather than binary + * * @bitdepth: %gint, bitdepth to save at + * + * ::: seealso + * [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -837,15 +839,15 @@ vips_ppmsave(VipsImage *in, const char *filename, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @format: #VipsForeignPpmFormat, format to save in - * * @ascii: %gboolean, save as ASCII rather than binary - * * @bitdepth: %gint, bitdepth to save at + * As [method@Image.ppmsave], but save to a target. * - * As vips_ppmsave(), but save to a target. + * ::: tip "Optional arguments" + * * @format: [enum@ForeignPpmFormat], format to save in + * * @ascii: %gboolean, save as ASCII rather than binary + * * @bitdepth: %gint, bitdepth to save at * - * See also: vips_ppmsave(). + * ::: seealso + * [method@Image.ppmsave]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/quantise.c b/libvips/foreign/quantise.c index 1af1992a46..0b1e194cde 100644 --- a/libvips/foreign/quantise.c +++ b/libvips/foreign/quantise.c @@ -50,7 +50,7 @@ #ifdef HAVE_IMAGEQUANT VipsQuantiseAttr * -vips__quantise_attr_create() +vips__quantise_attr_create(void) { return liq_attr_create(); } @@ -87,7 +87,7 @@ vips__quantise_image_quantize(VipsQuantiseImage *const input_image, return liq_image_quantize(input_image, options, result_output); } -/* Like vips__quantise_image_quantize(), but make a fixed palette that won't +/* Like [func@_quantise_image_quantize], but make a fixed palette that won't * get remapped during dithering. */ VipsQuantiseError @@ -181,7 +181,7 @@ vips__quantise_attr_destroy(VipsQuantiseAttr *attr) #elif defined(HAVE_QUANTIZR) /*!HAVE_IMAGEQUANT*/ VipsQuantiseAttr * -vips__quantise_attr_create() +vips__quantise_attr_create(void) { return quantizr_new_options(); } diff --git a/libvips/foreign/quantise.h b/libvips/foreign/quantise.h index 4b2b033c20..6d1728cc00 100644 --- a/libvips/foreign/quantise.h +++ b/libvips/foreign/quantise.h @@ -59,7 +59,7 @@ extern "C" { #endif #ifdef HAVE_QUANTIZATION -VipsQuantiseAttr *vips__quantise_attr_create(); +VipsQuantiseAttr *vips__quantise_attr_create(void); VipsQuantiseError vips__quantise_set_max_colors(VipsQuantiseAttr *attr, int colors); VipsQuantiseError vips__quantise_set_quality(VipsQuantiseAttr *attr, diff --git a/libvips/foreign/radload.c b/libvips/foreign/radload.c index 52ec2cc093..10c08d5856 100644 --- a/libvips/foreign/radload.c +++ b/libvips/foreign/radload.c @@ -375,11 +375,11 @@ vips_foreign_load_rad_buffer_init(VipsForeignLoadRadBuffer *buffer) * * Read a Radiance (HDR) file into a VIPS image. * - * Radiance files are read as #VIPS_CODING_RAD. They have one byte for each of + * Radiance files are read as [enum@Vips.Coding.RAD]. They have one byte for each of * red, green and blue, and one byte of shared exponent. Some operations (like - * vips_extract_area()) can work directly with images in this format, but + * [method@Image.extract_area]) can work directly with images in this format, but * mmany (all the arithmetic operations, for example) will not. Unpack - * #VIPS_CODING_RAD images to 3 band float with vips_rad2float() if + * [enum@Vips.Coding.RAD] images to 3 band float with [method@Image.rad2float] if * you want to do arithmetic on them. * * This operation ignores some header fields, like VIEW and DATE. It will not @@ -387,7 +387,8 @@ vips_foreign_load_rad_buffer_init(VipsForeignLoadRadBuffer *buffer) * * Sections of this reader from Greg Ward and Radiance with kind permission. * - * See also: vips_image_new_from_file(). + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -411,12 +412,13 @@ vips_radload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Exactly as vips_radload(), but read from a HDR-formatted memory block. + * Exactly as [ctor@Image.radload], but read from a HDR-formatted memory block. * * You must not free the buffer while @out is active. The - * #VipsObject::postclose signal on @out is a good place to free. + * [signal@Object::postclose] signal on @out is a good place to free. * - * See also: vips_radload(). + * ::: seealso + * [ctor@Image.radload]. * * Returns: 0 on success, -1 on error. */ @@ -446,9 +448,10 @@ vips_radload_buffer(void *buf, size_t len, VipsImage **out, ...) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Exactly as vips_radload(), but read from a source. + * Exactly as [ctor@Image.radload], but read from a source. * - * See also: vips_radload(). + * ::: seealso + * [ctor@Image.radload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/radsave.c b/libvips/foreign/radsave.c index 3e7387c3c8..4ad6074843 100644 --- a/libvips/foreign/radsave.c +++ b/libvips/foreign/radsave.c @@ -294,7 +294,8 @@ vips_foreign_save_rad_buffer_init(VipsForeignSaveRadBuffer *buffer) * * Sections of this reader from Greg Ward and Radiance with kind permission. * - * See also: vips_image_write_to_file(). + * ::: seealso + * [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -318,13 +319,14 @@ vips_radsave(VipsImage *in, const char *filename, ...) * @len: (type gsize): return output length here * @...: %NULL-terminated list of optional named arguments * - * As vips_radsave(), but save to a memory buffer. + * As [method@Image.radsave], but save to a memory buffer. * * The address of the buffer is returned in @buf, the length of the buffer in - * @len. You are responsible for freeing the buffer with g_free() when you + * @len. You are responsible for freeing the buffer with [func@GLib.free] when you * are done with it. * - * See also: vips_radsave(), vips_image_write_to_file(). + * ::: seealso + * [method@Image.radsave], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -362,9 +364,10 @@ vips_radsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * As vips_radsave(), but save to a target. + * As [method@Image.radsave], but save to a target. * - * See also: vips_radsave(). + * ::: seealso + * [method@Image.radsave]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/rawload.c b/libvips/foreign/rawload.c index 3861cf951b..3da27c2d62 100644 --- a/libvips/foreign/rawload.c +++ b/libvips/foreign/rawload.c @@ -201,23 +201,23 @@ vips_foreign_load_raw_init(VipsForeignLoadRaw *raw) * @bands: number of image bands * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @offset: %guint64, offset in bytes from start of file - * * @format: #VipsBandFormat, set image format - * * @interpretation: #VipsInterpretation, set image interpretation - * * This operation mmaps the file, setting up @out so that access to that * image will read from the file. * * By default, it assumes uchar pixels. Use @format to select something else. * - * The image will be tagged as #VIPS_INTERPRETATION_MULTIBAND. Use + * The image will be tagged as [enum@Vips.Interpretation.MULTIBAND]. Use * @interpretation to select something else. * - * Use vips_byteswap() to reverse the byte ordering if necessary. + * Use [method@Image.byteswap] to reverse the byte ordering if necessary. + * + * ::: tip "Optional arguments" + * * @offset: %guint64, offset in bytes from start of file + * * @format: [enum@BandFormat], set image format + * * @interpretation: [enum@Interpretation], set image interpretation * - * See also: vips_image_new_from_file(), vips_copy(), vips_byteswap(). + * ::: seealso + * vips_image_new_from_file(), [method@Image.copy], [method@Image.byteswap]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/rawsave.c b/libvips/foreign/rawsave.c index 6c495146b3..b137e5bebd 100644 --- a/libvips/foreign/rawsave.c +++ b/libvips/foreign/rawsave.c @@ -332,7 +332,8 @@ vips_foreign_save_raw_buffer_init(VipsForeignSaveRawBuffer *buffer) * Writes the pixels in @in to the file @filename with no header or other * metadata. * - * See also: vips_image_write_to_file(). + * ::: seealso + * [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -356,13 +357,14 @@ vips_rawsave(VipsImage *in, const char *filename, ...) * @len: (type gsize): return output length here * @...: %NULL-terminated list of optional named arguments * - * As vips_rawsave(), but save to a memory buffer. + * As [method@Image.rawsave], but save to a memory buffer. * * The address of the buffer is returned in @buf, the length of the buffer in - * @len. You are responsible for freeing the buffer with g_free() when you + * @len. You are responsible for freeing the buffer with [func@GLib.free] when you * are done with it. * - * See also: vips_rawsave(), vips_image_write_to_memory(), vips_image_write_to_file(). + * ::: seealso + * [method@Image.rawsave], [method@Image.write_to_memory], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -400,9 +402,10 @@ vips_rawsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * As vips_rawsave(), but save to a target. + * As [method@Image.rawsave], but save to a target. * - * See also: vips_rawsave(). + * ::: seealso + * [method@Image.rawsave]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/svgload.c b/libvips/foreign/svgload.c index ed1b92e6dc..d839225802 100644 --- a/libvips/foreign/svgload.c +++ b/libvips/foreign/svgload.c @@ -1040,15 +1040,9 @@ vips_foreign_load_svg_buffer_init(VipsForeignLoadSvgBuffer *buffer) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Render a SVG file into a VIPS image. * - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor - * * @unlimited: %gboolean, allow SVGs of any size - * * @stylesheet: %gchararray, custom CSS - * - * Render a SVG file into a VIPS image. Rendering uses the librsvg library - * and should be fast. + * Rendering uses the librsvg library and should be fast. * * Use @dpi to set the rendering resolution. The default is 72. You can also * scale the rendering by @scale. @@ -1063,7 +1057,14 @@ vips_foreign_load_svg_buffer_init(VipsForeignLoadSvgBuffer *buffer) * During the CSS cascade, the specified stylesheet will be applied with a * User Origin. This feature requires librsvg 2.48.0 or later. * - * See also: vips_image_new_from_file(). + * ::: tip "Optional arguments" + * * @dpi: %gdouble, render at this DPI + * * @scale: %gdouble, scale render by this factor + * * @unlimited: %gboolean, allow SVGs of any size + * * @stylesheet: %gchararray, custom CSS + * + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -1087,20 +1088,20 @@ vips_svgload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor - * * @unlimited: %gboolean, allow SVGs of any size - * * @stylesheet: %gchararray, custom CSS - * * Read a SVG-formatted memory block into a VIPS image. Exactly as - * vips_svgload(), but read from a memory buffer. + * [ctor@Image.svgload], but read from a memory buffer. * * You must not free the buffer while @out is active. The - * #VipsObject::postclose signal on @out is a good place to free. + * [signal@Object::postclose] signal on @out is a good place to free. + * + * ::: tip "Optional arguments" + * * @dpi: %gdouble, render at this DPI + * * @scale: %gdouble, scale render by this factor + * * @unlimited: %gboolean, allow SVGs of any size + * * @stylesheet: %gchararray, custom CSS * - * See also: vips_svgload(). + * ::: seealso + * [ctor@Image.svgload]. * * Returns: 0 on success, -1 on error. */ @@ -1130,17 +1131,17 @@ vips_svgload_buffer(void *buf, size_t len, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor - * * @unlimited: %gboolean, allow SVGs of any size - * * @stylesheet: %gchararray, custom CSS + * Exactly as [ctor@Image.svgload], but read from a string. This function + * takes a copy of the string. * - * Exactly as vips_svgload(), but read from a string. This function takes a - * copy of the string. + * ::: tip "Optional arguments" + * * @dpi: %gdouble, render at this DPI + * * @scale: %gdouble, scale render by this factor + * * @unlimited: %gboolean, allow SVGs of any size + * * @stylesheet: %gchararray, custom CSS * - * See also: vips_svgload(). + * ::: seealso + * [ctor@Image.svgload]. * * Returns: 0 on success, -1 on error. */ @@ -1170,9 +1171,10 @@ vips_svgload_string(const char *str, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Exactly as vips_svgload(), but read from a source. + * Exactly as [ctor@Image.svgload], but read from a source. * - * See also: vips_svgload(). + * ::: seealso + * [ctor@Image.svgload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/tiffload.c b/libvips/foreign/tiffload.c index 5286eabf84..b7bdbe5cb4 100644 --- a/libvips/foreign/tiffload.c +++ b/libvips/foreign/tiffload.c @@ -477,17 +477,9 @@ vips_foreign_load_tiff_buffer_init(VipsForeignLoadTiffBuffer *buffer) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Read a TIFF file into a VIPS image. * - * * @page: %gint, load this page - * * @n: %gint, load this many pages - * * @autorotate: %gboolean, use orientation tag to rotate the image - * during load - * * @subifd: %gint, select this subifd index - * * @fail_on: #VipsFailOn, types of read error to fail on - * * @unlimited: %gboolean, remove all denial of service limits - * - * Read a TIFF file into a VIPS image. It is a full baseline TIFF 6 reader, + * It is a full baseline TIFF 6 reader, * with extensions for tiled images, multipage images, XYZ and LAB colour * space, pyramidal images and JPEG compression, including CMYK and YCbCr. * @@ -506,7 +498,7 @@ vips_foreign_load_tiff_buffer_init(VipsForeignLoadTiffBuffer *buffer) * If @autorotate is %FALSE, the metadata field #VIPS_META_ORIENTATION is set * to the value of the orientation tag. Applications may read and interpret * this field - * as they wish later in processing. See vips_autorot(). Save + * as they wish later in processing. See [method@Image.autorot]. Save * operations will use #VIPS_META_ORIENTATION, if present, to set the * orientation of output images. * @@ -532,7 +524,17 @@ vips_foreign_load_tiff_buffer_init(VipsForeignLoadTiffBuffer *buffer) * attached as #VIPS_META_IMAGEDESCRIPTION. Data in the photoshop tag is * attached as #VIPS_META_PHOTOSHOP_NAME. * - * See also: vips_image_new_from_file(), vips_autorot(). + * ::: tip "Optional arguments" + * * @page: %gint, load this page + * * @n: %gint, load this many pages + * * @autorotate: %gboolean, use orientation tag to rotate the image + * during load + * * @subifd: %gint, select this subifd index + * * @fail_on: [enum@FailOn], types of read error to fail on + * * @unlimited: %gboolean, remove all denial of service limits + * + * ::: seealso + * vips_image_new_from_file(), [method@Image.autorot]. * * Returns: 0 on success, -1 on error. */ @@ -556,23 +558,23 @@ vips_tiffload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, load this page - * * @n: %gint, load this many pages - * * @autorotate: %gboolean, use orientation tag to rotate the image - * during load - * * @subifd: %gint, select this subifd index - * * @fail_on: #VipsFailOn, types of read error to fail on - * * @unlimited: %gboolean, remove all denial of service limits - * * Read a TIFF-formatted memory block into a VIPS image. Exactly as - * vips_tiffload(), but read from a memory source. + * [ctor@Image.tiffload], but read from a memory source. * * You must not free the buffer while @out is active. The - * #VipsObject::postclose signal on @out is a good place to free. + * [signal@Object::postclose] signal on @out is a good place to free. + * + * ::: tip "Optional arguments" + * * @page: %gint, load this page + * * @n: %gint, load this many pages + * * @autorotate: %gboolean, use orientation tag to rotate the image + * during load + * * @subifd: %gint, select this subifd index + * * @fail_on: [enum@FailOn], types of read error to fail on + * * @unlimited: %gboolean, remove all denial of service limits * - * See also: vips_tiffload(). + * ::: seealso + * [ctor@Image.tiffload]. * * Returns: 0 on success, -1 on error. */ @@ -602,19 +604,19 @@ vips_tiffload_buffer(void *buf, size_t len, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, load this page - * * @n: %gint, load this many pages - * * @autorotate: %gboolean, use orientation tag to rotate the image - * during load - * * @subifd: %gint, select this subifd index - * * @fail_on: #VipsFailOn, types of read error to fail on - * * @unlimited: %gboolean, remove all denial of service limits + * Exactly as [ctor@Image.tiffload], but read from a source. * - * Exactly as vips_tiffload(), but read from a source. + * ::: tip "Optional arguments" + * * @page: %gint, load this page + * * @n: %gint, load this many pages + * * @autorotate: %gboolean, use orientation tag to rotate the image + * during load + * * @subifd: %gint, select this subifd index + * * @fail_on: [enum@FailOn], types of read error to fail on + * * @unlimited: %gboolean, remove all denial of service limits * - * See also: vips_tiffload(). + * ::: seealso + * [ctor@Image.tiffload]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/tiffsave.c b/libvips/foreign/tiffsave.c index 6de1f84cb0..ea979cde9d 100644 --- a/libvips/foreign/tiffsave.c +++ b/libvips/foreign/tiffsave.c @@ -605,29 +605,6 @@ vips_foreign_save_tiff_buffer_init(VipsForeignSaveTiffBuffer *buffer) * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @compression: use this #VipsForeignTiffCompression - * * @Q: %gint quality factor - * * @predictor: use this #VipsForeignTiffPredictor - * * @tile: %gboolean, set %TRUE to write a tiled tiff - * * @tile_width: %gint for tile size - * * @tile_height: %gint for tile size - * * @pyramid: %gboolean, write an image pyramid - * * @bitdepth: %int, change bit depth to 1,2, or 4 bit - * * @miniswhite: %gboolean, write 1-bit images as MINISWHITE - * * @resunit: #VipsForeignTiffResunit for resolution unit - * * @xres: %gdouble horizontal resolution in pixels/mm - * * @yres: %gdouble vertical resolution in pixels/mm - * * @bigtiff: %gboolean, write a BigTiff file - * * @properties: %gboolean, set %TRUE to write an IMAGEDESCRIPTION tag - * * @region_shrink: #VipsRegionShrink How to shrink each 2x2 region. - * * @level: %gint, Zstd or Deflate (zlib) compression level - * * @lossless: %gboolean, WebP lossless mode - * * @depth: #VipsForeignDzDepth how deep to make the pyramid - * * @subifd: %gboolean write pyr layers as sub-ifds - * * @premultiply: %gboolean write premultiplied alpha - * * Write a VIPS image to a file as TIFF. * * If @in has the #VIPS_META_PAGE_HEIGHT metadata item, this is assumed to be a @@ -712,7 +689,30 @@ vips_foreign_save_tiff_buffer_init(VipsForeignSaveTiffBuffer *buffer) * Set @premultiply to save with premultiplied alpha. Some programs, such as * InDesign, will only work with premultiplied alpha. * - * See also: vips_tiffload(), vips_image_write_to_file(). + * ::: tip "Optional arguments" + * * @compression: use this [enum@ForeignTiffCompression] + * * @Q: %gint quality factor + * * @predictor: use this [enum@ForeignTiffPredictor] + * * @tile: %gboolean, set %TRUE to write a tiled tiff + * * @tile_width: %gint for tile size + * * @tile_height: %gint for tile size + * * @pyramid: %gboolean, write an image pyramid + * * @bitdepth: %int, change bit depth to 1,2, or 4 bit + * * @miniswhite: %gboolean, write 1-bit images as MINISWHITE + * * @resunit: [enum@ForeignTiffResunit] for resolution unit + * * @xres: %gdouble horizontal resolution in pixels/mm + * * @yres: %gdouble vertical resolution in pixels/mm + * * @bigtiff: %gboolean, write a BigTiff file + * * @properties: %gboolean, set %TRUE to write an IMAGEDESCRIPTION tag + * * @region_shrink: [enum@RegionShrink] How to shrink each 2x2 region. + * * @level: %gint, Zstd or Deflate (zlib) compression level + * * @lossless: %gboolean, WebP lossless mode + * * @depth: [enum@ForeignDzDepth] how deep to make the pyramid + * * @subifd: %gboolean write pyr layers as sub-ifds + * * @premultiply: %gboolean write premultiplied alpha + * + * ::: seealso + * [ctor@Image.tiffload], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -736,36 +736,36 @@ vips_tiffsave(VipsImage *in, const char *filename, ...) * @len: (type gsize): return output length here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @compression: use this #VipsForeignTiffCompression - * * @Q: %gint quality factor - * * @predictor: use this #VipsForeignTiffPredictor - * * @tile: %gboolean, set %TRUE to write a tiled tiff - * * @tile_width: %gint for tile size - * * @tile_height: %gint for tile size - * * @pyramid: %gboolean, write an image pyramid - * * @bitdepth: %int, set write bit depth to 1, 2, 4 or 8 - * * @miniswhite: %gboolean, write 1-bit images as MINISWHITE - * * @resunit: #VipsForeignTiffResunit for resolution unit - * * @xres: %gdouble horizontal resolution in pixels/mm - * * @yres: %gdouble vertical resolution in pixels/mm - * * @bigtiff: %gboolean, write a BigTiff file - * * @properties: %gboolean, set %TRUE to write an IMAGEDESCRIPTION tag - * * @region_shrink: #VipsRegionShrink How to shrink each 2x2 region. - * * @level: %gint, Zstd or Deflate (zlib) compression level - * * @lossless: %gboolean, WebP lossless mode - * * @depth: #VipsForeignDzDepth how deep to make the pyramid - * * @subifd: %gboolean write pyr layers as sub-ifds - * * @premultiply: %gboolean write premultiplied alpha - * - * As vips_tiffsave(), but save to a memory buffer. + * As [method@Image.tiffsave], but save to a memory buffer. * * The address of the buffer is returned in @buf, the length of the buffer in - * @len. You are responsible for freeing the buffer with g_free() when you + * @len. You are responsible for freeing the buffer with [func@GLib.free] when you * are done with it. * - * See also: vips_tiffsave(), vips_image_write_to_file(). + * ::: tip "Optional arguments" + * * @compression: use this [enum@ForeignTiffCompression] + * * @Q: %gint quality factor + * * @predictor: use this [enum@ForeignTiffPredictor] + * * @tile: %gboolean, set %TRUE to write a tiled tiff + * * @tile_width: %gint for tile size + * * @tile_height: %gint for tile size + * * @pyramid: %gboolean, write an image pyramid + * * @bitdepth: %int, change bit depth to 1,2, or 4 bit + * * @miniswhite: %gboolean, write 1-bit images as MINISWHITE + * * @resunit: [enum@ForeignTiffResunit] for resolution unit + * * @xres: %gdouble horizontal resolution in pixels/mm + * * @yres: %gdouble vertical resolution in pixels/mm + * * @bigtiff: %gboolean, write a BigTiff file + * * @properties: %gboolean, set %TRUE to write an IMAGEDESCRIPTION tag + * * @region_shrink: [enum@RegionShrink] How to shrink each 2x2 region. + * * @level: %gint, Zstd or Deflate (zlib) compression level + * * @lossless: %gboolean, WebP lossless mode + * * @depth: [enum@ForeignDzDepth] how deep to make the pyramid + * * @subifd: %gboolean write pyr layers as sub-ifds + * * @premultiply: %gboolean write premultiplied alpha + * + * ::: seealso + * [method@Image.tiffsave], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -803,32 +803,32 @@ vips_tiffsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @compression: use this #VipsForeignTiffCompression - * * @Q: %gint quality factor - * * @predictor: use this #VipsForeignTiffPredictor - * * @tile: %gboolean, set %TRUE to write a tiled tiff - * * @tile_width: %gint for tile size - * * @tile_height: %gint for tile size - * * @pyramid: %gboolean, write an image pyramid - * * @bitdepth: %int, set write bit depth to 1, 2, 4 or 8 - * * @miniswhite: %gboolean, write 1-bit images as MINISWHITE - * * @resunit: #VipsForeignTiffResunit for resolution unit - * * @xres: %gdouble horizontal resolution in pixels/mm - * * @yres: %gdouble vertical resolution in pixels/mm - * * @bigtiff: %gboolean, write a BigTiff file - * * @properties: %gboolean, set %TRUE to write an IMAGEDESCRIPTION tag - * * @region_shrink: #VipsRegionShrink How to shrink each 2x2 region. - * * @level: %gint, Zstd or Deflate (zlib) compression level - * * @lossless: %gboolean, WebP lossless mode - * * @depth: #VipsForeignDzDepth how deep to make the pyramid - * * @subifd: %gboolean write pyr layers as sub-ifds - * * @premultiply: %gboolean write premultiplied alpha - * - * As vips_tiffsave(), but save to a target. - * - * See also: vips_tiffsave(), vips_image_write_to_target(). + * As [method@Image.tiffsave], but save to a target. + * + * ::: tip "Optional arguments" + * * @compression: use this [enum@ForeignTiffCompression] + * * @Q: %gint quality factor + * * @predictor: use this [enum@ForeignTiffPredictor] + * * @tile: %gboolean, set %TRUE to write a tiled tiff + * * @tile_width: %gint for tile size + * * @tile_height: %gint for tile size + * * @pyramid: %gboolean, write an image pyramid + * * @bitdepth: %int, change bit depth to 1,2, or 4 bit + * * @miniswhite: %gboolean, write 1-bit images as MINISWHITE + * * @resunit: [enum@ForeignTiffResunit] for resolution unit + * * @xres: %gdouble horizontal resolution in pixels/mm + * * @yres: %gdouble vertical resolution in pixels/mm + * * @bigtiff: %gboolean, write a BigTiff file + * * @properties: %gboolean, set %TRUE to write an IMAGEDESCRIPTION tag + * * @region_shrink: [enum@RegionShrink] How to shrink each 2x2 region. + * * @level: %gint, Zstd or Deflate (zlib) compression level + * * @lossless: %gboolean, WebP lossless mode + * * @depth: [enum@ForeignDzDepth] how deep to make the pyramid + * * @subifd: %gboolean write pyr layers as sub-ifds + * * @premultiply: %gboolean write premultiplied alpha + * + * ::: seealso + * [method@Image.tiffsave], [method@Image.write_to_target]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/vips2jpeg.c b/libvips/foreign/vips2jpeg.c index 9e5226b864..cce1ab2298 100644 --- a/libvips/foreign/vips2jpeg.c +++ b/libvips/foreign/vips2jpeg.c @@ -520,7 +520,7 @@ write_jpeg_block(VipsRegion *region, VipsRect *area, void *a) write->row_pointer[y] = (JSAMPROW) VIPS_REGION_ADDR(region, area->left, area->top + y); - /* Catch any longjmp()s from jpeg_write_scanlines() here. + /* Catch any longjmp()s from jpe[func@GLib.write_scanlines] here. */ if (setjmp(write->eman.jmp)) return -1; diff --git a/libvips/foreign/vipsload.c b/libvips/foreign/vipsload.c index 5678a6cb3a..35d1c170a3 100644 --- a/libvips/foreign/vipsload.c +++ b/libvips/foreign/vipsload.c @@ -329,7 +329,8 @@ vips_foreign_load_vips_source_init(VipsForeignLoadVipsSource *source) * * Read in a vips image. * - * See also: vips_vipssave(). + * ::: seealso + * [method@Image.vipssave]. * * Returns: 0 on success, -1 on error. */ @@ -352,7 +353,7 @@ vips_vipsload(const char *filename, VipsImage **out, ...) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Exactly as vips_vipsload(), but read from a source. + * Exactly as [ctor@Image.vipsload], but read from a source. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/vipssave.c b/libvips/foreign/vipssave.c index 9fbf7edade..b3033955df 100644 --- a/libvips/foreign/vipssave.c +++ b/libvips/foreign/vipssave.c @@ -270,7 +270,8 @@ vips_foreign_save_vips_target_init(VipsForeignSaveVipsTarget *target) * * Write @in to @filename in VIPS format. * - * See also: vips_vipsload(). + * ::: seealso + * [ctor@Image.vipsload]. * * Returns: 0 on success, -1 on error. */ @@ -293,7 +294,7 @@ vips_vipssave(VipsImage *in, const char *filename, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * As vips_vipssave(), but save to a target. + * As [method@Image.vipssave], but save to a target. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/webpload.c b/libvips/foreign/webpload.c index 9a67a31545..b8a1791f51 100644 --- a/libvips/foreign/webpload.c +++ b/libvips/foreign/webpload.c @@ -441,19 +441,13 @@ vips_foreign_load_webp_buffer_init(VipsForeignLoadWebpBuffer *buffer) * @out: (out): decompressed image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages - * * @scale: %gdouble, scale by this much on load - * * Read a WebP file into a VIPS image. * * Use @page to select a page to render, numbering from zero. * * Use @n to select the number of pages to render. The default is 1. Pages are * rendered in a vertical column, with each individual page aligned to the - * left. Set to -1 to mean "until the end of the document". Use vips_grid() + * left. Set to -1 to mean "until the end of the document". Use [method@Image.grid] * to change page layout. * * Use @scale to specify a scale-on-load factor. For example, 2.0 to double @@ -462,7 +456,13 @@ vips_foreign_load_webp_buffer_init(VipsForeignLoadWebpBuffer *buffer) * * The loader supports ICC, EXIF and XMP metadata. * - * See also: vips_image_new_from_file(). + * ::: tip "Optional arguments" + * * @page: %gint, page (frame) to read + * * @n: %gint, load this many pages + * * @scale: %gdouble, scale by this much on load + * + * ::: seealso + * vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ @@ -486,19 +486,19 @@ vips_webpload(const char *filename, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages - * * @scale: %gdouble, scale by this much on load - * * Read a WebP-formatted memory block into a VIPS image. Exactly as - * vips_webpload(), but read from a memory buffer. + * [ctor@Image.webpload], but read from a memory buffer. * * You must not free the buffer while @out is active. The - * #VipsObject::postclose signal on @out is a good place to free. + * [signal@Object::postclose] signal on @out is a good place to free. + * + * ::: tip "Optional arguments" + * * @page: %gint, page (frame) to read + * * @n: %gint, load this many pages + * * @scale: %gdouble, scale by this much on load * - * See also: vips_webpload() + * ::: seealso + * [ctor@Image.webpload] * * Returns: 0 on success, -1 on error. */ @@ -528,15 +528,15 @@ vips_webpload_buffer(void *buf, size_t len, VipsImage **out, ...) * @out: (out): image to write * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages - * * @scale: %gdouble, scale by this much on load + * Exactly as [ctor@Image.webpload], but read from a source. * - * Exactly as vips_webpload(), but read from a source. + * ::: tip "Optional arguments" + * * @page: %gint, page (frame) to read + * * @n: %gint, load this many pages + * * @scale: %gdouble, scale by this much on load * - * See also: vips_webpload() + * ::: seealso + * [ctor@Image.webpload] * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/webpsave.c b/libvips/foreign/webpsave.c index 4a44954e9f..ee2071d26e 100644 --- a/libvips/foreign/webpsave.c +++ b/libvips/foreign/webpsave.c @@ -1170,23 +1170,6 @@ vips_foreign_save_webp_mime_init(VipsForeignSaveWebpMime *mime) * @filename: file to write to * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression - * * @preset: #VipsForeignWebpPreset, choose lossy compression preset - * * @smart_subsample: %gboolean, enables high quality chroma subsampling - * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking filter - * * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q) - * * @alpha_q: %gint, set alpha quality in lossless mode - * * @effort: %gint, level of CPU effort to reduce file size - * * @target_size: %gint, desired target size in bytes - * * @passes: %gint, number of entropy-analysis passes - * * @min_size: %gboolean, minimise size - * * @mixed: %gboolean, allow both lossy and lossless encoding - * * @kmin: %gint, minimum number of frames between keyframes - * * @kmax: %gint, maximum number of frames between keyframes - * * Write an image to a file in WebP format. * * By default, images are saved in lossy format, with @@ -1233,7 +1216,26 @@ vips_foreign_save_webp_mime_init(VipsForeignSaveWebpMime *mime) * Use the metadata items `loop` and `delay` to set the number of * loops for the animation and the frame delays. * - * See also: vips_webpload(), vips_image_write_to_file(). + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @lossless: %gboolean, enables lossless compression + * * @preset: [enum@ForeignWebpPreset], choose lossy compression preset + * * @smart_subsample: %gboolean, enables high quality chroma subsampling + * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking + * filter + * * @near_lossless: %gboolean, preprocess in lossless mode (controlled + * by Q) + * * @alpha_q: %gint, set alpha quality in lossless mode + * * @effort: %gint, level of CPU effort to reduce file size + * * @target_size: %gint, desired target size in bytes + * * @passes: %gint, number of entropy-analysis passes + * * @min_size: %gboolean, minimise size + * * @mixed: %gboolean, allow both lossy and lossless encoding + * * @kmin: %gint, minimum number of frames between keyframes + * * @kmax: %gint, maximum number of frames between keyframes + * + * ::: seealso + * [ctor@Image.webpload], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -1257,30 +1259,32 @@ vips_webpsave(VipsImage *in, const char *filename, ...) * @len: return output length here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression - * * @preset: #VipsForeignWebpPreset, choose lossy compression preset - * * @smart_subsample: %gboolean, enables high quality chroma subsampling - * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking filter - * * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q) - * * @alpha_q: %gint, set alpha quality in lossless mode - * * @effort: %gint, level of CPU effort to reduce file size - * * @target_size: %gint, desired target size in bytes - * * @passes: %gint, number of entropy-analysis passes - * * @min_size: %gboolean, minimise size - * * @mixed: %gboolean, allow both lossy and lossless encoding - * * @kmin: %gint, minimum number of frames between keyframes - * * @kmax: %gint, maximum number of frames between keyframes - * - * As vips_webpsave(), but save to a memory buffer. + * As [method@Image.webpsave], but save to a memory buffer. * * The address of the buffer is returned in @buf, the length of the buffer in - * @len. You are responsible for freeing the buffer with g_free() when you + * @len. You are responsible for freeing the buffer with [func@GLib.free] when you * are done with it. * - * See also: vips_webpsave(). + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @lossless: %gboolean, enables lossless compression + * * @preset: [enum@ForeignWebpPreset], choose lossy compression preset + * * @smart_subsample: %gboolean, enables high quality chroma subsampling + * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking + * filter + * * @near_lossless: %gboolean, preprocess in lossless mode (controlled + * by Q) + * * @alpha_q: %gint, set alpha quality in lossless mode + * * @effort: %gint, level of CPU effort to reduce file size + * * @target_size: %gint, desired target size in bytes + * * @passes: %gint, number of entropy-analysis passes + * * @min_size: %gboolean, minimise size + * * @mixed: %gboolean, allow both lossy and lossless encoding + * * @kmin: %gint, minimum number of frames between keyframes + * * @kmax: %gint, maximum number of frames between keyframes + * + * ::: seealso + * [method@Image.webpsave]. * * Returns: 0 on success, -1 on error. */ @@ -1317,26 +1321,28 @@ vips_webpsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * @in: image to save * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * As [method@Image.webpsave], but save as a mime webp on stdout. * - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression - * * @preset: #VipsForeignWebpPreset, choose lossy compression preset - * * @smart_subsample: %gboolean, enables high quality chroma subsampling - * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking filter - * * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q) - * * @alpha_q: %gint, set alpha quality in lossless mode - * * @effort: %gint, level of CPU effort to reduce file size - * * @target_size: %gint, desired target size in bytes - * * @passes: %gint, number of entropy-analysis passes - * * @min_size: %gboolean, minimise size - * * @mixed: %gboolean, allow both lossy and lossless encoding - * * @kmin: %gint, minimum number of frames between keyframes - * * @kmax: %gint, maximum number of frames between keyframes + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @lossless: %gboolean, enables lossless compression + * * @preset: [enum@ForeignWebpPreset], choose lossy compression preset + * * @smart_subsample: %gboolean, enables high quality chroma subsampling + * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking + * filter + * * @near_lossless: %gboolean, preprocess in lossless mode (controlled + * by Q) + * * @alpha_q: %gint, set alpha quality in lossless mode + * * @effort: %gint, level of CPU effort to reduce file size + * * @target_size: %gint, desired target size in bytes + * * @passes: %gint, number of entropy-analysis passes + * * @min_size: %gboolean, minimise size + * * @mixed: %gboolean, allow both lossy and lossless encoding + * * @kmin: %gint, minimum number of frames between keyframes + * * @kmax: %gint, maximum number of frames between keyframes * - * As vips_webpsave(), but save as a mime webp on stdout. - * - * See also: vips_webpsave(), vips_image_write_to_file(). + * ::: seealso + * [method@Image.webpsave], [method@Image.write_to_file]. * * Returns: 0 on success, -1 on error. */ @@ -1359,26 +1365,28 @@ vips_webpsave_mime(VipsImage *in, ...) * @target: save image to this target * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression - * * @preset: #VipsForeignWebpPreset, choose lossy compression preset - * * @smart_subsample: %gboolean, enables high quality chroma subsampling - * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking filter - * * @near_lossless: %gboolean, preprocess in lossless mode (controlled by Q) - * * @alpha_q: %gint, set alpha quality in lossless mode - * * @effort: %gint, level of CPU effort to reduce file size - * * @target_size: %gint, desired target size in bytes - * * @passes: %gint, number of entropy-analysis passes - * * @min_size: %gboolean, minimise size - * * @mixed: %gboolean, allow both lossy and lossless encoding - * * @kmin: %gint, minimum number of frames between keyframes - * * @kmax: %gint, maximum number of frames between keyframes + * As [method@Image.webpsave], but save to a target. * - * As vips_webpsave(), but save to a target. + * ::: tip "Optional arguments" + * * @Q: %gint, quality factor + * * @lossless: %gboolean, enables lossless compression + * * @preset: [enum@ForeignWebpPreset], choose lossy compression preset + * * @smart_subsample: %gboolean, enables high quality chroma subsampling + * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking + * filter + * * @near_lossless: %gboolean, preprocess in lossless mode (controlled + * by Q) + * * @alpha_q: %gint, set alpha quality in lossless mode + * * @effort: %gint, level of CPU effort to reduce file size + * * @target_size: %gint, desired target size in bytes + * * @passes: %gint, number of entropy-analysis passes + * * @min_size: %gboolean, minimise size + * * @mixed: %gboolean, allow both lossy and lossless encoding + * * @kmin: %gint, minimum number of frames between keyframes + * * @kmax: %gint, maximum number of frames between keyframes * - * See also: vips_webpsave(). + * ::: seealso + * [method@Image.webpsave]. * * Returns: 0 on success, -1 on error. */ From 1db77accf3e2e2a16eb413a9b2519febf8100f7f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 26 Apr 2025 09:54:12 +0100 Subject: [PATCH 138/174] move scRGB2BW on top of ColourCode (#4468) * move scRGB2BW on top of ColourCode saves some alpha messing * move scRGB2sRGB on top of colourcode * do sRGB2scRGB as well * oop, dropped a few bands * try to fix fuzzing --- libvips/colour/colour.c | 2 +- libvips/colour/icc_transform.c | 3 +- libvips/colour/meson.build | 48 +++---- libvips/colour/sRGB2scRGB.c | 239 ++++++--------------------------- libvips/colour/scRGB2BW.c | 205 ++++++++-------------------- libvips/colour/scRGB2sRGB.c | 215 +++++++++-------------------- 6 files changed, 186 insertions(+), 526 deletions(-) diff --git a/libvips/colour/colour.c b/libvips/colour/colour.c index 3bc9d6e2f9..de16cc1cde 100644 --- a/libvips/colour/colour.c +++ b/libvips/colour/colour.c @@ -412,7 +412,7 @@ vips_colour_code_build(VipsObject *object) in = code->in; - /* If this is a LABQ and the coder wants uncoded, unpack. + /* We want labq, rad etc. all decoded (unlike colour_build). */ if (in && code->input_coding == VIPS_CODING_NONE && diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 65243f754e..28922d5d8b 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -928,8 +928,7 @@ decode_xyz(guint16 *fixed, float *xyz, int n) /* Process a buffer of data. */ static void -vips_icc_import_line(VipsColour *colour, - VipsPel *out, VipsPel **in, int width) +vips_icc_import_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) { VipsIcc *icc = (VipsIcc *) colour; diff --git a/libvips/colour/meson.build b/libvips/colour/meson.build index 9e7278f0a9..23ac71dfb1 100644 --- a/libvips/colour/meson.build +++ b/libvips/colour/meson.build @@ -1,43 +1,43 @@ colour_sources = files( - 'profiles.c', - 'profile_load.c', - 'colour.c', 'CMYK2XYZ.c', - 'XYZ2CMYK.c', + 'colour.c', 'colourspace.c', - 'dE76.c', 'dE00.c', + 'dE76.c', 'dECMC.c', + 'float2rad.c', + 'HSV2sRGB.c', 'icc_transform.c', - 'Lab2XYZ.c', + 'Lab2LabQ.c', + 'Lab2LabS.c', 'Lab2LCh.c', + 'Lab2XYZ.c', + 'LabQ2Lab.c', + 'LabQ2LabS.c', + 'LabQ2sRGB.c', + 'LabS2Lab.c', + 'LabS2LabQ.c', 'LCh2Lab.c', 'LCh2UCS.c', + 'profile_load.c', + 'profiles.c', + 'rad2float.c', + 'scRGB2BW.c', + 'scRGB2sRGB.c', + 'scRGB2XYZ.c', + 'sRGB2HSV.c', + 'sRGB2scRGB.c', 'UCS2LCh.c', + 'XYZ2CMYK.c', 'XYZ2Lab.c', + 'XYZ2scRGB.c', 'XYZ2Yxy.c', 'Yxy2XYZ.c', - 'float2rad.c', - 'rad2float.c', - 'Lab2LabQ.c', - 'LabQ2Lab.c', - 'LabS2Lab.c', - 'Lab2LabS.c', - 'LabS2LabQ.c', - 'LabQ2LabS.c', - 'LabQ2sRGB.c', - 'sRGB2scRGB.c', - 'sRGB2HSV.c', - 'HSV2sRGB.c', - 'scRGB2XYZ.c', - 'scRGB2BW.c', - 'XYZ2scRGB.c', - 'scRGB2sRGB.c', -) + ) colour_headers = files( - 'profiles.h', 'pcolour.h', + 'profiles.h', ) libvips_sources += colour_sources diff --git a/libvips/colour/sRGB2scRGB.c b/libvips/colour/sRGB2scRGB.c index f4c8be3a73..0c18247a16 100644 --- a/libvips/colour/sRGB2scRGB.c +++ b/libvips/colour/sRGB2scRGB.c @@ -19,6 +19,8 @@ * - look for RGB16 tag, not just ushort, for the 16-bit path * 24/11/17 lovell * - special path for 3 and 4 band images + * 16/4/25 + * - move on top of ColourCode */ /* @@ -60,31 +62,21 @@ #include "pcolour.h" -/* We can't use VipsColourCode as our parent class. We want to handle - * alpha ourselves so we can get 16 -> 8 bit conversion right. - */ - -typedef struct _VipssRGB2scRGB { - VipsOperation parent_instance; - - VipsImage *in; - VipsImage *out; -} VipssRGB2scRGB; +typedef VipsColourCode VipssRGB2scRGB; +typedef VipsColourCodeClass VipssRGB2scRGBClass; -typedef VipsOperationClass VipssRGB2scRGBClass; +G_DEFINE_TYPE(VipssRGB2scRGB, vips_sRGB2scRGB, VIPS_TYPE_COLOUR_CODE); -G_DEFINE_TYPE(VipssRGB2scRGB, vips_sRGB2scRGB, VIPS_TYPE_OPERATION); - -/* Convert a buffer of 8-bit pixels. - */ static void -vips_sRGB2scRGB_line_8(float *restrict q, VipsPel *restrict p, - int extra_bands, int width) +vips_sRGB2scRGB_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) { - int i, j; + if (colour->in[0]->BandFmt == VIPS_FORMAT_UCHAR) { + float *restrict q; + VipsPel *restrict p; - if (extra_bands == 0) { - for (i = 0; i < width; i++) { + q = (float *) out; + p = in[0]; + for (int i = 0; i < width; i++) { q[0] = vips_v2Y_8[p[0]]; q[1] = vips_v2Y_8[p[1]]; q[2] = vips_v2Y_8[p[2]]; @@ -93,44 +85,13 @@ vips_sRGB2scRGB_line_8(float *restrict q, VipsPel *restrict p, q += 3; } } - else if (extra_bands == 1) { - for (i = 0; i < width; i++) { - q[0] = vips_v2Y_8[p[0]]; - q[1] = vips_v2Y_8[p[1]]; - q[2] = vips_v2Y_8[p[2]]; - q[3] = p[3] / 255.0; - - p += 4; - q += 4; - } - } - else { - for (i = 0; i < width; i++) { - q[0] = vips_v2Y_8[p[0]]; - q[1] = vips_v2Y_8[p[1]]; - q[2] = vips_v2Y_8[p[2]]; + else if (colour->in[0]->BandFmt == VIPS_FORMAT_USHORT) { + float *restrict q; + unsigned short *restrict p; - p += 3; - q += 3; - - for (j = 0; j < extra_bands; j++) - q[j] = p[j] / 255.0; - p += extra_bands; - q += extra_bands; - } - } -} - -/* Convert a buffer of 16-bit pixels. - */ -static void -vips_sRGB2scRGB_line_16(float *restrict q, unsigned short *restrict p, - int extra_bands, int width) -{ - int i, j; - - if (extra_bands == 0) { - for (i = 0; i < width; i++) { + q = (float *) out; + p = (unsigned short *) in[0]; + for (int i = 0; i < width; i++) { q[0] = vips_v2Y_16[p[0]]; q[1] = vips_v2Y_16[p[1]]; q[2] = vips_v2Y_16[p[2]]; @@ -139,162 +100,47 @@ vips_sRGB2scRGB_line_16(float *restrict q, unsigned short *restrict p, q += 3; } } - else if (extra_bands == 1) { - for (i = 0; i < width; i++) { - q[0] = vips_v2Y_16[p[0]]; - q[1] = vips_v2Y_16[p[1]]; - q[2] = vips_v2Y_16[p[2]]; - q[3] = p[3] / 65535.0; - - p += 4; - q += 4; - } - } - else { - for (i = 0; i < width; i++) { - q[0] = vips_v2Y_16[p[0]]; - q[1] = vips_v2Y_16[p[1]]; - q[2] = vips_v2Y_16[p[2]]; - - p += 3; - q += 3; - - for (j = 0; j < extra_bands; j++) - q[j] = p[j] / 65535.0; - p += extra_bands; - q += extra_bands; - } - } -} - -static int -vips_sRGB2scRGB_gen(VipsRegion *out_region, - void *seq, void *a, void *b, gboolean *stop) -{ - VipsRegion *ir = (VipsRegion *) seq; - VipsRect *r = &out_region->valid; - VipsImage *in = ir->im; - - int y; - - if (vips_region_prepare(ir, r)) - return -1; - - VIPS_GATE_START("vips_sRGB2scRGB_gen: work"); - - if (in->BandFmt == VIPS_FORMAT_UCHAR) { - vips_col_make_tables_RGB_8(); - - for (y = 0; y < r->height; y++) { - VipsPel *p = VIPS_REGION_ADDR(ir, r->left, r->top + y); - float *q = (float *) - VIPS_REGION_ADDR(out_region, r->left, r->top + y); - - vips_sRGB2scRGB_line_8(q, p, in->Bands - 3, r->width); - } - } - else { - vips_col_make_tables_RGB_16(); - - for (y = 0; y < r->height; y++) { - VipsPel *p = VIPS_REGION_ADDR(ir, r->left, r->top + y); - float *q = (float *) - VIPS_REGION_ADDR(out_region, r->left, r->top + y); - - vips_sRGB2scRGB_line_16(q, (unsigned short *) p, - in->Bands - 3, r->width); - } - } - - VIPS_GATE_STOP("vips_sRGB2scRGB_gen: work"); - - return 0; + else + g_assert_not_reached(); } static int vips_sRGB2scRGB_build(VipsObject *object) { - VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); - VipssRGB2scRGB *sRGB2scRGB = (VipssRGB2scRGB *) object; - - VipsImage **t = (VipsImage **) vips_object_local_array(object, 2); - - VipsImage *in; - VipsImage *out; - VipsBandFormat format; - - if (VIPS_OBJECT_CLASS(vips_sRGB2scRGB_parent_class)->build(object)) - return -1; - - in = sRGB2scRGB->in; - if (vips_check_bands_atleast(class->nickname, in, 3)) - return -1; - - // we are changing the gamma, so any profile on the image can no longer - // work (and will cause horrible problems in any downstream colour - // handling) - if (vips_copy(in, &t[0], NULL)) - return -1; - in = t[0]; - vips_image_remove(in, VIPS_META_ICC_NAME); + VipsColour *colour = (VipsColour *) object; + VipsColourCode *code = (VipsColourCode *) object; - format = in->Type == VIPS_INTERPRETATION_RGB16 - ? VIPS_FORMAT_USHORT - : VIPS_FORMAT_UCHAR; - if (in->BandFmt != format) { - if (vips_cast(in, &t[1], format, NULL)) - return -1; - in = t[1]; - } - - out = vips_image_new(); - if (vips_image_pipelinev(out, - VIPS_DEMAND_STYLE_THINSTRIP, in, NULL)) { - g_object_unref(out); - return -1; + // input image we want + if (vips_object_argument_isset(object, "in") && + code->in->Type == VIPS_INTERPRETATION_RGB16) { + vips_col_make_tables_RGB_16(); + code->input_format = VIPS_FORMAT_USHORT; } - out->Type = VIPS_INTERPRETATION_scRGB; - out->BandFmt = VIPS_FORMAT_FLOAT; - - if (vips_image_generate(out, - vips_start_one, vips_sRGB2scRGB_gen, vips_stop_one, - in, sRGB2scRGB)) { - g_object_unref(out); - return -1; + else { + vips_col_make_tables_RGB_8(); + code->input_format = VIPS_FORMAT_UCHAR; } + colour->input_bands = 3; - g_object_set(object, "out", out, NULL); + // output image we make + colour->interpretation = VIPS_INTERPRETATION_scRGB; + colour->format = VIPS_FORMAT_FLOAT; + colour->bands = 3; - return 0; + return VIPS_OBJECT_CLASS(vips_sRGB2scRGB_parent_class)->build(object); } static void vips_sRGB2scRGB_class_init(VipssRGB2scRGBClass *class) { - GObjectClass *gobject_class = G_OBJECT_CLASS(class); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsOperationClass *operation_class = VIPS_OPERATION_CLASS(class); - - gobject_class->set_property = vips_object_set_property; - gobject_class->get_property = vips_object_get_property; + VipsColourClass *colour_class = VIPS_COLOUR_CLASS(class); object_class->nickname = "sRGB2scRGB"; object_class->description = _("convert an sRGB image to scRGB"); object_class->build = vips_sRGB2scRGB_build; - operation_class->flags = VIPS_OPERATION_SEQUENTIAL; - - VIPS_ARG_IMAGE(class, "in", 1, - _("Input"), - _("Input image"), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET(VipssRGB2scRGB, in)); - - VIPS_ARG_IMAGE(class, "out", 100, - _("Output"), - _("Output image"), - VIPS_ARGUMENT_REQUIRED_OUTPUT, - G_STRUCT_OFFSET(VipssRGB2scRGB, out)); + colour_class->process_line = vips_sRGB2scRGB_line; } static void @@ -308,14 +154,13 @@ vips_sRGB2scRGB_init(VipssRGB2scRGB *sRGB2scRGB) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Convert an sRGB image to scRGB. The input image can be 8 or 16-bit. + * Convert an sRGB image to scRGB. * - * If the input image is tagged as [enum@Vips.Interpretation.RGB16], any extra - * channels after RGB are divided by 256. Thus, scRGB alpha is - * always 0 - 255.99. + * RGB16 images are also handled. * * ::: seealso - * [method@Image.scRGB2XYZ], [method@Image.scRGB2sRGB], [method@Image.rad2float]. + * [method@Image.scRGB2XYZ], [method@Image.scRGB2sRGB], + * [method@Image.rad2float]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/scRGB2BW.c b/libvips/colour/scRGB2BW.c index 369ad1d66d..49eb52e411 100644 --- a/libvips/colour/scRGB2BW.c +++ b/libvips/colour/scRGB2BW.c @@ -2,6 +2,8 @@ * * 17/4/15 * - from scRGB2BW.c + * 16/4/25 + * - move on top of ColourCode */ /* @@ -43,178 +45,99 @@ #include "pcolour.h" -/* We can't use VipsColourCode as our parent class. We want to handle - * alpha ourselves so we can get 16 -> 8 bit conversion right. - */ - typedef struct _VipsscRGB2BW { - VipsOperation parent_instance; + VipsColourCode parent_instance; - VipsImage *in; - VipsImage *out; int depth; } VipsscRGB2BW; -typedef VipsOperationClass VipsscRGB2BWClass; +typedef VipsColourCodeClass VipsscRGB2BWClass; -G_DEFINE_TYPE(VipsscRGB2BW, vips_scRGB2BW, VIPS_TYPE_OPERATION); +G_DEFINE_TYPE(VipsscRGB2BW, vips_scRGB2BW, VIPS_TYPE_COLOUR_CODE); -/* Process a buffer of data. - */ static void -vips_scRGB2BW_line_8(VipsPel *restrict q, float *restrict p, - int extra_bands, int width) +vips_scRGB2BW_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) { - int i, j; + VipsscRGB2BW *scRGB2BW = (VipsscRGB2BW *) colour; - for (i = 0; i < width; i++) { - float R = p[0]; - float G = p[1]; - float B = p[2]; + if (scRGB2BW->depth == 16) { + unsigned short *restrict q; + float *restrict p; - int g; - int og; + q = (unsigned short *) out; + p = (float *) in[0]; + for (int i = 0; i < width; i++) { + const float R = p[0]; + const float G = p[1]; + const float B = p[2]; - vips_col_scRGB2BW_8(R, G, B, &g, &og); + int g; + int og; + vips_col_scRGB2BW_16(R, G, B, &g, &og); - p += 3; + q[0] = g; - q[0] = g; - - q += 1; - - for (j = 0; j < extra_bands; j++) - q[j] = VIPS_CLIP(0, (int) (p[j] * 255.0), UCHAR_MAX); - p += extra_bands; - q += extra_bands; + p += 3; + q += 1; + } } -} - -static void -vips_scRGB2BW_line_16(unsigned short *restrict q, float *restrict p, - int extra_bands, int width) -{ - int i, j; - - for (i = 0; i < width; i++) { - float R = p[0]; - float G = p[1]; - float B = p[2]; - - int g; - int og; - - vips_col_scRGB2BW_16(R, G, B, &g, &og); - - p += 3; - - q[0] = g; - - q += 1; - - for (j = 0; j < extra_bands; j++) - q[j] = VIPS_CLIP(0, (int) (p[j] * 65535.0), USHRT_MAX); - p += extra_bands; - q += extra_bands; + else { + unsigned char *restrict q; + float *restrict p; + + q = (unsigned char *) out; + p = (float *) in[0]; + for (int i = 0; i < width; i++) { + const float R = p[0]; + const float G = p[1]; + const float B = p[2]; + + int g; + int og; + vips_col_scRGB2BW_8(R, G, B, &g, &og); + + q[0] = g; + + p += 3; + q += 1; + } } } -static int -vips_scRGB2BW_gen(VipsRegion *out_region, - void *seq, void *a, void *b, gboolean *stop) -{ - VipsRegion *ir = (VipsRegion *) seq; - VipsscRGB2BW *scRGB2BW = (VipsscRGB2BW *) b; - VipsRect *r = &out_region->valid; - VipsImage *in = ir->im; - - int y; - - if (vips_region_prepare(ir, r)) - return -1; - - VIPS_GATE_START("vips_scRGB2BW_gen: work"); - - for (y = 0; y < r->height; y++) { - float *p = (float *) - VIPS_REGION_ADDR(ir, r->left, r->top + y); - VipsPel *q = (VipsPel *) - VIPS_REGION_ADDR(out_region, r->left, r->top + y); - - if (scRGB2BW->depth == 16) - vips_scRGB2BW_line_16((unsigned short *) q, p, - in->Bands - 3, r->width); - else - vips_scRGB2BW_line_8(q, p, - in->Bands - 3, r->width); - } - - VIPS_GATE_STOP("vips_scRGB2BW_gen: work"); - - return 0; -} - static int vips_scRGB2BW_build(VipsObject *object) { VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); VipsscRGB2BW *scRGB2BW = (VipsscRGB2BW *) object; + VipsColour *colour = (VipsColour *) object; + VipsColourCode *code = (VipsColourCode *) object; - VipsImage **t = (VipsImage **) vips_object_local_array(object, 2); + // input image we want - VipsImage *in; - VipsBandFormat format; - VipsInterpretation interpretation; - VipsImage *out; - - if (VIPS_OBJECT_CLASS(vips_scRGB2BW_parent_class)->build(object)) - return -1; + code->input_format = VIPS_FORMAT_FLOAT; + colour->input_bands = 3; - in = scRGB2BW->in; - if (vips_check_bands_atleast(class->nickname, in, 3)) - return -1; + // output image we make switch (scRGB2BW->depth) { case 16: - interpretation = VIPS_INTERPRETATION_GREY16; - format = VIPS_FORMAT_USHORT; + colour->interpretation = VIPS_INTERPRETATION_GREY16; + colour->format = VIPS_FORMAT_USHORT; break; case 8: - interpretation = VIPS_INTERPRETATION_B_W; - format = VIPS_FORMAT_UCHAR; + colour->interpretation = VIPS_INTERPRETATION_B_W; + colour->format = VIPS_FORMAT_UCHAR; break; default: - vips_error(class->nickname, - "%s", _("depth must be 8 or 16")); - return -1; - } - - if (vips_cast_float(in, &t[0], NULL)) - return -1; - in = t[0]; - - out = vips_image_new(); - if (vips_image_pipelinev(out, - VIPS_DEMAND_STYLE_THINSTRIP, in, NULL)) { - g_object_unref(out); - return -1; - } - out->Type = interpretation; - out->BandFmt = format; - out->Bands = in->Bands - 2; - - if (vips_image_generate(out, - vips_start_one, vips_scRGB2BW_gen, vips_stop_one, - in, scRGB2BW)) { - g_object_unref(out); + vips_error(class->nickname, "%s", _("depth must be 8 or 16")); return -1; } - g_object_set(object, "out", out, NULL); + colour->bands = 1; - return 0; + return VIPS_OBJECT_CLASS(vips_scRGB2BW_parent_class)->build(object); } static void @@ -222,7 +145,7 @@ vips_scRGB2BW_class_init(VipsscRGB2BWClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS(class); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsOperationClass *operation_class = VIPS_OPERATION_CLASS(class); + VipsColourClass *colour_class = VIPS_COLOUR_CLASS(class); gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; @@ -231,19 +154,7 @@ vips_scRGB2BW_class_init(VipsscRGB2BWClass *class) object_class->description = _("convert scRGB to BW"); object_class->build = vips_scRGB2BW_build; - operation_class->flags = VIPS_OPERATION_SEQUENTIAL; - - VIPS_ARG_IMAGE(class, "in", 1, - _("Input"), - _("Input image"), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET(VipsscRGB2BW, in)); - - VIPS_ARG_IMAGE(class, "out", 100, - _("Output"), - _("Output image"), - VIPS_ARGUMENT_REQUIRED_OUTPUT, - G_STRUCT_OFFSET(VipsscRGB2BW, out)); + colour_class->process_line = vips_scRGB2BW_line; VIPS_ARG_INT(class, "depth", 130, _("Depth"), diff --git a/libvips/colour/scRGB2sRGB.c b/libvips/colour/scRGB2sRGB.c index 82f9793188..efcf25fb61 100644 --- a/libvips/colour/scRGB2sRGB.c +++ b/libvips/colour/scRGB2sRGB.c @@ -27,6 +27,8 @@ * - cut about to make scRGB2sRGB.c * 12/2/15 * - add 16-bit alpha handling + * 16/4/25 + * - move on top of ColourCode */ /* @@ -68,117 +70,65 @@ #include "pcolour.h" -/* We can't use VipsColourCode as our parent class. We want to handle - * alpha ourselves so we can get 16 -> 8 bit conversion right. - */ - typedef struct _VipsscRGB2sRGB { - VipsOperation parent_instance; + VipsColourCode parent_instance; - VipsImage *in; - VipsImage *out; int depth; } VipsscRGB2sRGB; -typedef VipsOperationClass VipsscRGB2sRGBClass; - -G_DEFINE_TYPE(VipsscRGB2sRGB, vips_scRGB2sRGB, VIPS_TYPE_OPERATION); - -/* Process a buffer of data. - */ -static void -vips_scRGB2sRGB_line_8(VipsPel *restrict q, float *restrict p, - int extra_bands, int width) -{ - int i, j; - - for (i = 0; i < width; i++) { - float R = p[0]; - float G = p[1]; - float B = p[2]; - - int r, g, b; - - vips_col_scRGB2sRGB_8(R, G, B, &r, &g, &b, NULL); - - p += 3; +typedef VipsColourCodeClass VipsscRGB2sRGBClass; - q[0] = r; - q[1] = g; - q[2] = b; - - q += 3; - - for (j = 0; j < extra_bands; j++) - q[j] = VIPS_CLIP(0, (int) (p[j] * 255.0), UCHAR_MAX); - p += extra_bands; - q += extra_bands; - } -} +G_DEFINE_TYPE(VipsscRGB2sRGB, vips_scRGB2sRGB, VIPS_TYPE_COLOUR_CODE); static void -vips_scRGB2sRGB_line_16(unsigned short *restrict q, float *restrict p, - int extra_bands, int width) +vips_scRGB2sRGB_line(VipsColour *colour, VipsPel *out, VipsPel **in, int width) { - int i, j; - - for (i = 0; i < width; i++) { - float R = p[0]; - float G = p[1]; - float B = p[2]; - - int r, g, b; + VipsscRGB2sRGB *scRGB2sRGB = (VipsscRGB2sRGB *) colour; - vips_col_scRGB2sRGB_16(R, G, B, &r, &g, &b, NULL); + if (scRGB2sRGB->depth == 16) { + unsigned short *restrict q; + float *restrict p; - p += 3; + q = (unsigned short *) out; + p = (float *) in[0]; + for (int i = 0; i < width; i++) { + const float R = p[0]; + const float G = p[1]; + const float B = p[2]; - q[0] = r; - q[1] = g; - q[2] = b; + int r, g, b; + vips_col_scRGB2sRGB_16(R, G, B, &r, &g, &b, NULL); - q += 3; + q[0] = r; + q[1] = g; + q[2] = b; - for (j = 0; j < extra_bands; j++) - q[j] = VIPS_CLIP(0, (int) (p[j] * 65535.0), USHRT_MAX); - p += extra_bands; - q += extra_bands; + p += 3; + q += 3; + } } -} - -static int -vips_scRGB2sRGB_gen(VipsRegion *out_region, - void *seq, void *a, void *b, gboolean *stop) -{ - VipsRegion *ir = (VipsRegion *) seq; - VipsscRGB2sRGB *scRGB2sRGB = (VipsscRGB2sRGB *) b; - VipsRect *r = &out_region->valid; - VipsImage *in = ir->im; - - int y; - - if (vips_region_prepare(ir, r)) - return -1; - - VIPS_GATE_START("vips_scRGB2sRGB_gen: work"); - - for (y = 0; y < r->height; y++) { - float *p = (float *) - VIPS_REGION_ADDR(ir, r->left, r->top + y); - VipsPel *q = (VipsPel *) - VIPS_REGION_ADDR(out_region, r->left, r->top + y); - - if (scRGB2sRGB->depth == 16) - vips_scRGB2sRGB_line_16((unsigned short *) q, p, - in->Bands - 3, r->width); - else - vips_scRGB2sRGB_line_8(q, p, - in->Bands - 3, r->width); + else { + unsigned char *restrict q; + float *restrict p; + + q = (unsigned char *) out; + p = (float *) in[0]; + for (int i = 0; i < width; i++) { + const float R = p[0]; + const float G = p[1]; + const float B = p[2]; + + int r, g, b; + vips_col_scRGB2sRGB_8(R, G, B, &r, &g, &b, NULL); + + q[0] = r; + q[1] = g; + q[2] = b; + + p += 3; + q += 3; + } } - - VIPS_GATE_STOP("vips_scRGB2sRGB_gen: work"); - - return 0; } static int @@ -186,38 +136,25 @@ vips_scRGB2sRGB_build(VipsObject *object) { VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(object); VipsscRGB2sRGB *scRGB2sRGB = (VipsscRGB2sRGB *) object; + VipsColour *colour = (VipsColour *) object; + VipsColourCode *code = (VipsColourCode *) object; - VipsImage **t = (VipsImage **) vips_object_local_array(object, 2); - - VipsImage *in; - VipsBandFormat format; - VipsInterpretation interpretation; - VipsImage *out; + // input image we want - if (VIPS_OBJECT_CLASS(vips_scRGB2sRGB_parent_class)->build(object)) - return -1; - - in = scRGB2sRGB->in; - if (vips_check_bands_atleast(class->nickname, in, 3)) - return -1; + code->input_format = VIPS_FORMAT_FLOAT; + colour->input_bands = 3; - // we are changing the gamma, so any profile on the image can no longer - // work (and will cause horrible problems in any downstream colour - // handling) - if (vips_copy(in, &t[0], NULL)) - return -1; - in = t[0]; - vips_image_remove(in, VIPS_META_ICC_NAME); + // output image we make switch (scRGB2sRGB->depth) { case 16: - interpretation = VIPS_INTERPRETATION_RGB16; - format = VIPS_FORMAT_USHORT; + colour->interpretation = VIPS_INTERPRETATION_RGB16; + colour->format = VIPS_FORMAT_USHORT; break; case 8: - interpretation = VIPS_INTERPRETATION_sRGB; - format = VIPS_FORMAT_UCHAR; + colour->interpretation = VIPS_INTERPRETATION_sRGB; + colour->format = VIPS_FORMAT_UCHAR; break; default: @@ -225,29 +162,9 @@ vips_scRGB2sRGB_build(VipsObject *object) return -1; } - if (vips_cast_float(in, &t[1], NULL)) - return -1; - in = t[1]; - - out = vips_image_new(); - if (vips_image_pipelinev(out, - VIPS_DEMAND_STYLE_THINSTRIP, in, NULL)) { - g_object_unref(out); - return -1; - } - out->Type = interpretation; - out->BandFmt = format; + colour->bands = 3; - if (vips_image_generate(out, - vips_start_one, vips_scRGB2sRGB_gen, vips_stop_one, - in, scRGB2sRGB)) { - g_object_unref(out); - return -1; - } - - g_object_set(object, "out", out, NULL); - - return 0; + return VIPS_OBJECT_CLASS(vips_scRGB2sRGB_parent_class)->build(object); } static void @@ -255,28 +172,16 @@ vips_scRGB2sRGB_class_init(VipsscRGB2sRGBClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS(class); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsOperationClass *operation_class = VIPS_OPERATION_CLASS(class); + VipsColourClass *colour_class = VIPS_COLOUR_CLASS(class); gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; object_class->nickname = "scRGB2sRGB"; - object_class->description = _("convert an scRGB image to sRGB"); + object_class->description = _("convert scRGB to sRGB"); object_class->build = vips_scRGB2sRGB_build; - operation_class->flags = VIPS_OPERATION_SEQUENTIAL; - - VIPS_ARG_IMAGE(class, "in", 1, - _("Input"), - _("Input image"), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET(VipsscRGB2sRGB, in)); - - VIPS_ARG_IMAGE(class, "out", 100, - _("Output"), - _("Output image"), - VIPS_ARGUMENT_REQUIRED_OUTPUT, - G_STRUCT_OFFSET(VipsscRGB2sRGB, out)); + colour_class->process_line = vips_scRGB2sRGB_line; VIPS_ARG_INT(class, "depth", 130, _("Depth"), From 0407285a19da298283440f18bf4cc4b654c9d106 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 27 Apr 2025 11:51:11 +0100 Subject: [PATCH 139/174] update docs in freqfilt --- libvips/freqfilt/freqfilt.c | 4 ++-- libvips/freqfilt/freqmult.c | 3 ++- libvips/freqfilt/fwfft.c | 3 ++- libvips/freqfilt/invfft.c | 14 ++++++++------ libvips/freqfilt/phasecor.c | 3 ++- libvips/freqfilt/spectrum.c | 6 ++++-- 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/libvips/freqfilt/freqfilt.c b/libvips/freqfilt/freqfilt.c index 463a342e76..7b0603de6c 100644 --- a/libvips/freqfilt/freqfilt.c +++ b/libvips/freqfilt/freqfilt.c @@ -116,8 +116,8 @@ vips_freqfilt_init(VipsFreqfilt *freqfilt) * partial bandjoin -> * output pipeline * - * vips__fftproc() needs to just call VipsFftProcessFn directly for 1 band images, - * so we can't cache the output in this fn. + * vips__fftproc() needs to just call VipsFftProcessFn directly for 1 band + * images, so we can't cache the output in this fn. */ int vips__fftproc(VipsObject *context, diff --git a/libvips/freqfilt/freqmult.c b/libvips/freqfilt/freqmult.c index 8f586d71eb..9e28cb0444 100644 --- a/libvips/freqfilt/freqmult.c +++ b/libvips/freqfilt/freqmult.c @@ -151,7 +151,8 @@ vips_freqmult_init(VipsFreqmult *freqmult) * transformed back to real space. If @in is already a complex image, just * multiply then inverse transform. * - * See also: vips_invfft(), vips_mask_ideal(). + * ::: seealso + * [method@Image.invfft], [ctor@Image.mask_ideal]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/freqfilt/fwfft.c b/libvips/freqfilt/fwfft.c index 6aea0ece14..342368ea2f 100644 --- a/libvips/freqfilt/fwfft.c +++ b/libvips/freqfilt/fwfft.c @@ -370,7 +370,8 @@ vips_fwfft_init(VipsFwfft *fwfft) * VIPS uses the fftw Fourier Transform library. If this library was not * available when VIPS was configured, these functions will fail. * - * See also: vips_invfft(). + * ::: seealso + * [method@Image.invfft]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/freqfilt/invfft.c b/libvips/freqfilt/invfft.c index bd73d33f2a..16347e563e 100644 --- a/libvips/freqfilt/invfft.c +++ b/libvips/freqfilt/invfft.c @@ -284,17 +284,19 @@ vips_invfft_init(VipsInvfft *invfft) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Transform an image from Fourier space to real space. * - * * @real: only output the real part - * - * Transform an image from Fourier space to real space. The result is complex. - * If you are OK with a real result, set @real, it's quicker. + * The result is complex. If you are OK with a real result, set @real, + * it's quicker. * * VIPS uses the fftw Fourier Transform library. If this library was not * available when VIPS was configured, these functions will fail. * - * See also: vips_fwfft(). + * ::: tip "Optional arguments" + * * @real: %gboolean, only output the real part + * + * ::: seealso + * [method@Image.fwfft]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/freqfilt/phasecor.c b/libvips/freqfilt/phasecor.c index f84ef35ea6..c2be7afcf5 100644 --- a/libvips/freqfilt/phasecor.c +++ b/libvips/freqfilt/phasecor.c @@ -129,7 +129,8 @@ vips_phasecor_init(VipsPhasecor *phasecor) * Convert the two input images to Fourier space, calculate phase-correlation, * back to real space. * - * See also: vips_fwfft(), vips_cross_phase(), + * ::: seealso + * [method@Image.fwfft], [method@Image.cross_phase], * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/freqfilt/spectrum.c b/libvips/freqfilt/spectrum.c index 7caf60b531..500f0f4796 100644 --- a/libvips/freqfilt/spectrum.c +++ b/libvips/freqfilt/spectrum.c @@ -115,9 +115,11 @@ vips_spectrum_init(VipsSpectrum *spectrum) * Make a displayable (ie. 8-bit unsigned int) power spectrum. * * If @in is non-complex, it is transformed to Fourier space. Then the - * absolute value is passed through vips_scale() in log mode, and vips_wrap(). + * absolute value is passed through [method@Image.scale] in log mode, and + * [method@Image.wrap]. * - * See also: vips_fwfft(), vips_scale(), vips_wrap(). + * ::: seealso + * [method@Image.fwfft], [method@Image.scale], [method@Image.wrap]. * * Returns: 0 on success, -1 on error. */ From 4a56261f44d805daca3a024fe32effebdeff6ed3 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 27 Apr 2025 12:39:38 +0100 Subject: [PATCH 140/174] revise docs in histogram --- doc/rename.sed | 1 + libvips/histogram/case.c | 7 ++++--- libvips/histogram/hist_cum.c | 3 ++- libvips/histogram/hist_equal.c | 9 ++++----- libvips/histogram/hist_local.c | 10 +++++----- libvips/histogram/hist_match.c | 5 +++-- libvips/histogram/hist_norm.c | 3 ++- libvips/histogram/maplut.c | 10 +++++----- libvips/histogram/percent.c | 5 +++-- libvips/histogram/stdif.c | 30 ++++++++++++++++-------------- 10 files changed, 45 insertions(+), 38 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index a0fab00ddf..7611e9d37d 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -396,6 +396,7 @@ s/vips_\(stats\)()/[method@Image.\1]/g s/vips_\(stdif\)()/[method@Image.\1]/g s/vips_\(subsample\)()/[method@Image.\1]/g s/vips_\(subtract\)()/[method@Image.\1]/g +s/vips_\(switch\)()/[func@Image.\1]/g s/vips_\(tanh\)()/[method@Image.\1]/g s/vips_\(tan\)()/[method@Image.\1]/g s/vips_\(text\)()/[ctor@Image.\1]/g diff --git a/libvips/histogram/case.c b/libvips/histogram/case.c index 109cf7e817..63c9b6e94d 100644 --- a/libvips/histogram/case.c +++ b/libvips/histogram/case.c @@ -290,10 +290,11 @@ vips_casev(VipsImage *index, VipsImage **cases, VipsImage **out, int n, * The output image is the same size as @index. Images in @cases are * expanded to the smallest common format and number of bands. * - * Combine this with vips_switch() to make something like a case statement or - * a multi-way vips_ifthenelse(). + * Combine this with [method@Image.switch] to make something like a case statement or + * a multi-way [method@Image.ifthenelse]. * - * See also: vips_maplut(), vips_switch(), vips_ifthenelse(). + * ::: seealso + * [method@Image.maplut], [method@Image.switch], [method@Image.ifthenelse]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/histogram/hist_cum.c b/libvips/histogram/hist_cum.c index d51588585c..6d71f9a0b3 100644 --- a/libvips/histogram/hist_cum.c +++ b/libvips/histogram/hist_cum.c @@ -174,7 +174,8 @@ vips_hist_cum_init(VipsHistCum *hist_cum) * * Form cumulative histogram. * - * See also: vips_hist_norm(). + * ::: seealso + * [method@Image.hist_norm]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/histogram/hist_equal.c b/libvips/histogram/hist_equal.c index c2f4930bee..7b2c5207fa 100644 --- a/libvips/histogram/hist_equal.c +++ b/libvips/histogram/hist_equal.c @@ -142,15 +142,14 @@ vips_hist_equal_init(VipsHistEqual *equal) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Histogram-equalise @in. * - * * @band: band to equalise - * - * Histogram-equalise @in. Equalise using band @bandno, or if @bandno is -1, + * Equalise using band @bandno, or if @bandno is -1, * equalise bands independently. The output format is always the same as the * input format. * - * See also: + * ::: tip "Optional arguments" + * * @band: %gint, band to equalise * * Returns: 0 on success, -1 on error */ diff --git a/libvips/histogram/hist_local.c b/libvips/histogram/hist_local.c index d0a696d2af..8956cabd70 100644 --- a/libvips/histogram/hist_local.c +++ b/libvips/histogram/hist_local.c @@ -404,10 +404,6 @@ vips_hist_local_init(VipsHistLocal *local) * @height: height of region * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @max_slope: maximum brightening - * * Performs local histogram equalisation on @in using a * window of size @width by @height centered on the input pixel. * @@ -419,7 +415,11 @@ vips_hist_local_init(VipsHistLocal *local) * performed. A value of 3 is often used. Local histogram equalization with * contrast limiting is usually called CLAHE. * - * See also: vips_hist_equal(). + * ::: tip "Optional arguments" + * * @max_slope: %gint, maximum brightening + * + * ::: seealso + * [method@Image.hist_equal]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/histogram/hist_match.c b/libvips/histogram/hist_match.c index 074ece49a6..e6d5a97908 100644 --- a/libvips/histogram/hist_match.c +++ b/libvips/histogram/hist_match.c @@ -186,8 +186,9 @@ vips_hist_match_init(VipsHistMatch *match) * cumulative histograms, @out will be a LUT that adjusts the PDF of the image * from which @in was made to match the PDF of @ref's image. * - * See also: vips_maplut(), vips_hist_find(), vips_hist_norm(), - * vips_hist_cum(). + * ::: seealso + * [method@Image.maplut], [method@Image.hist_find], [method@Image.hist_norm], + * [method@Image.hist_cum]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/histogram/hist_norm.c b/libvips/histogram/hist_norm.c index bd6dc649e8..bf1a36b178 100644 --- a/libvips/histogram/hist_norm.c +++ b/libvips/histogram/hist_norm.c @@ -165,7 +165,8 @@ vips_hist_norm_init(VipsHistNorm *hist_norm) * index, so for example the max for a uchar image becomes 255. * Normalise each band separately. * - * See also: vips_hist_cum(). + * ::: seealso + * [method@Image.hist_cum]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/histogram/maplut.c b/libvips/histogram/maplut.c index c0acb5707c..86f86e2791 100644 --- a/libvips/histogram/maplut.c +++ b/libvips/histogram/maplut.c @@ -779,10 +779,6 @@ vips_maplut_init(VipsMaplut *maplut) * @lut: look-up table * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @band: apply one-band @lut to this band of @in - * * Map an image through another image acting as a LUT (Look Up Table). * The lut may have any type and the output image will be that type. * @@ -804,7 +800,11 @@ vips_maplut_init(VipsMaplut *maplut) * separately. If @in has one band, then @lut may have many bands and * the output will have the same number of bands as @lut. * - * See also: vips_hist_find(), vips_identity(). + * ::: tip "Optional arguments" + * * @band: %gint, apply one-band @lut to this band of @in + * + * ::: seealso + * [method@Image.hist_find], [ctor@Image.identity]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/histogram/percent.c b/libvips/histogram/percent.c index 258d99d7b9..f07b77641b 100644 --- a/libvips/histogram/percent.c +++ b/libvips/histogram/percent.c @@ -138,7 +138,7 @@ vips_percent_init(VipsPercent *percent) * @threshold: (out): output threshold value * @...: %NULL-terminated list of optional named arguments * - * vips_percent() returns (through the @threshold parameter) the threshold + * [method@Image.percent] returns (through the @threshold parameter) the threshold * below which there are @percent values of @in. For example: * * |[ @@ -151,7 +151,8 @@ vips_percent_init(VipsPercent *percent) * The function works for uchar and ushort images only. It can be used * to threshold the scaled result of a filtering operation. * - * See also: vips_hist_find(), vips_profile(). + * ::: seealso + * [method@Image.hist_find], [method@Image.profile]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/histogram/stdif.c b/libvips/histogram/stdif.c index 0d73b4603b..5e637df867 100644 --- a/libvips/histogram/stdif.c +++ b/libvips/histogram/stdif.c @@ -366,25 +366,20 @@ vips_stdif_init(VipsStdif *stdif) * @height: height of region * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * [method@Image.stdif] performs statistical differencing according to the + * formula given in page 45 of the book "An Introduction to Digital Image + * Processing" by Wayne Niblack. * - * * @a: weight of new mean - * * @m0: target mean - * * @b: weight of new deviation - * * @s0: target deviation - * - * vips_stdif() performs statistical differencing according to the formula - * given in page 45 of the book "An Introduction to Digital Image - * Processing" by Wayne Niblack. This transformation emphasises the way in + * This transformation emphasises the way in * which a pel differs statistically from its neighbours. It is useful for * enhancing low-contrast images with lots of detail, such as X-ray plates. * * At point (i,j) the output is given by the equation: * - * |[ + * ``` * vout(i,j) = @a * @m0 + (1 - @a) * meanv + * (vin(i,j) - meanv) * (@b * @s0) / (@s0 + @b * stdv) - * ]| + * ``` * * Values @a, @m0, @b and @s0 are entered, while meanv and stdv are the values * calculated over a moving window of size @width, @height centred on pixel @@ -393,15 +388,22 @@ vips_stdif_init(VipsStdif *stdif) * * Try: * - * |[ + * ``` * vips stdif $VIPSHOME/pics/huysum.v fred.v 0.5 128 0.5 50 11 11 - * ]| + * ``` * * The operation works on one-band uchar images only, and writes a one-band * uchar image as its result. The output image has the same size as the * input. * - * See also: vips_hist_local(). + * ::: tip "Optional arguments" + * * @a: %gdouble, weight of new mean + * * @m0: %gdouble, target mean + * * @b: %gdouble, weight of new deviation + * * @s0: %gdouble, target deviation + * + * ::: seealso + * [method@Image.hist_local]. * * Returns: 0 on success, -1 on error */ From 6505b0c3f0da0a9a6bd8ba0690129b7e7f48f37b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 27 Apr 2025 12:40:08 +0100 Subject: [PATCH 141/174] oops, dropped a file --- libvips/histogram/case.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libvips/histogram/case.c b/libvips/histogram/case.c index 63c9b6e94d..826a155201 100644 --- a/libvips/histogram/case.c +++ b/libvips/histogram/case.c @@ -290,8 +290,8 @@ vips_casev(VipsImage *index, VipsImage **cases, VipsImage **out, int n, * The output image is the same size as @index. Images in @cases are * expanded to the smallest common format and number of bands. * - * Combine this with [method@Image.switch] to make something like a case statement or - * a multi-way [method@Image.ifthenelse]. + * Combine this with [func@Image.switch] to make something like a case + * statement or a multi-way [method@Image.ifthenelse]. * * ::: seealso * [method@Image.maplut], [method@Image.switch], [method@Image.ifthenelse]. From dfffacc981e30c147f6d155bd3303d59679011ec Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 27 Apr 2025 12:40:43 +0100 Subject: [PATCH 142/174] still dropped --- libvips/histogram/case.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvips/histogram/case.c b/libvips/histogram/case.c index 826a155201..42df9fb16f 100644 --- a/libvips/histogram/case.c +++ b/libvips/histogram/case.c @@ -294,7 +294,7 @@ vips_casev(VipsImage *index, VipsImage **cases, VipsImage **out, int n, * statement or a multi-way [method@Image.ifthenelse]. * * ::: seealso - * [method@Image.maplut], [method@Image.switch], [method@Image.ifthenelse]. + * [method@Image.maplut], [func@Image.switch], [method@Image.ifthenelse]. * * Returns: 0 on success, -1 on error */ From dc483a17d134178801c8c4e3d4c7d03a06ea71c2 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 27 Apr 2025 13:42:39 +0100 Subject: [PATCH 143/174] revise docs in morphology --- doc/rename.sed | 3 +++ libvips/morphology/countlines.c | 3 ++- libvips/morphology/labelregions.c | 18 ++++++++++-------- libvips/morphology/morph.c | 13 +++++++------ libvips/morphology/nearest.c | 11 ++++++----- libvips/morphology/rank.c | 8 +++++--- 6 files changed, 33 insertions(+), 23 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index 7611e9d37d..4dde4aed87 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -4,6 +4,8 @@ s/vips_\(error_thaw\)/apple_\1_apple/g s/vips_\(error_buffer\)/apple_\1_apple/g s/vips_\(image_new\)/apple_\1_apple/g s/vips_\(target_new_to_memory\)/apple_\1_apple/g +s/vips_\(vector_isenabled\)/apple_\1_apple/g +s/vips_\(vector_set_enabled\)/apple_\1_apple/g s/vips_\(.*\)_get_type/apple_\1_get_type_apple/g s/See also: \([^.]\)/::: seealso\n * \1/g @@ -489,6 +491,7 @@ s/#VIPS_OPERATION_ROUND_\([^ ,.]*\)/[enum@Vips.OperationRound.\1]/g s/#VIPS_OPERATION_COMPLEX_\([^ ,.]*\)/[enum@Vips.OperationComplex.\1]/g s/#VIPS_OPERATION_COMPLEX2_\([^ ,.]*\)/[enum@Vips.OperationComplex2.\1]/g s/#VIPS_OPERATION_COMPLEXGET_\([^ ,.]*\)/[enum@Vips.OperationComplexget.\1]/g +s/#VIPS_OPERATION_MORPHOLOGY_\([^ ,.]*\)/[enum@Vips.OperationMorphology.\1]/g s/#VIPS_OPERATION_\([^ ,.]*\)/[flags@Vips.OperationFlags.\1]/g s/#VIPS_FORMAT_\([^ ,.]*\)/[enum@Vips.BandFormat.\1]/g s/#VIPS_PRECISION_\([^ ,.]*\)/[enum@Vips.Precision.\1]/g diff --git a/libvips/morphology/countlines.c b/libvips/morphology/countlines.c index 265fc8d4ad..0a1ccf85ba 100644 --- a/libvips/morphology/countlines.c +++ b/libvips/morphology/countlines.c @@ -169,7 +169,8 @@ vips_countlines_init(VipsCountlines *countlines) * Xsize or Ysize and returns the mean of the result * Input should be one band, 8-bit. * - * See also: vips_morph(), vips_conv(). + * ::: seealso + * [method@Image.morph], [method@Image.conv]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/morphology/labelregions.c b/libvips/morphology/labelregions.c index a30f50d574..79162559cc 100644 --- a/libvips/morphology/labelregions.c +++ b/libvips/morphology/labelregions.c @@ -145,9 +145,7 @@ vips_labelregions_init(VipsLabelregions *labelregions) * @mask: write labelled regions here * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @segments: return number of regions found here + * Label regions of equal pixels in an image. * * Repeatedly scans @in for regions of 4-connected pixels * with the same pixel value. Every time a region is discovered, those @@ -155,16 +153,20 @@ vips_labelregions_init(VipsLabelregions *labelregions) * have been labelled, the operation returns, setting @segments to the number * of discrete regions which were detected. * - * @mask is always a 1-band #VIPS_FORMAT_INT image of the same dimensions as - * @in. + * @mask is always a 1-band [enum@Vips.BandFormat.INT] image of the same + * dimensions as @in. * * This operation is useful for, for example, blob counting. You can use the * morphological operators to detect and isolate a series of objects, then use - * vips_labelregions() to number them all. + * [method@Image.labelregions] to number them all. + * + * Use [method@Image.hist_find_indexed] to (for example) find blob coordinates. * - * Use vips_hist_find_indexed() to (for example) find blob coordinates. + * ::: tip "Optional arguments" + * * @segments: %gint, return number of regions found here * - * See also: vips_hist_find_indexed(). + * ::: seealso + * [method@Image.hist_find_indexed]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/morphology/morph.c b/libvips/morphology/morph.c index 8752a4817d..aeaf83fe7c 100644 --- a/libvips/morphology/morph.c +++ b/libvips/morphology/morph.c @@ -114,7 +114,8 @@ typedef struct { * * More like hit-miss, really. * - * See also: vips_morph(). + * ::: seealso + * [method@Image.morph]. */ typedef struct { @@ -1007,21 +1008,21 @@ vips_morph_init(VipsMorph *morph) * based on the book "Fundamentals of Digital Image Processing" by A. Jain, * pp 384-388, Prentice-Hall, 1989. * - * For #VIPS_OPERATION_MORPHOLOGY_ERODE, + * For [enum@Vips.OperationMorphology.ERODE], * the whole mask must match for the output pixel to be * set, that is, the result is the logical AND of the selected input pixels. * - * For #VIPS_OPERATION_MORPHOLOGY_DILATE, + * For [enum@Vips.OperationMorphology.DILATE], * the output pixel is set if any part of the mask * matches, that is, the result is the logical OR of the selected input pixels. * - * See the boolean operations vips_andimage(), vips_orimage() and - * vips_eorimage() + * See the boolean operations [method@Image.andimage], [method@Image.orimage] + * and [method@Image.eorimage] * for analogues of the usual set difference and set union operations. * * Operations are performed using the processor's vector unit, * if possible. Disable this with `--vips-novector` or `VIPS_NOVECTOR` or - * vips_vector_set_enabled() + * [func@vector_set_enabled]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/morphology/nearest.c b/libvips/morphology/nearest.c index 768a2d87f5..5243c0cf10 100644 --- a/libvips/morphology/nearest.c +++ b/libvips/morphology/nearest.c @@ -329,10 +329,6 @@ vips_fill_nearest_init(VipsFillNearest *nearest) * @out: image with zero pixels filled with the nearest non-zero pixel * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @distance: output image of distance to nearest non-zero pixel - * * Fill outwards from every non-zero pixel in @in, setting pixels in @distance * and @value. * @@ -343,7 +339,12 @@ vips_fill_nearest_init(VipsFillNearest *nearest) * @distance is a one-band float image. @value has the same number of bands and * format as @in. * - * See also: vips_hist_find_indexed(). + * ::: tip "Optional arguments" + * * @distance: [class@Image], output image of distance to nearest + * non-zero pixel + * + * ::: seealso + * [method@Image.hist_find_indexed]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/morphology/rank.c b/libvips/morphology/rank.c index 2151084f75..b18766b12f 100644 --- a/libvips/morphology/rank.c +++ b/libvips/morphology/rank.c @@ -605,7 +605,7 @@ vips_rank_init(VipsRank *rank) * @index: select pixel * @...: %NULL-terminated list of optional named arguments * - * vips_rank() does rank filtering on an image. A window of size @width by + * [method@Image.rank] does rank filtering on an image. A window of size @width by * @height is passed over the image. At each position, the pixels inside the * window are sorted into ascending order and the pixel at position @index is * output. @index numbers from 0. @@ -622,7 +622,8 @@ vips_rank_init(VipsRank *rank) * The special cases n == 0 and n == m * m - 1 are useful dilate and * expand operators. * - * See also: vips_conv(), vips_median(), vips_spcor(). + * ::: seealso + * [method@Image.conv], [method@Image.median], [method@Image.spcor]. * * Returns: 0 on success, -1 on error */ @@ -651,7 +652,8 @@ vips_rank(VipsImage *in, VipsImage **out, * * vips_rank(in, out, size, size, (size * size) / 2); * - * See also: vips_rank(). + * ::: seealso + * [method@Image.rank]. * * Returns: 0 on success, -1 on error */ From 847790afbf4c2e65c658d5cbe2abf81779b26b6b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 27 Apr 2025 14:51:13 +0100 Subject: [PATCH 144/174] reformats docs in mosaicing --- doc/rename.sed | 3 +++ libvips/mosaicing/chkpair.c | 7 ++++--- libvips/mosaicing/global_balance.c | 22 ++++++++++---------- libvips/mosaicing/match.c | 13 ++++++------ libvips/mosaicing/matrixinvert.c | 16 ++++++++------- libvips/mosaicing/matrixmultiply.c | 3 ++- libvips/mosaicing/merge.c | 10 +++++----- libvips/mosaicing/mosaic.c | 32 +++++++++++++++--------------- libvips/mosaicing/mosaic1.c | 18 ++++++++--------- libvips/mosaicing/mosaicing.c | 2 ++ libvips/mosaicing/remosaic.c | 11 +++++----- 11 files changed, 73 insertions(+), 64 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index 4dde4aed87..f99c301ab4 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -2,6 +2,9 @@ s/vips_\(amiMSBfirst\)/apple_\1_apple/g s/vips_\(error_freeze\)/apple_\1_apple/g s/vips_\(error_thaw\)/apple_\1_apple/g s/vips_\(error_buffer\)/apple_\1_apple/g +s/vips_\(error_clear\)/apple_\1_apple/g +s/vips_\(_make_blend_luts\)/apple_\1_apple/g +s/vips_\(clinear\)/apple_\1_apple/g s/vips_\(image_new\)/apple_\1_apple/g s/vips_\(target_new_to_memory\)/apple_\1_apple/g s/vips_\(vector_isenabled\)/apple_\1_apple/g diff --git a/libvips/mosaicing/chkpair.c b/libvips/mosaicing/chkpair.c index d1e9284b2f..7bcf6faf6b 100644 --- a/libvips/mosaicing/chkpair.c +++ b/libvips/mosaicing/chkpair.c @@ -82,10 +82,11 @@ * * Only the first band of each image is correlated. @ref and @sec may be * very large --- the function extracts and generates just the - * parts needed. Correlation is done with vips_spcor(); the position of - * the maximum is found with vips_max(). + * parts needed. Correlation is done with [method@Image.spcor]; the position + * of the maximum is found with [method@Image.max]. * - * See also: vips_match(), vips__lrmosaic(). + * ::: seealso + * [method@Image.match], [method@Image.mosaic]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/mosaicing/global_balance.c b/libvips/mosaicing/global_balance.c index c3e7152bd6..65f52823ad 100644 --- a/libvips/mosaicing/global_balance.c +++ b/libvips/mosaicing/global_balance.c @@ -1608,7 +1608,7 @@ find_factors(SymbolTable *st, double gamma) #ifdef DEBUG /* Diagnostics! */ - printf("debugging output for vips_global_balance():\n"); + printf("debugging output for vips_globalbalance():\n"); for (i = 0; i < st->nim; i++) printf("balance factor %d = %g\n", i, st->fac[i]); total = 0.0; @@ -1953,12 +1953,7 @@ vips_globalbalance_init(VipsGlobalbalance *globalbalance) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @gamma: gamma of source images - * * @int_output: %TRUE for integer image output - * - * vips_globalbalance() can be used to remove contrast differences in + * [method@Image.globalbalance] can be used to remove contrast differences in * an assembled mosaic. * * It reads the History field attached to @in and builds a list of the source @@ -1973,16 +1968,21 @@ vips_globalbalance_init(VipsGlobalbalance *globalbalance) * 1.0 will stop this. * * Each of the source images is transformed with the appropriate correction - * factor, then the mosaic is reassembled. @out is #VIPS_FORMAT_FLOAT, but - * if @int_output is set, the output image is the same format as the input - * images. + * factor, then the mosaic is reassembled. @out is + * [enum@Vips.BandFormat.FLOAT], but if @int_output is set, the output image + * is the same format as the input images. * * There are some conditions that must be met before this operation can work: * the source images must all be present under the filenames recorded in the * history on @in, and the mosaic must have been built using only operations in * this package. * - * See also: vips_remosaic(). + * ::: tip "Optional arguments" + * * @gamma: %gdouble, gamma of source images + * * @int_output: %gboolean, %TRUE for integer image output + * + * ::: seealso + * [method@Image.mosaic]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/mosaicing/match.c b/libvips/mosaicing/match.c index 783e343c20..8ca669b91e 100644 --- a/libvips/mosaicing/match.c +++ b/libvips/mosaicing/match.c @@ -317,13 +317,6 @@ vips_match_init(VipsMatch *match) * @ys2: second secondary tie-point * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @search: search to improve tie-points - * * @hwindow: half window size - * * @harea: half search size - * * @interpolate: interpolate pixels with this - * * Scale, rotate and translate @sec so that the tie-points line up. * * If @search is %TRUE, before performing the transformation, the tie-points @@ -332,6 +325,12 @@ vips_match_init(VipsMatch *match) * * This function will only work well for small rotates and scales. * + * ::: tip "Optional arguments" + * * @search: %gboolean, search to improve tie-points + * * @hwindow: %gint, half window size + * * @harea: %gint, half search size + * * @interpolate: [class@Interpolate], interpolate pixels with this + * * Returns: 0 on success, -1 on error */ int diff --git a/libvips/mosaicing/matrixinvert.c b/libvips/mosaicing/matrixinvert.c index b2d389ba93..02bce4de2d 100644 --- a/libvips/mosaicing/matrixinvert.c +++ b/libvips/mosaicing/matrixinvert.c @@ -91,18 +91,18 @@ vips_matrixinvert_dispose(GObject *gobject) * lu_decomp: * @mat: matrix to decompose * - * This function takes any square NxN #VipsImage. - * It returns a #VipsImage which is (N+1)xN. + * This function takes any square NxN [class@Image]. + * It returns a [class@Image] which is (N+1)xN. * * It calculates the PLU decomposition, storing the upper and diagonal parts * of U, together with the lower parts of L, as an NxN matrix in the first * N rows of the new matrix. The diagonal parts of L are all set to unity * and are not stored. * - * The final row of the new #VipsImage has only integer entries, which + * The final row of the new [class@Image] has only integer entries, which * represent the row-wise permutations made by the permutation matrix P. * - * The scale and offset members of the input #VipsImage are ignored. + * The scale and offset members of the input [class@Image] are ignored. * * See: * @@ -220,7 +220,7 @@ lu_decomp(VipsImage *mat) * @vec: name for output matrix * * Solve the system of linear equations Ax=b, where matrix A has already - * been decomposed into LU form in VipsImage *lu. Input vector b is in + * been decomposed into LU form in @lu. Input vector b is in * vec and is overwritten with vector x. * * See: @@ -228,7 +228,8 @@ lu_decomp(VipsImage *mat) * PRESS, W. et al, 1992. Numerical Recipes in C; The Art of Scientific * Computing, 2nd ed. Cambridge: Cambridge University Press, pp. 43-50. * - * See also: vips__matrixtranspose(), vips__matrixmultiply(). + * ::: seealso + * [method@Image.matrixmultiply]. * * Returns: 0 on success, -1 on error */ @@ -466,7 +467,8 @@ vips_matrixinvert_init(VipsMatrixinvert *matrix) * This operation calculates the inverse of the matrix represented in @m. * The scale and offset members of the input matrix are ignored. * - * See also: vips_matrixload(). + * ::: seealso + * [ctor@Image.matrixload], [method@Image.matrixmultiply]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/mosaicing/matrixmultiply.c b/libvips/mosaicing/matrixmultiply.c index b95e62336a..9c62675ea3 100644 --- a/libvips/mosaicing/matrixmultiply.c +++ b/libvips/mosaicing/matrixmultiply.c @@ -178,7 +178,8 @@ vips_matrixmultiply_init(VipsMatrixmultiply *matrix) * * The scale and offset members of @left and @right are ignored. * - * See also: vips_matrixinvert(). + * ::: seealso + * [method@Image.matrixinvert]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/mosaicing/merge.c b/libvips/mosaicing/merge.c index dbbba076c2..b8c7368b72 100644 --- a/libvips/mosaicing/merge.c +++ b/libvips/mosaicing/merge.c @@ -181,10 +181,6 @@ vips_merge_init(VipsMerge *merge) * @dy: displacement of ref from sec * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @mblend: %gint, maximum blend size - * * This operation joins two images left-right (with @ref on the left) or * up-down (with @ref above) with a smooth seam. * @@ -209,7 +205,11 @@ vips_merge_init(VipsMerge *merge) * is, zero pixels in the overlap area do not contribute to the merge. * This makes it possible to join non-rectangular images. * - * See also: vips_mosaic(), vips_insert(). + * ::: tip "Optional arguments" + * * @mblend: %gint, maximum blend size + * + * ::: seealso + * [method@Image.mosaic], [method@Image.insert]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/mosaicing/mosaic.c b/libvips/mosaicing/mosaic.c index bb04a05cf0..be7cdce97b 100644 --- a/libvips/mosaicing/mosaic.c +++ b/libvips/mosaicing/mosaic.c @@ -320,19 +320,6 @@ vips_mosaic_init(VipsMosaic *mosaic) * @ysec: position in secondary image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @bandno: %gint, band to search for features - * * @hwindow: %gint, half window size - * * @harea: %gint, half search size - * * @mblend: %gint, maximum blend size - * * @dx0: %gint, output, detected displacement - * * @dy0: %gint, output, detected displacement - * * @scale1: %gdouble, output, detected first order scale - * * @angle1: %gdouble, output, detected first order rotation - * * @dx1: %gdouble, output, detected first order displacement - * * @dy1: %gdouble, output, detected first order displacement - * * This operation joins two images left-right (with @ref on the left) or * top-bottom (with @ref above) given an approximate overlap. * @@ -346,13 +333,26 @@ vips_mosaic_init(VipsMosaic *mosaic) * fit are discarded, and the model refitted until either too few points * remain or the model reaches good agreement. * - * The detected displacement is used with vips_merge() to join the two images - * together. + * The detected displacement is used with [method@Image.merge] to join the + * two images together. * * You can read out the detected transform with @dx0, @dy0, @scale1, @angle1, * @dx1, @dy1. * - * See also: vips_merge(), vips_insert(). + * ::: tip "Optional arguments" + * * @bandno: %gint, band to search for features + * * @hwindow: %gint, half window size + * * @harea: %gint, half search size + * * @mblend: %gint, maximum blend size + * * @dx0: %gint, output, detected displacement + * * @dy0: %gint, output, detected displacement + * * @scale1: %gdouble, output, detected first order scale + * * @angle1: %gdouble, output, detected first order rotation + * * @dx1: %gdouble, output, detected first order displacement + * * @dy1: %gdouble, output, detected first order displacement + * + * ::: seealso + * [method@Image.merge], [method@Image.insert]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/mosaicing/mosaic1.c b/libvips/mosaicing/mosaic1.c index a0871c4c5b..44b5f56f53 100644 --- a/libvips/mosaicing/mosaic1.c +++ b/libvips/mosaicing/mosaic1.c @@ -641,14 +641,6 @@ vips_mosaic1_init(VipsMosaic1 *mosaic1) * @ys2: second secondary tie-point * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @search: search to improve tie-points - * * @hwindow: half window size - * * @harea: half search size - * * @interpolate: interpolate pixels with this - * * @mblend: maximum blend size - * * This operation joins two images top-bottom (with @sec on the right) * or left-right (with @sec at the bottom) * given an approximate pair of tie-points. @sec is scaled and rotated as @@ -675,7 +667,15 @@ vips_mosaic1_init(VipsMosaic1 *mosaic1) * Smallest common format in * [arithmetic](libvips-arithmetic.html)). * - * See also: vips_merge(), vips_insert(), vips_globalbalance(). + * ::: tip "Optional arguments" + * * @search: %gboolean, search to improve tie-points + * * @hwindow: %gint, half window size + * * @harea: %gint, half search size + * * @interpolate: [class@Interpolate], interpolate pixels with this + * * @mblend: %gint, maximum blend size + * + * ::: seealso + * [method@Image.merge], [method@Image.insert], [method@Image.globalbalance]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/mosaicing/mosaicing.c b/libvips/mosaicing/mosaicing.c index b214b9112f..f9cc8e682a 100644 --- a/libvips/mosaicing/mosaicing.c +++ b/libvips/mosaicing/mosaicing.c @@ -58,6 +58,7 @@ vips_mosaicing_operation_init(void) extern GType vips_globalbalance_get_type(void); extern GType vips_matrixinvert_get_type(void); extern GType vips_matrixmultiply_get_type(void); + extern GType vips_remosaic_get_type(void); vips_merge_get_type(); vips_mosaic_get_type(); @@ -66,4 +67,5 @@ vips_mosaicing_operation_init(void) vips_matrixmultiply_get_type(); vips_match_get_type(); vips_globalbalance_get_type(); + vips_remosaic_get_type(); } diff --git a/libvips/mosaicing/remosaic.c b/libvips/mosaicing/remosaic.c index 7e141bc8d5..f0cdd83bfd 100644 --- a/libvips/mosaicing/remosaic.c +++ b/libvips/mosaicing/remosaic.c @@ -200,18 +200,19 @@ vips_remosaic_init(VipsRemosaic *remosaic) * @new_str: gamma of source images * @...: %NULL-terminated list of optional named arguments * - * vips_remosaic() works rather as vips_globalbalance(). It takes apart the - * mosaiced image @in and rebuilds it, substituting images. + * [method@Image.remosaic] works rather as [method@Image.globalbalance]. It + * takes apart the mosaiced image @in and rebuilds it, substituting images. * - * Unlike vips_globalbalance(), images are substituted based on their file‐ - * names. The rightmost occurrence of the string @old_str is swapped + * Unlike [method@Image.globalbalance], images are substituted based on their + * filenames. The rightmost occurrence of the string @old_str is swapped * for @new_str, that file is opened, and that image substituted for * the old image. * * It's convenient for multispectral images. You can mosaic one band, then * use that mosaic as a template for mosaicing the others automatically. * - * See also: vips_globalbalance(). + * ::: seealso + * [method@Image.globalbalance]. * * Returns: 0 on success, -1 on error */ From c0f79708a6c3c77c60f50504223e8b401f7d051f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 27 Apr 2025 15:49:27 +0100 Subject: [PATCH 145/174] rework doc comments in resample --- doc/rename.sed | 5 ++ libvips/resample/affine.c | 55 +++++++------- libvips/resample/interpolate.c | 9 ++- libvips/resample/mapim.c | 37 +++++----- libvips/resample/nohalo.cpp | 2 +- libvips/resample/quadratic.c | 78 +++++++++++--------- libvips/resample/reduce.c | 19 ++--- libvips/resample/reduceh.cpp | 18 +++-- libvips/resample/reducev.cpp | 18 +++-- libvips/resample/resample.c | 3 +- libvips/resample/resize.c | 36 ++++----- libvips/resample/shrink.c | 19 ++--- libvips/resample/shrinkh.c | 16 ++-- libvips/resample/shrinkv.c | 15 ++-- libvips/resample/similarity.c | 53 +++++++------- libvips/resample/thumbnail.c | 129 +++++++++++++++++---------------- 16 files changed, 275 insertions(+), 237 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index f99c301ab4..6c08db2ba4 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -406,6 +406,9 @@ s/vips_\(tanh\)()/[method@Image.\1]/g s/vips_\(tan\)()/[method@Image.\1]/g s/vips_\(text\)()/[ctor@Image.\1]/g s/vips_\(thumbnail_image\)()/[method@Image.\1]/g +s/vips_\(thumbnail_buffer\)()/[ctor@Image.\1]/g +s/vips_\(thumbnail_source\)()/[ctor@Image.\1]/g +s/vips_\(thumbnail\)()/[ctor@Image.\1]/g s/vips_\(tiffsave_buffer\)()/[method@Image.\1]/g s/vips_\(tiffsave\)()/[method@Image.\1]/g s/vips_\(tiffsave_target\)()/[method@Image.\1]/g @@ -438,6 +441,7 @@ s/vips_\(zoom\)()/[method@Image.\1]/g s/vips_\([^(]*\)()/[func@\1]/g +s/#Vips\(Kernel\)/[enum@\1]/g s/#Vips\(SdfShape\)/[enum@\1]/g s/#Vips\(CombineMode\)/[enum@\1]/g s/#Vips\(Access\)/[enum@\1]/g @@ -486,6 +490,7 @@ s/#Vips\(ThreadpoolProgressFn\)/[callback@\1]/g s/#VIPS_COMBINE_MODE_\([^ ,.]*\)/[enum@Vips.CombineMode.\1]/g s/#VIPS_SDF_SHAPE_\([^ ,.]*\)/[enum@Vips.SdfShape.\1]/g +s/#VIPS_KERNEL_\([^ ,.]*\)/[enum@Vips.Kernel.\1]/g s/#VIPS_OPERATION_MATH_\([^ ,.]*\)/[enum@Vips.OperationMath.\1]/g s/#VIPS_OPERATION_MATH2_\([^ ,.]*\)/[enum@Vips.OperationMath2.\1]/g s/#VIPS_OPERATION_RELATIONAL_\([^ ,.]*\)/[enum@Vips.OperationRelational.\1]/g diff --git a/libvips/resample/affine.c b/libvips/resample/affine.c index 5e757161d9..7207779591 100644 --- a/libvips/resample/affine.c +++ b/libvips/resample/affine.c @@ -727,31 +727,22 @@ vips_affine_init(VipsAffine *affine) * @d: transformation matrix coefficient * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @interpolate: #VipsInterpolate, interpolate pixels with this - * * @oarea: #VipsArrayInt, output rectangle - * * @idx: %gdouble, input horizontal offset - * * @idy: %gdouble, input vertical offset - * * @odx: %gdouble, output horizontal offset - * * @ody: %gdouble, output vertical offset - * * @extend: #VipsExtend how to generate new pixels - * * @background: #VipsArrayDouble colour for new pixels - * * @premultiplied: %gboolean, images are already premultiplied - * * This operator performs an affine transform on an image using @interpolate. * * The transform is: * - * |[ - * X = @a * (x + @idx) + @b * (y + @idy) + @odx - * Y = @c * (x + @idx) + @d * (y + @idy) + @doy + * ``` + * X = @a * (x + @idx) + @b * (y + @idy) + @odx + * Y = @c * (x + @idx) + @d * (y + @idy) + @doy + * ``` * - * where: - * x and y are the coordinates in input image. - * X and Y are the coordinates in output image. - * (0,0) is the upper left corner. - * ]| + * where: + * + * ``` + * x and y are the coordinates in input image. + * X and Y are the coordinates in output image. + * (0,0) is the upper left corner. + * ``` * * The section of the output space defined by @oarea is written to * @out. @oarea is a four-element int array of left, top, width, height. @@ -759,21 +750,33 @@ vips_affine_init(VipsAffine *affine) * transformed input image. * * By default, new pixels are filled with @background. This defaults to - * zero (black). You can set other extend types with @extend. #VIPS_EXTEND_COPY - * is better for image upsizing. + * zero (black). You can set other extend types with @extend. + * [enum@Vips.Extend.COPY] is better for image upsizing. * * @interpolate defaults to bilinear. * * @idx, @idy, @odx, @ody default to zero. * - * Image are normally treated as unpremultiplied, so this operation can be used - * directly on PNG images. If your images have been through vips_premultiply(), - * set @premultiplied. + * Image are normally treated as unpremultiplied, so this operation can be + * used directly on PNG images. If your images have been through + * [method@Image.premultiply], set @premultiplied. * * This operation does not change xres or yres. The image resolution needs to * be updated by the application. * - * See also: vips_shrink(), vips_resize(), #VipsInterpolate. + * ::: tip "Optional arguments" + * * @interpolate: [class@Interpolate], interpolate pixels with this + * * @oarea: [struct@ArrayInt], output rectangle + * * @idx: %gdouble, input horizontal offset + * * @idy: %gdouble, input vertical offset + * * @odx: %gdouble, output horizontal offset + * * @ody: %gdouble, output vertical offset + * * @extend: [enum@Extend], how to generate new pixels + * * @background: [struct@ArrayDouble] colour for new pixels + * * @premultiplied: %gboolean, images are already premultiplied + * + * ::: seealso + * [method@Image.shrink], [method@Image.resize], [class@Interpolate]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/resample/interpolate.c b/libvips/resample/interpolate.c index 7d3c86d70b..df3da9c97b 100644 --- a/libvips/resample/interpolate.c +++ b/libvips/resample/interpolate.c @@ -90,7 +90,8 @@ G_DEFINE_ABSTRACT_TYPE(VipsInterpolate, vips_interpolate, VIPS_TYPE_OBJECT); * * The interpolated value should be written to the pixel pointed to by @out. * - * See also: [struct@VipsInterpolateClass]. + * ::: seealso + * [struct@VipsInterpolateClass]. */ /** @@ -119,7 +120,8 @@ G_DEFINE_ABSTRACT_TYPE(VipsInterpolate, vips_interpolate, VIPS_TYPE_OBJECT); * You also need to set [property@VipsObject:nickname] and * [property@VipsObject:description] in [class@Object]. * - * See also: [callback@InterpolateMethod], [class@Object] or + * ::: seealso + * [callback@InterpolateMethod], [class@Object] or * [func@Interpolate.bilinear_static]. */ @@ -641,7 +643,8 @@ vips__interpolate_init(void) * Look up an interpolator from a nickname and make one. You need to free the * result with [method@GObject.Object.unref] when you're done with it. * - * See also: [func@type_find]. + * ::: seealso + * [func@type_find]. * * Returns: an interpolator, or `NULL` on error. */ diff --git a/libvips/resample/mapim.c b/libvips/resample/mapim.c index 4a5786733e..6ca97eb4a8 100644 --- a/libvips/resample/mapim.c +++ b/libvips/resample/mapim.c @@ -600,27 +600,21 @@ vips_mapim_init(VipsMapim *mapim) * @index: index image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * This operator resamples @in using @index to look up pixels. * - * * @interpolate: interpolate pixels with this - * * @extend: #VipsExtend how to generate new pixels - * * @background: #VipsArrayDouble colour for new pixels - * * @premultiplied: %gboolean, images are already premultiplied + * @out is the same size as @index, with each pixel being fetched from that + * position in @in. That is: * - * This operator resamples @in using @index to look up pixels. @out is - * the same size as @index, with each pixel being fetched from that position in - * @in. That is: - * - * |[ + * ``` * out[x, y] = in[index[x, y]] - * ]| + * ``` * * If @index has one band, that band must be complex. Otherwise, @index must * have two bands of any format. * * Coordinates in @index are in pixels, with (0, 0) being the top-left corner - * of @in, and with y increasing down the image. Use vips_xyz() to build index - * images. + * of @in, and with y increasing down the image. Use [ctor@Image.xyz] to + * build index images. * * @interpolate defaults to bilinear. * @@ -629,16 +623,23 @@ vips_mapim_init(VipsMapim *mapim) * is better for image upsizing. * * Image are normally treated as unpremultiplied, so this operation can be used - * directly on PNG images. If your images have been through vips_premultiply(), - * set @premultiplied. + * directly on PNG images. If your images have been through + * [method@Image.premultiply], set @premultiplied. * * This operation does not change xres or yres. The image resolution needs to * be updated by the application. * - * See vips_maplut() for a 1D equivalent of this operation. + * See [method@Image.maplut] for a 1D equivalent of this operation. + * + * ::: tip "Optional arguments" + * * @interpolate: [class@Interpolate], interpolate pixels with this + * * @extend: [enum@Vips.Extend], how to generate new pixels + * * @background: [struct@ArrayDouble], colour for new pixels + * * @premultiplied: %gboolean, images are already premultiplied * - * See also: vips_xyz(), vips_affine(), vips_resize(), - * vips_maplut(), #VipsInterpolate. + * ::: seealso + * [ctor@Image.xyz], [method@Image.affine], [method@Image.resize], + * [method@Image.maplut], [class@Interpolate]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/resample/nohalo.cpp b/libvips/resample/nohalo.cpp index 8096a2aefc..92f1e01ea1 100644 --- a/libvips/resample/nohalo.cpp +++ b/libvips/resample/nohalo.cpp @@ -230,7 +230,7 @@ * http://doi.acm.org/10.1145/1557626.1557657. */ -/* Uncomment to enable bounds checking for VIPS_REGION_ADDR(). +/* Uncomment to enable bounds checking for [func@REGION_ADDR]. */ #define DEBUG diff --git a/libvips/resample/quadratic.c b/libvips/resample/quadratic.c index 144eae325c..8635676639 100644 --- a/libvips/resample/quadratic.c +++ b/libvips/resample/quadratic.c @@ -53,38 +53,6 @@ #include "presample.h" -/* The transform we compute: - -x', y' = coordinates of srcim -x, y = coordinates of dstim -a .. l = coefficients - -x = x' + a : order 0 image shift only - + b x' + c y' : order 1 + affine transf. - + d x' y' : order 2 + bilinear transf. - + e x' x' + f y' y' : order 3 + quadratic transf. - -y = y' + g - + h y' + i x' - + j y' x' - + k y' y' + l x' x' - -input matrix: - - a g - -- - b h - c i - -- - d j - -- - e k - f l - -matrix height may be 1, 3, 4, 6 - - */ - typedef struct _VipsQuadratic { VipsResample parent_instance; @@ -375,13 +343,51 @@ vips_quadratic_init(VipsQuadratic *quadratic) * @coeff: horizontal quadratic * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Transform an image with a 0, 1, 2, or 3rd order polynomial. + * + * The transform we compute: + * + * ``` + * x = x' + a : order 0 image shift only + * + b x' + c y' : order 1 + affine transf. + * + d x' y' : order 2 + bilinear transf. + * + e x' x' + f y' y' : order 3 + quadratic transf. + * + * y = y' + g + * + h y' + i x' + * + j y' x' + * + k y' y' + l x' x' + * ``` + * + * where: + * + * ``` + * x', y' = coordinates of srcim + * x, y = coordinates of dstim + * a .. l = coefficients + * ``` + * + * The coefficients are in the input matrix, ordered as: + * + * ``` + * a g + * -- + * b h + * c i + * -- + * d j + * -- + * e k + * f l + * ``` * - * * @interpolate: use this interpolator (default bilinear) + * The matrix height may be 1, 3, 4, 6 * - * This operation is unfinished and unusable, sorry. + * ::: tip "Optional arguments" + * * @interpolate: use this interpolator (default bilinear) * - * See also: vips_affine(). + * ::: seealso + * [method@Image.affine]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/resample/reduce.c b/libvips/resample/reduce.c index b1c5f773ec..07b8f48341 100644 --- a/libvips/resample/reduce.c +++ b/libvips/resample/reduce.c @@ -206,26 +206,27 @@ vips_reduce_init(VipsReduce *reduce) * @vshrink: vertical shrink * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Reduce @in by a pair of factors with a pair of 1D kernels. * - * * @kernel: #VipsKernel to use to interpolate (default: lanczos3) - * * @gap: reducing gap to use (default: 0.0) + * This will not work well for shrink factors greater than three. * - * Reduce @in by a pair of factors with a pair of 1D kernels. This - * will not work well for shrink factors greater than three. - * - * Set @gap to speed up reducing by having vips_shrink() to shrink + * Set @gap to speed up reducing by having [method@Image.shrink] to shrink * with a box filter first. The bigger @gap, the closer the result * to the fair resampling. The smaller @gap, the faster resizing. * The default value is 0.0 (no optimization). * - * This is a very low-level operation: see vips_resize() for a more + * This is a very low-level operation: see [method@Image.resize] for a more * convenient way to resize images. * * This operation does not change xres or yres. The image resolution needs to * be updated by the application. * - * See also: vips_shrink(), vips_resize(), vips_affine(). + * ::: tip "Optional arguments" + * * @kernel: [enum@Kernel], kernel to interpolate with (default: lanczos3) + * * @gap: reducing gap to use (default: 0.0) + * + * ::: seealso + * [method@Image.shrink], [method@Image.resize], [method@Image.affine]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/resample/reduceh.cpp b/libvips/resample/reduceh.cpp index 7933f9f6e0..f9b3247f80 100644 --- a/libvips/resample/reduceh.cpp +++ b/libvips/resample/reduceh.cpp @@ -636,26 +636,28 @@ vips_reduceh_init(VipsReduceh *reduceh) * @hshrink: horizontal reduce * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Reduce @in horizontally by a float factor. * - * * @kernel: #VipsKernel to use to interpolate (default: lanczos3) - * * @gap: reducing gap to use (default: 0.0) - * - * Reduce @in horizontally by a float factor. The pixels in @out are + * The pixels in @out are * interpolated with a 1D mask generated by @kernel. * - * Set @gap to speed up reducing by having vips_shrinkh() to shrink + * Set @gap to speed up reducing by having [method@Image.shrinkh] to shrink * with a box filter first. The bigger @gap, the closer the result * to the fair resampling. The smaller @gap, the faster resizing. * The default value is 0.0 (no optimization). * - * This is a very low-level operation: see vips_resize() for a more + * This is a very low-level operation: see [method@Image.resize] for a more * convenient way to resize images. * * This operation does not change xres or yres. The image resolution needs to * be updated by the application. * - * See also: vips_shrink(), vips_resize(), vips_affine(). + * ::: tip "Optional arguments" + * * @kernel: [enum@Kernel], to use to interpolate (default: lanczos3) + * * @gap: %gboolean, reducing gap to use (default: 0.0) + * + * ::: seealso + * [method@Image.shrink], [method@Image.resize], [method@Image.affine]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/resample/reducev.cpp b/libvips/resample/reducev.cpp index 7bead22733..5fd5afd57d 100644 --- a/libvips/resample/reducev.cpp +++ b/libvips/resample/reducev.cpp @@ -1120,26 +1120,28 @@ vips_reducev_init(VipsReducev *reducev) * @vshrink: vertical reduce * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Reduce @in vertically by a float factor. * - * * @kernel: #VipsKernel to use to interpolate (default: lanczos3) - * * @gap: reducing gap to use (default: 0.0) - * - * Reduce @in vertically by a float factor. The pixels in @out are + * The pixels in @out are * interpolated with a 1D mask generated by @kernel. * - * Set @gap to speed up reducing by having vips_shrinkv() to shrink + * Set @gap to speed up reducing by having [method@Image.shrinkv] to shrink * with a box filter first. The bigger @gap, the closer the result * to the fair resampling. The smaller @gap, the faster resizing. * The default value is 0.0 (no optimization). * - * This is a very low-level operation: see vips_resize() for a more + * This is a very low-level operation: see [method@Image.resize] for a more * convenient way to resize images. * * This operation does not change xres or yres. The image resolution needs to * be updated by the application. * - * See also: vips_shrink(), vips_resize(), vips_affine(). + * ::: tip "Optional arguments" + * * @kernel: [enum@Kernel], to use to interpolate (default: lanczos3) + * * @gap: %gboolean, reducing gap to use (default: 0.0) + * + * ::: seealso + * [method@Image.shrink], [method@Image.resize], [method@Image.affine]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/resample/resample.c b/libvips/resample/resample.c index 1b4155dc5b..c13ec6f6a8 100644 --- a/libvips/resample/resample.c +++ b/libvips/resample/resample.c @@ -62,7 +62,8 @@ * Controls whether an operation should upsize, downsize, both up and * downsize, or force a size. * - * See also: vips_thumbnail(). + * ::: seealso + * [ctor@Image.thumbnail]. */ G_DEFINE_ABSTRACT_TYPE(VipsResample, vips_resample, VIPS_TYPE_OPERATION); diff --git a/libvips/resample/resize.c b/libvips/resample/resize.c index 0b488e6b92..4a949bf40e 100644 --- a/libvips/resample/resize.c +++ b/libvips/resample/resize.c @@ -370,7 +370,7 @@ vips_resize_class_init(VipsResizeClass *class) G_STRUCT_OFFSET(VipsResize, idy), -10000000.0, 10000000.0, 0.0); - /* It's a kernel now we use vips_reduce() not vips_affine(). + /* It's a kernel now we use vips_reduce() not [method@Image.affine]. */ VIPS_ARG_INTERPOLATE(class, "interpolate", 2, _("Interpolate"), @@ -402,29 +402,25 @@ vips_resize_init(VipsResize *resize) * @scale: scale factor * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @vscale: %gdouble vertical scale factor - * * @kernel: #VipsKernel to reduce with - * * @gap: reducing gap to use (default: 2.0) - * * Resize an image. * - * Set @gap to speed up downsizing by having vips_shrink() to shrink + * Set @gap to speed up downsizing by having [method@Image.shrink] to shrink * with a box filter first. The bigger @gap, the closer the result * to the fair resampling. The smaller @gap, the faster resizing. * The default value is 2.0 (very close to fair resampling * while still being faster in many cases). * - * vips_resize() normally uses #VIPS_KERNEL_LANCZOS3 for the final reduce, you - * can change this with @kernel. Downsizing is done with centre convention. + * [method@Image.resize] normally uses [enum@Vips.Kernel.LANCZOS3] for the final + * reduce, you can change this with @kernel. Downsizing is done with centre + * convention. * - * When upsizing (@scale > 1), the operation uses vips_affine() with - * a #VipsInterpolate selected depending on @kernel. It will use - * #VipsInterpolateBicubic for #VIPS_KERNEL_CUBIC and above. It adds a - * 0.5 pixel displacement to the input pixels to get centre convention scaling. + * When upsizing (@scale > 1), the operation uses [method@Image.affine] with + * a [class@Interpolate] selected depending on @kernel. It will use + * [class@Interpolate] "bicubic" for [enum@Vips.Kernel.CUBIC] and above. It + * adds a 0.5 pixel displacement to the input pixels to get centre convention + * scaling. * - * vips_resize() normally maintains the image aspect ratio. If you set + * [method@Image.resize] normally maintains the image aspect ratio. If you set * @vscale, that factor is used for the vertical scale and @scale for the * horizontal. * @@ -436,9 +432,15 @@ vips_resize_init(VipsResize *resize) * be updated by the application. * * This operation does not premultiply alpha. If your image has an alpha - * channel, you should use vips_premultiply() on it first. + * channel, you should use [method@Image.premultiply] on it first. + * + * ::: tip "optional arguments" + * * @vscale: %gdouble, vertical scale factor + * * @kernel: [enum@Kernel], to reduce with + * * @gap: %gdouble, reducing gap to use (default: 2.0) * - * See also: vips_premultiply(), vips_shrink(), vips_reduce(). + * ::: seealso + * [method@Image.premultiply], [method@Image.shrink], [method@Image.reduce]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/resample/shrink.c b/libvips/resample/shrink.c index 7b0e13982b..c013f39b02 100644 --- a/libvips/resample/shrink.c +++ b/libvips/resample/shrink.c @@ -189,22 +189,23 @@ vips_shrink_init(VipsShrink *shrink) * @vshrink: vertical shrink * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Shrink @in by a pair of factors with a simple box filter. * - * * @ceil: round-up output dimensions + * For non-integer factors, [method@Image.shrink] will first shrink by the + * integer part with a box filter, then use [method@Image.reduce] to shrink + * by the remaining fractional part. * - * Shrink @in by a pair of factors with a simple box filter. For non-integer - * factors, vips_shrink() will first shrink by the integer part with a box - * filter, then use vips_reduce() to shrink by the - * remaining fractional part. - * - * This is a very low-level operation: see vips_resize() for a more + * This is a very low-level operation: see [method@Image.resize] for a more * convenient way to resize images. * * This operation does not change xres or yres. The image resolution needs to * be updated by the application. * - * See also: vips_resize(), vips_reduce(). + * ::: tip "Optional arguments" + * * @ceil: %gboolean, round-up output dimensions + * + * ::: seealso + * [method@Image.resize], [method@Image.reduce]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/resample/shrinkh.c b/libvips/resample/shrinkh.c index ebcdea7aa2..88229ba277 100644 --- a/libvips/resample/shrinkh.c +++ b/libvips/resample/shrinkh.c @@ -468,20 +468,22 @@ vips_shrinkh_init(VipsShrinkh *shrink) * @hshrink: horizontal shrink * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @ceil: round-up output dimensions - * - * Shrink @in horizontally by an integer factor. Each pixel in the output is + * Shrink @in horizontally by an integer factor. + * Each pixel in the output is * the average of the corresponding line of @hshrink pixels in the input. * - * This is a very low-level operation: see vips_resize() for a more + * This is a very low-level operation: see [method@Image.resize] for a more * convenient way to resize images. * * This operation does not change xres or yres. The image resolution needs to * be updated by the application. * - * See also: vips_shrinkv(), vips_shrink(), vips_resize(), vips_affine(). + * ::: tip "Optional arguments" + * * @ceil: %gboolean, round-up output dimensions + * + * ::: seealso + * [method@Image.shrinkv], [method@Image.shrink], [method@Image.resize], + * [method@Image.affine]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/resample/shrinkv.c b/libvips/resample/shrinkv.c index cb24936233..ec8e13f53c 100644 --- a/libvips/resample/shrinkv.c +++ b/libvips/resample/shrinkv.c @@ -545,20 +545,23 @@ vips_shrinkv_init(VipsShrinkv *shrink) * @vshrink: vertical shrink * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Shrink @in vertically by an integer factor. * - * * @ceil: round-up output dimensions - * - * Shrink @in vertically by an integer factor. Each pixel in the output is + * Each pixel in the output is * the average of the corresponding column of @vshrink pixels in the input. * - * This is a very low-level operation: see vips_resize() for a more + * This is a very low-level operation: see [method@Image.resize] for a more * convenient way to resize images. * * This operation does not change xres or yres. The image resolution needs to * be updated by the application. * - * See also: vips_shrinkh(), vips_shrink(), vips_resize(), vips_affine(). + * ::: tip "Optional arguments" + * * @ceil: %gboolean, round-up output dimensions + * + * ::: seealso + * [method@Image.shrinkh], [method@Image.shrink], [method@Image.resize], + * [method@Image.affine]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/resample/similarity.c b/libvips/resample/similarity.c index 3508df846a..770ad55a41 100644 --- a/libvips/resample/similarity.c +++ b/libvips/resample/similarity.c @@ -1,4 +1,4 @@ -/* simple wrapper over vips_affine() to make scale / rotate easy from the +/* simple wrapper over [method@Image.affine] to make scale / rotate easy from the * command-line * * 3/10/13 @@ -222,22 +222,22 @@ vips_similarity_init(VipsSimilarity *similarity) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * This operator calls [method@Image.affine] for you, calculating the matrix + * for the affine transform from @scale and @angle. Other parameters are + * passed on to [method@Image.affine] unaltered. * - * * @scale: %gdouble, scale by this factor - * * @angle: %gdouble, rotate by this many degrees clockwise - * * @interpolate: #VipsInterpolate, interpolate pixels with this - * * @background: #VipsArrayDouble colour for new pixels - * * @idx: %gdouble, input horizontal offset - * * @idy: %gdouble, input vertical offset - * * @odx: %gdouble, output horizontal offset - * * @ody: %gdouble, output vertical offset + * ::: tip "Optional arguments" + * * @scale: %gdouble, scale by this factor + * * @angle: %gdouble, rotate by this many degrees clockwise + * * @interpolate: [class@Interpolate], interpolate pixels with this + * * @background: [struct@ArrayDouble] colour for new pixels + * * @idx: %gdouble, input horizontal offset + * * @idy: %gdouble, input vertical offset + * * @odx: %gdouble, output horizontal offset + * * @ody: %gdouble, output vertical offset * - * This operator calls vips_affine() for you, calculating the matrix for the - * affine transform from @scale and @angle. Other parameters are passed on to - * vips_affine() unaltered. - * - * See also: vips_affine(), #VipsInterpolate. + * ::: seealso + * [method@Image.affine], [class@Interpolate]. * * Returns: 0 on success, -1 on error */ @@ -292,20 +292,21 @@ vips_rotate_init(VipsRotate *rotate) * @angle: %gdouble, rotate by this many degrees clockwise * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * This operator calls [method@Image.affine] for you, calculating the matrix + * for the affine transform from @scale and @angle. * - * * @interpolate: #VipsInterpolate, interpolate pixels with this - * * @background: #VipsArrayDouble colour for new pixels - * * @idx: %gdouble, input horizontal offset - * * @idy: %gdouble, input vertical offset - * * @odx: %gdouble, output horizontal offset - * * @ody: %gdouble, output vertical offset + * Other parameters are passed on to [method@Image.affine] unaltered. * - * This operator calls vips_affine() for you, calculating the matrix for the - * affine transform from @scale and @angle. Other parameters are passed on to - * vips_affine() unaltered. + * ::: tip "Optional arguments" + * * @interpolate: [class@Interpolate], interpolate pixels with this + * * @background: [struct@ArrayDouble], colour for new pixels + * * @idx: %gdouble, input horizontal offset + * * @idy: %gdouble, input vertical offset + * * @odx: %gdouble, output horizontal offset + * * @ody: %gdouble, output vertical offset * - * See also: vips_affine(), #VipsInterpolate. + * ::: seealso + * [method@Image.affine], [class@Interpolate]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/resample/thumbnail.c b/libvips/resample/thumbnail.c index f8830434ff..63cb706485 100644 --- a/libvips/resample/thumbnail.c +++ b/libvips/resample/thumbnail.c @@ -486,7 +486,7 @@ vips_thumbnail_find_jpegshrink(VipsThumbnail *thumbnail, /* Shrink-on-load is a simple block shrink and will add quite a bit of * extra sharpness to the image. We want to block shrink to a - * bit above our target, then vips_shrink() / vips_reduce() to the + * bit above our target, then vips_shrink / vips_reduce() to the * final size. * * Leave at least a factor of two for the final resize step. @@ -1214,26 +1214,16 @@ vips_thumbnail_file_init(VipsThumbnailFile *file) * @width: target width in pixels * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Make a thumbnail from a file. * - * * @height: %gint, target height in pixels - * * @size: #VipsSize, upsize, downsize, both or force - * * @no_rotate: %gboolean, don't rotate upright using orientation tag - * * @crop: #VipsInteresting, shrink and crop to fill target - * * @linear: %gboolean, perform shrink in linear light - * * @import_profile: %gchararray, fallback import ICC profile - * * @export_profile: %gchararray, export ICC profile - * * @intent: #VipsIntent, rendering intent - * * @fail_on: #VipsFailOn, load error types to fail on - * - * Make a thumbnail from a file. Shrinking is done in three stages: using any + * Shrinking is done in three stages: using any * shrink-on-load features available in the file import library, using a block * shrink, and using a lanczos3 shrink. At least the final 200% is done with * lanczos3. The output should be high quality, and the operation should be * quick. * - * See vips_thumbnail_buffer() to thumbnail from a memory buffer, or - * vips_thumbnail_source() to thumbnail from an arbitrary byte source. + * See [ctor@Image.thumbnail_buffer] to thumbnail from a memory buffer, or + * [ctor@Image.thumbnail_source] to thumbnail from an arbitrary byte source. * * By default, libvips will only use the first frame of animated or multipage * images. To thumbnail all pages or frames, pass `n=-1` to the loader in @@ -1244,7 +1234,7 @@ vips_thumbnail_file_init(VipsThumbnailFile *file) * @height to a very large number to ignore that dimension. * * If you set @crop, then the output image will fill the whole of the @width x - * @height rectangle, with any excess cropped away. See vips_smartcrop() for + * @height rectangle, with any excess cropped away. See [method@Image.smartcrop] for * details on the cropping strategy. * * Normally the operation will upsize or downsize as required to fit the image @@ -1278,7 +1268,19 @@ vips_thumbnail_file_init(VipsThumbnailFile *file) * Use @fail_on to control the types of error that will cause loading to fail. * The default is #VIPS_FAIL_ON_NONE, ie. thumbnail is permissive. * - * See also: vips_thumbnail_buffer(). + * ::: tip "Optional arguments" + * * @height: %gint, target height in pixels + * * @size: [enum@Size], upsize, downsize, both or force + * * @no_rotate: %gboolean, don't rotate upright using orientation tag + * * @crop: [enum@Interesting], shrink and crop to fill target + * * @linear: %gboolean, perform shrink in linear light + * * @import_profile: %gchararray, fallback import ICC profile + * * @export_profile: %gchararray, export ICC profile + * * @intent: [enum@Intent], rendering intent + * * @fail_on: [enum@FailOn], load error types to fail on + * + * ::: seealso + * [ctor@Image.thumbnail_buffer]. * * Returns: 0 on success, -1 on error. */ @@ -1469,24 +1471,25 @@ vips_thumbnail_buffer_init(VipsThumbnailBuffer *buffer) * @width: target width in pixels * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: + * Exactly as [ctor@Image.thumbnail], but read from a memory buffer. * - * * @height: %gint, target height in pixels - * * @size: #VipsSize, upsize, downsize, both or force - * * @no_rotate: %gboolean, don't rotate upright using orientation tag - * * @crop: #VipsInteresting, shrink and crop to fill target - * * @linear: %gboolean, perform shrink in linear light - * * @import_profile: %gchararray, fallback import ICC profile - * * @export_profile: %gchararray, export ICC profile - * * @intent: #VipsIntent, rendering intent - * * @fail_on: #VipsFailOn, load error types to fail on - * * @option_string: %gchararray, extra loader options + * One extra optional argument, @option_string, lets you pass options to the + * underlying loader. * - * Exactly as vips_thumbnail(), but read from a memory buffer. One extra - * optional argument, @option_string, lets you pass options to the underlying - * loader. + * ::: tip "Optional arguments" + * * @height: %gint, target height in pixels + * * @size: [enum@Size], upsize, downsize, both or force + * * @no_rotate: %gboolean, don't rotate upright using orientation tag + * * @crop: [enum@Interesting], shrink and crop to fill target + * * @linear: %gboolean, perform shrink in linear light + * * @import_profile: %gchararray, fallback import ICC profile + * * @export_profile: %gchararray, export ICC profile + * * @intent: [enum@Intent], rendering intent + * * @fail_on: [enum@FailOn], load error types to fail on + * * @option_string: %gchararray, extra loader options * - * See also: vips_thumbnail(). + * ::: seealso + * [ctor@Image.thumbnail]. * * Returns: 0 on success, -1 on error. */ @@ -1681,24 +1684,26 @@ vips_thumbnail_source_init(VipsThumbnailSource *source) * @width: target width in pixels * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @height: %gint, target height in pixels - * * @size: #VipsSize, upsize, downsize, both or force - * * @no_rotate: %gboolean, don't rotate upright using orientation tag - * * @crop: #VipsInteresting, shrink and crop to fill target - * * @linear: %gboolean, perform shrink in linear light - * * @import_profile: %gchararray, fallback import ICC profile - * * @export_profile: %gchararray, export ICC profile - * * @intent: #VipsIntent, rendering intent - * * @fail_on: #VipsFailOn, load error types to fail on - * * @option_string: %gchararray, extra loader options + * Exactly as [ctor@Image.thumbnail], but read from a source. * - * Exactly as vips_thumbnail(), but read from a source. One extra + * One extra * optional argument, @option_string, lets you pass options to the underlying * loader. * - * See also: vips_thumbnail(). + * ::: tip "Optional arguments" + * * @height: %gint, target height in pixels + * * @size: [enum@Size], upsize, downsize, both or force + * * @no_rotate: %gboolean, don't rotate upright using orientation tag + * * @crop: [enum@Interesting], shrink and crop to fill target + * * @linear: %gboolean, perform shrink in linear light + * * @import_profile: %gchararray, fallback import ICC profile + * * @export_profile: %gchararray, export ICC profile + * * @intent: [enum@Intent], rendering intent + * * @fail_on: [enum@FailOn], load error types to fail on + * * @option_string: %gchararray, extra loader options + * + * ::: seealso + * [ctor@Image.thumbnail]. * * Returns: 0 on success, -1 on error. */ @@ -1797,26 +1802,26 @@ vips_thumbnail_image_init(VipsThumbnailImage *image) * @width: target width in pixels * @...: %NULL-terminated list of optional named arguments * - * Optional arguments: - * - * * @height: %gint, target height in pixels - * * @size: #VipsSize, upsize, downsize, both or force - * * @no_rotate: %gboolean, don't rotate upright using orientation tag - * * @crop: #VipsInteresting, shrink and crop to fill target - * * @linear: %gboolean, perform shrink in linear light - * * @import_profile: %gchararray, fallback import ICC profile - * * @export_profile: %gchararray, export ICC profile - * * @intent: #VipsIntent, rendering intent - * * @fail_on: #VipsFailOn, load error types to fail on - * - * Exactly as vips_thumbnail(), but read from an existing image. + * Exactly as [ctor@Image.thumbnail], but read from an existing image. * * This operation * is not able to exploit shrink-on-load features of image load libraries, so - * it can be much slower than `vips_thumbnail()` and produce poorer quality - * output. Only use it if you really have to. + * it can be much slower than [ctor@Image.thumbnail] and produce poorer quality + * output. Only use this operation if you really have to. + * + * ::: tip "Optional arguments" + * * @height: %gint, target height in pixels + * * @size: [enum@Size], upsize, downsize, both or force + * * @no_rotate: %gboolean, don't rotate upright using orientation tag + * * @crop: [enum@Interesting], shrink and crop to fill target + * * @linear: %gboolean, perform shrink in linear light + * * @import_profile: %gchararray, fallback import ICC profile + * * @export_profile: %gchararray, export ICC profile + * * @intent: [enum@Intent], rendering intent + * * @fail_on: [enum@FailOn], load error types to fail on * - * See also: vips_thumbnail(). + * ::: seealso + * [ctor@Image.thumbnail]. * * Returns: 0 on success, -1 on error. */ From 2672bb658893da7f1cc3a4b1660b154f4308ad84 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 28 Apr 2025 18:10:22 +0100 Subject: [PATCH 146/174] fix delay metadata for webp and jxl save (#4481) * fix delay metadata for webp and jxl save we could modify a const pointer in some cases, causing unexpected side effects via the operation cache see https://github.com/libvips/libvips/issues/4479 * Update libvips/foreign/webpsave.c Co-authored-by: Kleis Auke Wolthuizen * Update libvips/foreign/jxlsave.c Co-authored-by: Kleis Auke Wolthuizen --------- Co-authored-by: Kleis Auke Wolthuizen --- libvips/foreign/cgifsave.c | 3 +-- libvips/foreign/jxlsave.c | 38 ++++++++++++++++++++---------------- libvips/foreign/webpsave.c | 40 ++++++++++++++++++++------------------ 3 files changed, 43 insertions(+), 38 deletions(-) diff --git a/libvips/foreign/cgifsave.c b/libvips/foreign/cgifsave.c index fa2d03e2bb..7298e4fbda 100644 --- a/libvips/foreign/cgifsave.c +++ b/libvips/foreign/cgifsave.c @@ -666,8 +666,7 @@ vips_foreign_save_cgif_write_frame(VipsForeignSaveCgif *cgif) if (cgif->delay && cgif->page_number < cgif->delay_length) - frame_config.delay = - rint(cgif->delay[cgif->page_number] / 10.0); + frame_config.delay = rint(cgif->delay[cgif->page_number] / 10.0); /* Attach a local palette, if we need one. */ diff --git a/libvips/foreign/jxlsave.c b/libvips/foreign/jxlsave.c index db046b0be3..4339eaf9fd 100644 --- a/libvips/foreign/jxlsave.c +++ b/libvips/foreign/jxlsave.c @@ -302,6 +302,24 @@ vips_foreign_save_jxl_process_output(VipsForeignSaveJxl *jxl) return 0; } +static int +vips_foreign_save_jxl_get_delay(VipsForeignSaveJxl *jxl, int page_number) +{ + int delay; + + if (jxl->delay && + page_number < jxl->delay_length) + delay = jxl->delay[page_number]; + else + // the old gif delay field was in centiseconds, so convert to ms + delay = jxl->gif_delay * 10; + + /* Force frames with a small or no duration to 100ms for consistency + * with web browsers and other transcoding tools. + */ + return delay <= 10 ? 100 : delay; +} + static int vips_foreign_save_jxl_add_frame(VipsForeignSaveJxl *jxl) { @@ -326,10 +344,9 @@ vips_foreign_save_jxl_add_frame(VipsForeignSaveJxl *jxl) if (!jxl->is_animated) header.duration = 0xffffffff; - else if (jxl->delay && jxl->page_number < jxl->delay_length) - header.duration = jxl->delay[jxl->page_number]; else - header.duration = jxl->gif_delay * 10; + header.duration = + vips_foreign_save_jxl_get_delay(jxl, jxl->page_number); JxlEncoderSetFrameHeader(frame_settings, &header); } @@ -472,7 +489,6 @@ vips_foreign_save_jxl_build(VipsObject *object) VipsImage *in; VipsBandFormat format; - int i; if (VIPS_OBJECT_CLASS(vips_foreign_save_jxl_parent_class)->build(object)) return -1; @@ -696,8 +712,7 @@ vips_foreign_save_jxl_build(VipsObject *object) */ jxl->gif_delay = 10; if (vips_image_get_typeof(save->ready, "gif-delay") && - vips_image_get_int(save->ready, "gif-delay", - &jxl->gif_delay)) + vips_image_get_int(save->ready, "gif-delay", &jxl->gif_delay)) return -1; /* New images have an array of ints instead. @@ -714,17 +729,6 @@ vips_foreign_save_jxl_build(VipsObject *object) if (vips_image_get_typeof(save->ready, "delay") || vips_image_get_typeof(save->ready, "gif-delay")) jxl->is_animated = TRUE; - - /* Force frames with a small or no duration to 100ms - * to be consistent with web browsers and other - * transcoding tools. - */ - if (jxl->gif_delay <= 1) - jxl->gif_delay = 10; - - for (i = 0; i < jxl->delay_length; i++) - if (jxl->delay[i] <= 10) - jxl->delay[i] = 100; } #ifdef DEBUG diff --git a/libvips/foreign/webpsave.c b/libvips/foreign/webpsave.c index ee2071d26e..67e07cf4fd 100644 --- a/libvips/foreign/webpsave.c +++ b/libvips/foreign/webpsave.c @@ -294,6 +294,24 @@ vips_foreign_save_webp_write_webp_image(VipsForeignSaveWebp *webp, return 0; } +static int +vips_foreign_save_webp_get_delay(VipsForeignSaveWebp *webp, int page_number) +{ + int delay; + + if (webp->delay && + page_number < webp->delay_length) + delay = webp->delay[page_number]; + else + // the old gif delay field was in centiseconds, so convert to ms + delay = webp->gif_delay * 10; + + /* Force frames with a small or no duration to 100ms for consistency + * with web browsers and other transcoding tools. + */ + return delay <= 10 ? 100 : delay; +} + /* We have a complete frame --- write! */ static int @@ -318,11 +336,8 @@ vips_foreign_save_webp_write_frame(VipsForeignSaveWebp *webp) /* Adjust current timestamp */ - if (webp->delay && - webp->page_number < webp->delay_length) - webp->timestamp_ms += webp->delay[webp->page_number]; - else - webp->timestamp_ms += webp->gif_delay * 10; + webp->timestamp_ms += + vips_foreign_save_webp_get_delay(webp, webp->page_number); } else { /* Single image write @@ -636,7 +651,6 @@ vips_foreign_save_webp_init_anim_enc(VipsForeignSaveWebp *webp) int page_height = vips_image_get_page_height(save->ready); WebPAnimEncoderOptions anim_config; - int i; /* Init config for animated write */ @@ -659,31 +673,19 @@ vips_foreign_save_webp_init_anim_enc(VipsForeignSaveWebp *webp) /* Get delay array * * There might just be the old gif-delay field. This is centiseconds. + * New images have an array of ints giving millisecond durations. */ webp->gif_delay = 10; if (vips_image_get_typeof(save->ready, "gif-delay") && vips_image_get_int(save->ready, "gif-delay", &webp->gif_delay)) return -1; - /* New images have an array of ints instead. - */ webp->delay = NULL; if (vips_image_get_typeof(save->ready, "delay") && vips_image_get_array_int(save->ready, "delay", &webp->delay, &webp->delay_length)) return -1; - /* Force frames with a small or no duration to 100ms - * to be consistent with web browsers and other - * transcoding tools. - */ - if (webp->gif_delay <= 1) - webp->gif_delay = 10; - - for (i = 0; i < webp->delay_length; i++) - if (webp->delay[i] <= 10) - webp->delay[i] = 100; - return 0; } From 7cba1e91fe3daaf58a97c2593cac4b73c6f1b3cf Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 30 Apr 2025 13:06:08 +0200 Subject: [PATCH 147/174] Revert "OSS-Fuzz: limit link jobs to 4 (#4108)" (#4485) Mitigates issue https://github.com/mesonbuild/meson/issues/14524, the fuzz introspector build was already broken for some time due to https://github.com/google/oss-fuzz/pull/12983#issuecomment-2659255900. This reverts commit 50caa1922fa88e02c8cbfb3192fe8282d7da6eee. --- fuzz/oss_fuzz_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzz/oss_fuzz_build.sh b/fuzz/oss_fuzz_build.sh index 6f9435ef9b..57d279cb88 100755 --- a/fuzz/oss_fuzz_build.sh +++ b/fuzz/oss_fuzz_build.sh @@ -192,7 +192,7 @@ popd # Disable building man pages, gettext po files, tools, and tests sed -i "/subdir('man')/{N;N;N;d;}" meson.build meson setup build --prefix=$WORK --libdir=lib --prefer-static --default-library=static --buildtype=debugoptimized \ - -Dbackend_max_links=4 -Ddeprecated=false -Dexamples=false -Dcplusplus=false -Dmodules=disabled \ + -Ddeprecated=false -Dexamples=false -Dcplusplus=false -Dmodules=disabled \ -Dfuzzing_engine=oss-fuzz -Dfuzzer_ldflags="$LIB_FUZZING_ENGINE" \ -Dcpp_link_args="$LDFLAGS -Wl,-rpath=\$ORIGIN/lib" meson install -C build --tag devel From 04672c7d6b9eae8c440a55e8f98c1371e8dc22cd Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 30 Apr 2025 13:09:19 +0200 Subject: [PATCH 148/174] OSS-Fuzz: disable build of examples in spng (#4484) --- fuzz/oss_fuzz_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzz/oss_fuzz_build.sh b/fuzz/oss_fuzz_build.sh index 57d279cb88..fb1a974df1 100755 --- a/fuzz/oss_fuzz_build.sh +++ b/fuzz/oss_fuzz_build.sh @@ -103,7 +103,7 @@ popd # libspng pushd $SRC/libspng meson setup build --prefix=$WORK --libdir=lib --default-library=static --buildtype=debugoptimized \ - -Dstatic_zlib=true + -Dstatic_zlib=true -Dbuild_examples=false meson install -C build --tag devel popd From 1fb9dc3a7cfe8e46d8068bbaad4e5054f9b83b99 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 30 Apr 2025 12:49:41 +0100 Subject: [PATCH 149/174] lazy create of file targets (#4482) `vips_target_new_to_file()` used to immediately create the target file. If the filename was not actually used (eg. by `dzsave`), a stray file would be left behind. This PR moves the file create to the first `_write()` operation. See https://github.com/libvips/libvips/issues/4476 --- libvips/iofuncs/target.c | 59 ++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/libvips/iofuncs/target.c b/libvips/iofuncs/target.c index a400d4d7b9..dedebdac54 100644 --- a/libvips/iofuncs/target.c +++ b/libvips/iofuncs/target.c @@ -115,25 +115,10 @@ vips_target_build(VipsObject *object) return -1; } - if (connection->filename) { - const char *filename = connection->filename; + // for filename targets, don't create the file we write on _build() -- + // do it lazily on the first write - int fd; - - /* 0644 is rw user, r group and other. - */ - if ((fd = vips_tracked_open(filename, - MODE_READWRITE, 0644)) == -1) { - vips_error_system(errno, - vips_connection_nick(connection), - "%s", _("unable to open for write")); - return -1; - } - - connection->tracked_descriptor = fd; - connection->descriptor = fd; - } - else if (vips_object_argument_isset(object, "descriptor")) { + if (vips_object_argument_isset(object, "descriptor")) { connection->descriptor = dup(connection->descriptor); connection->close_descriptor = connection->descriptor; @@ -151,6 +136,36 @@ vips_target_build(VipsObject *object) return 0; } +/* If necessary, create the file we write to from the filename. We do this + * lazily on first write, since eg. dzsave might not actually write to this + * filename in some cases. + */ +static int +vips_target_create_file(VipsTarget *target) +{ + VipsConnection *connection = VIPS_CONNECTION(target); + + if (connection->filename && + connection->tracked_descriptor == -1) { + const char *filename = connection->filename; + + int fd; + + /* 0644 is rw user, r group and other. + */ + if ((fd = vips_tracked_open(filename, MODE_READWRITE, 0644)) == -1) { + vips_error_system(errno, vips_connection_nick(connection), + "%s", _("unable to open for write")); + return -1; + } + + connection->tracked_descriptor = fd; + connection->descriptor = fd; + } + + return 0; +} + static gint64 vips_target_write_real(VipsTarget *target, const void *data, size_t length) { @@ -169,8 +184,12 @@ vips_target_write_real(VipsTarget *target, const void *data, size_t length) target->position += length; result = length; } - else - result = write(connection->descriptor, data, length); + else { + if (vips_target_create_file(target)) + result = -1; + else + result = write(connection->descriptor, data, length); + } return result; } From 08afac5ada0e25d3f68cb5f4c9e6807627d57f63 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 30 Apr 2025 13:00:41 +0100 Subject: [PATCH 150/174] Cast TIFFSetField length args to uint32 (#4483) * start hacking * read and write TIFFTAG_IMAGESOURCEDATA tags Photoshop uses another private tag to store some extra document data. see https://github.com/libvips/libvips/discussions/4478 * remove the IMAGEDATA stuff, not useful but the improvement to TIFFSetField() seems worth keeping * remove stray define --- libvips/foreign/tiff.h | 9 +++++++ libvips/foreign/tiff2vips.c | 9 ------- libvips/foreign/vips2tiff.c | 49 ++++++++++++++++++++----------------- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/libvips/foreign/tiff.h b/libvips/foreign/tiff.h index 67d21ad46c..8bfc8ea5bf 100644 --- a/libvips/foreign/tiff.h +++ b/libvips/foreign/tiff.h @@ -33,6 +33,15 @@ #include +/* Aperio TIFFs (svs) use these compression types for jp2k-compressed tiles. + */ +#define JP2K_YCC (33003) +#define JP2K_RGB (33005) + +/* Bioformats uses this tag for jp2k compressed tiles. + */ +#define JP2K_LOSSY (33004) + #ifdef __cplusplus extern "C" { #endif /*__cplusplus*/ diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index 718678f0a7..1eb03edd3d 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -271,15 +271,6 @@ #include "jpeg.h" #endif /*HAVE_JPEG*/ -/* Aperio TIFFs (svs) use these compression types for jp2k-compressed tiles. - */ -#define JP2K_YCC 33003 -#define JP2K_RGB 33005 - -/* Bioformats uses this tag for jp2k compressed tiles. - */ -#define JP2K_LOSSY 33004 - /* Compression types we handle ourselves. */ static int rtiff_we_decompress[] = { diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 89f23930c1..4c37b0e4fe 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -285,10 +285,6 @@ */ #define MAX_ALPHA (64) -/* Bioformats uses this tag for lossy jp2k compressed tiles. - */ -#define JP2K_LOSSY 33004 - /* Compression types we handle ourselves. */ static int wtiff_we_compress[] = { @@ -396,6 +392,16 @@ struct _Wtiff { GMutex lock; }; +/* libvips uses size_t for the length of binary data items, but libtiff wants + * uint32. + */ +static void +set_data64(TIFF *tif, guint32 tag, size_t length, const void *data) +{ + if (length <= UINT_MAX) + TIFFSetField(tif, tag, (guint32) length, data); +} + /* Write an ICC Profile from a file into the JPEG stream. */ static int @@ -410,7 +416,7 @@ embed_profile_file(TIFF *tif, const char *profile) size_t length; const void *data = vips_blob_get(blob, &length); - TIFFSetField(tif, TIFFTAG_ICCPROFILE, length, data); + set_data64(tif, TIFFTAG_ICCPROFILE, length, data); #ifdef DEBUG printf("vips2tiff: attached profile \"%s\"\n", profile); @@ -432,7 +438,7 @@ embed_profile_meta(TIFF *tif, VipsImage *im) if (vips_image_get_blob(im, VIPS_META_ICC_NAME, &data, &length)) return -1; - TIFFSetField(tif, TIFFTAG_ICCPROFILE, length, data); + set_data64(tif, TIFFTAG_ICCPROFILE, length, data); #ifdef DEBUG printf("vips2tiff: attached profile from meta\n"); @@ -576,7 +582,7 @@ wtiff_embed_xmp(Wtiff *wtiff, TIFF *tif) if (vips_image_get_blob(wtiff->ready, VIPS_META_XMP_NAME, &data, &size)) return -1; - TIFFSetField(tif, TIFFTAG_XMLPACKET, size, data); + set_data64(tif, TIFFTAG_XMLPACKET, size, data); #ifdef DEBUG printf("vips2tiff: attached XMP from meta\n"); @@ -608,7 +614,7 @@ wtiff_embed_iptc(Wtiff *wtiff, TIFF *tif) else size /= 4; - TIFFSetField(tif, TIFFTAG_RICHTIFFIPTC, size, data); + set_data64(tif, TIFFTAG_RICHTIFFIPTC, size, data); #ifdef DEBUG printf("vips2tiff: attached IPTC from meta\n"); @@ -623,16 +629,16 @@ wtiff_embed_photoshop(Wtiff *wtiff, TIFF *tif) const void *data; size_t size; - if (!vips_image_get_typeof(wtiff->ready, VIPS_META_PHOTOSHOP_NAME)) - return 0; - if (vips_image_get_blob(wtiff->ready, VIPS_META_PHOTOSHOP_NAME, - &data, &size)) - return -1; - TIFFSetField(tif, TIFFTAG_PHOTOSHOP, size, data); + if (vips_image_get_typeof(wtiff->ready, VIPS_META_PHOTOSHOP_NAME)) { + if (vips_image_get_blob(wtiff->ready, VIPS_META_PHOTOSHOP_NAME, + &data, &size)) + return -1; + set_data64(tif, TIFFTAG_PHOTOSHOP, size, data); #ifdef DEBUG - printf("vips2tiff: attached photoshop data from meta\n"); + printf("vips2tiff: attached %zd bytes of photoshop data\n", size); #endif /*DEBUG*/ + } return 0; } @@ -885,10 +891,10 @@ wtiff_write_header(Wtiff *wtiff, Layer *layer) if (wtiff->compression == COMPRESSION_ZSTD) { // Set zstd compression level - only accept valid values (1-22) if (wtiff->level) - TIFFSetField(tif, TIFFTAG_ZSTD_LEVEL, VIPS_CLIP(1, wtiff->level, 22)); - if (wtiff->predictor != VIPS_FOREIGN_TIFF_PREDICTOR_NONE) TIFFSetField(tif, - TIFFTAG_PREDICTOR, wtiff->predictor); + TIFFTAG_ZSTD_LEVEL, VIPS_CLIP(1, wtiff->level, 22)); + if (wtiff->predictor != VIPS_FOREIGN_TIFF_PREDICTOR_NONE) + TIFFSetField(tif, TIFFTAG_PREDICTOR, wtiff->predictor); } #endif /*HAVE_TIFF_COMPRESSION_WEBP*/ @@ -960,8 +966,7 @@ wtiff_write_header(Wtiff *wtiff, Layer *layer) int alpha_bands; - TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, - wtiff->ready->Bands); + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, wtiff->ready->Bands); TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, vips_format_sizeof(wtiff->ready->BandFmt) << 3); @@ -1109,7 +1114,7 @@ wtiff_write_header(Wtiff *wtiff, Layer *layer) printf("setting %zd bytes of table data\n", length); #endif /*DEBUG*/ - TIFFSetField(tif, TIFFTAG_JPEGTABLES, length, buffer); + set_data64(tif, TIFFTAG_JPEGTABLES, length, buffer); g_free(buffer); } @@ -2297,7 +2302,7 @@ wtiff_write_lines(Wtiff *wtiff, VipsRegion *region, VipsRect *lines) */ #define CopyField(tag, v) \ if (TIFFGetField(in, tag, &v)) \ - TIFFSetField(out, tag, v) + TIFFSetField(out, tag, v) static int wtiff_copy_tiles(Wtiff *wtiff, TIFF *out, TIFF *in) From cc97d227a626aa40d38e08e246f9c65ffd784ffe Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 30 Apr 2025 14:01:34 +0200 Subject: [PATCH 151/174] OSS-Fuzz: add workaround for mesonbuild/meson#14533 (#4487) By appending the sanitizer-specific flags to the `LDFLAGS` env. --- fuzz/oss_fuzz_build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fuzz/oss_fuzz_build.sh b/fuzz/oss_fuzz_build.sh index fb1a974df1..63f6b8f94e 100755 --- a/fuzz/oss_fuzz_build.sh +++ b/fuzz/oss_fuzz_build.sh @@ -188,6 +188,9 @@ cmake \ cmake --build . --target install popd +# FIXME: Workaround for https://github.com/mesonbuild/meson/issues/14533 +export LDFLAGS+=" $CFLAGS" + # libvips # Disable building man pages, gettext po files, tools, and tests sed -i "/subdir('man')/{N;N;N;d;}" meson.build From 057a1082cd3a14a95a6375025f2a15bf922a8ced Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 30 Apr 2025 13:22:18 +0100 Subject: [PATCH 152/174] restore vips_remosaic() we'd forgotten to init it. Also, rebuild cpp API. --- ChangeLog | 1 + cplusplus/include/vips/VImage8.h | 11 ++++++++++- cplusplus/vips-operators.cpp | 17 ++++++++++++++--- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9bc530f7aa..b3b2d6533e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,7 @@ master - share and reuse openslide connections - drop support for openslide 3.3 - fix vips_quadratic() +- restore vips_remosaic(), it was not being linked 8.16.1 diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h index c132a240d1..6a56c18ae8 100644 --- a/cplusplus/include/vips/VImage8.h +++ b/cplusplus/include/vips/VImage8.h @@ -5424,6 +5424,15 @@ class VImage : public VObject { */ VImage remainder_const(std::vector c, VOption *options = nullptr) const; + /** + * Rebuild an mosaiced image. + * @param old_str Search for this string. + * @param new_str And swap for this string. + * @param options Set of options. + * @return Output image. + */ + VImage remosaic(const char *old_str, const char *new_str, VOption *options = nullptr) const; + /** * Replicate an image. * @param across Repeat this many times horizontally. @@ -5524,7 +5533,7 @@ class VImage : public VObject { VImage scRGB2XYZ(VOption *options = nullptr) const; /** - * Convert an scrgb image to srgb. + * Convert scrgb to srgb. * * **Optional parameters** * - **depth** -- Output device space depth in bits, int. diff --git a/cplusplus/vips-operators.cpp b/cplusplus/vips-operators.cpp index 4a60f95ecf..7c56408e11 100644 --- a/cplusplus/vips-operators.cpp +++ b/cplusplus/vips-operators.cpp @@ -1,6 +1,3 @@ -// bodies for vips operations -// this file is generated automatically, do not edit! -// clang-format off VImage VImage::CMC2LCh(VOption *options) const @@ -3074,6 +3071,20 @@ VImage::remainder_const(std::vector c, VOption *options) const return out; } +VImage +VImage::remosaic(const char *old_str, const char *new_str, VOption *options) const +{ + VImage out; + + call("remosaic", (options ? options : VImage::option()) + ->set("in", *this) + ->set("out", &out) + ->set("old_str", old_str) + ->set("new_str", new_str)); + + return out; +} + VImage VImage::replicate(int across, int down, VOption *options) const { From 33f0d51c768e906e6a5d08c958192717f2cca2bd Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 30 Apr 2025 16:02:22 +0200 Subject: [PATCH 153/174] lsan: remove pyvips suppression (#4490) --- suppressions/lsan.supp | 3 --- 1 file changed, 3 deletions(-) diff --git a/suppressions/lsan.supp b/suppressions/lsan.supp index 5e6298de26..6eba8040cc 100644 --- a/suppressions/lsan.supp +++ b/suppressions/lsan.supp @@ -21,6 +21,3 @@ leak:___kmp_allocate # TODO: Does this requires calling heif_deinit()? leak:x265::x265_malloc leak:x265_12bit::x265_malloc - -# TODO: Remove after PR https://github.com/libvips/pyvips/pull/497 -leak:vips_filename_get_filename From 530348455682a663d7f7833c213dfe80f6495d9b Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 30 Apr 2025 19:10:06 +0200 Subject: [PATCH 154/174] CI: upgrade Ubuntu's Clang to version 19 (#4489) --- .github/workflows/ci.yml | 12 ++++++------ .github/workflows/lint.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e11a314a78..1f2c362fdc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,9 +16,9 @@ jobs: os: ubuntu-24.04 build: { cc: gcc-14, cxx: g++-14, linker: ld, docs: true } - - name: "Linux x64 (Ubuntu 24.04) - Clang 18 with ASan and UBSan" + - name: "Linux x64 (Ubuntu 24.04) - Clang 19 with ASan and UBSan" os: ubuntu-24.04 - build: { cc: clang-18, cxx: clang++-18, linker: ld.lld-18, sanitize: true } + build: { cc: clang-19, cxx: clang++-19, linker: ld.lld-19, sanitize: true } - name: "macOS arm64 (14) - Xcode 15" os: macos-14 @@ -67,9 +67,9 @@ jobs: openexr openjpeg openslide pango \ poppler webp - - name: Install Clang 18 - if: runner.os == 'Linux' && matrix.build.cc == 'clang-18' - run: sudo apt-get install clang-18 libomp-18-dev lld-18 llvm-18 + - name: Install Clang 19 + if: runner.os == 'Linux' && matrix.build.cc == 'clang-19' + run: sudo apt-get install clang-19 libomp-19-dev lld-19 llvm-19 - name: Prepare macOS environment if: runner.os == 'macOS' @@ -79,7 +79,7 @@ jobs: - name: Prepare sanitizers if: matrix.build.sanitize env: - LLVM_PREFIX: /usr/lib/llvm-18 + LLVM_PREFIX: /usr/lib/llvm-19 run: | ASAN_DSO=`$CC -print-file-name=libclang_rt.asan-x86_64.so` echo "LDSHARED=$CC -shared" >> $GITHUB_ENV diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index fef6197973..f4a25351ee 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -13,7 +13,7 @@ jobs: id: linter with: style: file - version: 18 # Ubuntu 24.04 provides clang-format-18 + version: 19 # Ubuntu 24.04 provides clang-format-19 tidy-checks: '-*' # disable clang-tidy lines-changed-only: true # ignore bundled files From c8c06967fc3b1ec2e0671fc784a2ffe44c7d0560 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 1 May 2025 03:21:15 +0100 Subject: [PATCH 155/174] rename thumbnail's profile arguments (#4488) We use `input-profile` and `output-profile` everywhere else, but `thumbnail` calls them `import-profile` and `export-profile`, confusingly. LittleCMS seems to use `input-profile` and `output-profile` too. --- ChangeLog | 2 + doc/using-vipsthumbnail.md | 6 +-- libvips/resample/thumbnail.c | 92 +++++++++++++++++++------------- man/vipsthumbnail.1 | 44 +++++++-------- test/test-suite/test_resample.py | 2 +- tools/vipsthumbnail.c | 44 +++++++++------ 6 files changed, 111 insertions(+), 79 deletions(-) diff --git a/ChangeLog b/ChangeLog index b3b2d6533e..e906a300d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,8 @@ master - share and reuse openslide connections - drop support for openslide 3.3 - fix vips_quadratic() +- rename `thumbnail`'s export/import profile options as input/output for + consistency - restore vips_remosaic(), it was not being linked 8.16.1 diff --git a/doc/using-vipsthumbnail.md b/doc/using-vipsthumbnail.md index a5eb645e4a..d5e111e6b8 100644 --- a/doc/using-vipsthumbnail.md +++ b/doc/using-vipsthumbnail.md @@ -275,7 +275,7 @@ Now transform to sRGB and don't attach a profile (you can also use `keep=none`, though that will remove *all* metadata from the image): ```bash -$ vipsthumbnail shark.jpg --export-profile srgb -o tn_shark.jpg[profile=none] +$ vipsthumbnail shark.jpg --output-profile srgb -o tn_shark.jpg[profile=none] $ ls -l tn_shark.jpg -rw-r–r– 1 john john 4229 Nov  9 14:33 tn_shark.jpg ``` @@ -291,7 +291,7 @@ space, even though it has no embedded profile. ```bash -$ vipsthumbnail kgdev.jpg --import-profile /my/profiles/a98.icm +$ vipsthumbnail kgdev.jpg --input-profile /my/profiles/a98.icm ``` ## Final suggestion @@ -301,6 +301,6 @@ Putting all this together, I suggest this as a sensible set of options: ```bash $ vipsthumbnail fred.jpg \ --size 128 \ - --export-profile srgb \ + --output-profile srgb \ -o tn_%s.jpg[optimize_coding,keep=none] ``` diff --git a/libvips/resample/thumbnail.c b/libvips/resample/thumbnail.c index 63cb706485..f7b1f73c1b 100644 --- a/libvips/resample/thumbnail.c +++ b/libvips/resample/thumbnail.c @@ -116,8 +116,8 @@ typedef struct _VipsThumbnail { gboolean no_rotate; VipsInteresting crop; gboolean linear; - char *export_profile; - char *import_profile; + char *output_profile; + char *input_profile; VipsIntent intent; VipsFailOn fail_on; @@ -695,8 +695,8 @@ vips_thumbnail_build(VipsObject *object) */ preshrunk_page_height = vips_image_get_page_height(in); - needs_icc_transform = thumbnail->export_profile && - (thumbnail->import_profile || + needs_icc_transform = thumbnail->output_profile && + (thumbnail->input_profile || vips_image_get_typeof(in, VIPS_META_ICC_NAME)); /* RAD needs special unpacking. @@ -716,20 +716,20 @@ vips_thumbnail_build(VipsObject *object) */ have_imported = FALSE; if (thumbnail->linear) { - /* If we are doing colour management (there's an import + /* If we are doing colour management (there's an input * profile), then we can use XYZ PCS as the resize space. */ if (in->Coding == VIPS_CODING_NONE && (in->BandFmt == VIPS_FORMAT_UCHAR || in->BandFmt == VIPS_FORMAT_USHORT) && (vips_image_get_typeof(in, VIPS_META_ICC_NAME) || - thumbnail->import_profile)) { + thumbnail->input_profile)) { g_info("importing to XYZ PCS"); - if (thumbnail->import_profile) - g_info("fallback input profile %s", thumbnail->import_profile); + if (thumbnail->input_profile) + g_info("fallback input profile %s", thumbnail->input_profile); if (vips_icc_import(in, &t[2], - "input_profile", thumbnail->import_profile, + "input_profile", thumbnail->input_profile, "embedded", TRUE, "intent", thumbnail->intent, "pcs", VIPS_PCS_XYZ, @@ -844,11 +844,11 @@ vips_thumbnail_build(VipsObject *object) if (have_imported) { /* We are in PCS. Export with the output profile, if any (this * will export with the embedded input profile if there's no - * export profile). + * output profile). */ g_info("exporting to device space with a profile"); if (vips_icc_export(in, &t[9], - "output_profile", thumbnail->export_profile, + "output_profile", thumbnail->output_profile, "intent", thumbnail->intent, "depth", 8, NULL)) @@ -859,8 +859,8 @@ vips_thumbnail_build(VipsObject *object) /* We can transform to the output with a pair of ICC profiles. */ g_info("transforming with supplied profiles"); - if (vips_icc_transform(in, &t[9], thumbnail->export_profile, - "input_profile", thumbnail->import_profile, + if (vips_icc_transform(in, &t[9], thumbnail->output_profile, + "input_profile", thumbnail->input_profile, "intent", thumbnail->intent, "embedded", TRUE, "depth", 8, @@ -869,14 +869,14 @@ vips_thumbnail_build(VipsObject *object) in = t[9]; } - else if (thumbnail->export_profile) { + else if (thumbnail->output_profile) { /* We are in one of the resize space (sRGB, scRGB, B_W, GREY16, etc.) * and need to go to PCS, then export. */ - g_info("exporting with %s", thumbnail->export_profile); + g_info("exporting with %s", thumbnail->output_profile); if (vips_colourspace(in, &t[9], VIPS_INTERPRETATION_XYZ, NULL) || vips_icc_export(t[9], &t[10], - "output_profile", thumbnail->export_profile, + "output_profile", thumbnail->output_profile, "intent", thumbnail->intent, "depth", 8, NULL)) @@ -885,7 +885,7 @@ vips_thumbnail_build(VipsObject *object) } else if (thumbnail->linear) { /* We are in one of the scRGB or GREY16 spaces and there's - * no export profile. Output to sRGB or B_W. + * no output profile. Output to sRGB or B_W. */ VipsInterpretation interpretation; @@ -1012,18 +1012,18 @@ vips_thumbnail_class_init(VipsThumbnailClass *class) G_STRUCT_OFFSET(VipsThumbnail, linear), FALSE); - VIPS_ARG_STRING(class, "import_profile", 118, - _("Import profile"), - _("Fallback import profile"), + VIPS_ARG_STRING(class, "input_profile", 118, + _("Input profile"), + _("Fallback input profile"), VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET(VipsThumbnail, import_profile), + G_STRUCT_OFFSET(VipsThumbnail, input_profile), NULL); - VIPS_ARG_STRING(class, "export_profile", 119, - _("Export profile"), - _("Fallback export profile"), + VIPS_ARG_STRING(class, "output_profile", 119, + _("Output profile"), + _("Fallback output profile"), VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET(VipsThumbnail, export_profile), + G_STRUCT_OFFSET(VipsThumbnail, output_profile), NULL); VIPS_ARG_ENUM(class, "intent", 120, @@ -1046,12 +1046,30 @@ vips_thumbnail_class_init(VipsThumbnailClass *class) * This is now replaced (though still functional) with "no-rotate", * see above. */ - VIPS_ARG_BOOL(class, "auto_rotate", 121, + VIPS_ARG_BOOL(class, "auto_rotate", 130, _("Auto rotate"), _("Use orientation tags to rotate image upright"), VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED, G_STRUCT_OFFSET(VipsThumbnail, auto_rotate), TRUE); + + /* Renamed as input-profile and output-profile for consistency with the + * rest of the API. + */ + + VIPS_ARG_STRING(class, "import_profile", 131, + _("Import profile"), + _("Fallback import profile"), + VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED, + G_STRUCT_OFFSET(VipsThumbnail, input_profile), + NULL); + + VIPS_ARG_STRING(class, "export_profile", 132, + _("Export profile"), + _("Fallback export profile"), + VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED, + G_STRUCT_OFFSET(VipsThumbnail, output_profile), + NULL); } static void @@ -1217,7 +1235,7 @@ vips_thumbnail_file_init(VipsThumbnailFile *file) * Make a thumbnail from a file. * * Shrinking is done in three stages: using any - * shrink-on-load features available in the file import library, using a block + * shrink-on-load features available in the image load library, using a block * shrink, and using a lanczos3 shrink. At least the final 200% is done with * lanczos3. The output should be high quality, and the operation should be * quick. @@ -1256,9 +1274,9 @@ vips_thumbnail_file_init(VipsThumbnailFile *file) * also be far slower, since tricks like JPEG shrink-on-load cannot be used in * linear space. * - * If you set @export_profile to the filename of an ICC profile, the image + * If you set @output_profile to the filename of an ICC profile, the image * will be transformed to the target colourspace before writing to the - * output. You can also give an @import_profile which will be used if the + * output. You can also give an @input_profile which will be used if the * input image has no ICC profile, or if the profile embedded in the * input image is broken. * @@ -1274,8 +1292,8 @@ vips_thumbnail_file_init(VipsThumbnailFile *file) * * @no_rotate: %gboolean, don't rotate upright using orientation tag * * @crop: [enum@Interesting], shrink and crop to fill target * * @linear: %gboolean, perform shrink in linear light - * * @import_profile: %gchararray, fallback import ICC profile - * * @export_profile: %gchararray, export ICC profile + * * @input_profile: %gchararray, fallback input ICC profile + * * @output_profile: %gchararray, output ICC profile * * @intent: [enum@Intent], rendering intent * * @fail_on: [enum@FailOn], load error types to fail on * @@ -1482,8 +1500,8 @@ vips_thumbnail_buffer_init(VipsThumbnailBuffer *buffer) * * @no_rotate: %gboolean, don't rotate upright using orientation tag * * @crop: [enum@Interesting], shrink and crop to fill target * * @linear: %gboolean, perform shrink in linear light - * * @import_profile: %gchararray, fallback import ICC profile - * * @export_profile: %gchararray, export ICC profile + * * @input_profile: %gchararray, fallback input ICC profile + * * @output_profile: %gchararray, output ICC profile * * @intent: [enum@Intent], rendering intent * * @fail_on: [enum@FailOn], load error types to fail on * * @option_string: %gchararray, extra loader options @@ -1696,8 +1714,8 @@ vips_thumbnail_source_init(VipsThumbnailSource *source) * * @no_rotate: %gboolean, don't rotate upright using orientation tag * * @crop: [enum@Interesting], shrink and crop to fill target * * @linear: %gboolean, perform shrink in linear light - * * @import_profile: %gchararray, fallback import ICC profile - * * @export_profile: %gchararray, export ICC profile + * * @input_profile: %gchararray, fallback input ICC profile + * * @output_profile: %gchararray, output ICC profile * * @intent: [enum@Intent], rendering intent * * @fail_on: [enum@FailOn], load error types to fail on * * @option_string: %gchararray, extra loader options @@ -1815,8 +1833,8 @@ vips_thumbnail_image_init(VipsThumbnailImage *image) * * @no_rotate: %gboolean, don't rotate upright using orientation tag * * @crop: [enum@Interesting], shrink and crop to fill target * * @linear: %gboolean, perform shrink in linear light - * * @import_profile: %gchararray, fallback import ICC profile - * * @export_profile: %gchararray, export ICC profile + * * @input_profile: %gchararray, fallback input ICC profile + * * @output_profile: %gchararray, output ICC profile * * @intent: [enum@Intent], rendering intent * * @fail_on: [enum@FailOn], load error types to fail on * diff --git a/man/vipsthumbnail.1 b/man/vipsthumbnail.1 index b14ac4f2fd..d42942018c 100644 --- a/man/vipsthumbnail.1 +++ b/man/vipsthumbnail.1 @@ -5,7 +5,7 @@ vipsthumbnail \- make thumbnails of image files .B vipsthumbnail [flags] imagefile1 imagefile2 ... .SH DESCRIPTION .B vipsthumbnail(1) -processes each +processes each .B imagefile in turn, shrinking each image to fit within a 128 by 128 pixel square. The shrunk image is written to a new file named @@ -17,9 +17,9 @@ For example: $ vipsthumbnail fred.png jim.tif -will read image files +will read image files .B fred.png -and +and .B jim.tif and write thumbnails to the files .B tn_fred.jpg @@ -30,36 +30,36 @@ and will read image file .B fred.jpg -and write a 64 x 64 pixel thumbnail to the file +and write a 64 x 64 pixel thumbnail to the file .B thumbnails/fred.png. .SH OPTIONS .TP .B -s N, --size=N -Set the output thumbnail size to -.B N -x -.B N -pixels. +Set the output thumbnail size to +.B N +x +.B N +pixels. You can use "MxN" to specify a rectangular bounding box. The image is shrunk so that it just fits within this area, images -which are smaller than this are expanded. +which are smaller than this are expanded. Use "xN" or "Mx" to just resize on -one axis. +one axis. Append "<" to only resize if the input image is smaller than the target, append ">" to only resize if the input image is larger than the target. .TP -.B -o FORMAT, --output=FORMAT +.B -o FORMAT, --output=FORMAT Set the output format string. The input filename has any file type suffix -removed, then that value is substituted into +removed, then that value is substituted into .B FORMAT replacing -.B %s. -If +.B %s. +If .B FORMAT is a relative path, the name of the input directory is prepended. In other words, any path in @@ -75,7 +75,7 @@ prepended. You can add format options too, for example will write JPEG images with Q set to 20. .TP -.B -e PROFILE, --eprofile=PROFILE +.B -e PROFILE, --eprofile=PROFILE Export thumbnails with this ICC profile. Images are only colour-transformed if there is both an output and an input profile available. The input profile can either be embedded in the input image or supplied with the @@ -83,8 +83,8 @@ either be embedded in the input image or supplied with the option. .TP -.B -i PROFILE, --iprofile=PROFILE -Import images with this ICC profile, if no profile is embedded in the image. +.B -i PROFILE, --iprofile=PROFILE +Import images with this ICC profile, if no profile is embedded in the image. Images are only colour-transformed if there is both an output and an input profile available. The output profile should be supplied with the @@ -94,20 +94,20 @@ option. .TP .B -c, --crop Crop the output image down. The image is shrunk so as to completely fill the -bounding box in both axes, then any excess is cropped off. +bounding box in both axes, then any excess is cropped off. .TP .B -d, --delete Delete the output profile from the image. This can save a small amount of -space. +space. .TP .B -t, --rotate -Auto-rotate images using EXIF orientation tags. +Auto-rotate images using EXIF orientation tags. .TP .B -a, --linear -Shrink images in linear light colour space. This can be much slower. +Shrink images in linear light colour space. This can be much slower. .SH RETURN VALUE returns 0 on success and non-zero on error. Error can mean one or more diff --git a/test/test-suite/test_resample.py b/test/test-suite/test_resample.py index 6fd5c18c15..6ac8704477 100644 --- a/test/test-suite/test_resample.py +++ b/test/test-suite/test_resample.py @@ -241,7 +241,7 @@ def test_thumbnail(self): @pytest.mark.skipif(not pyvips.at_least_libvips(8, 5), reason="requires libvips >= 8.5") def test_thumbnail_icc(self): - im = pyvips.Image.thumbnail(JPEG_FILE_XYB, 442, export_profile="srgb") + im = pyvips.Image.thumbnail(JPEG_FILE_XYB, 442, output_profile="srgb") assert im.width == 290 assert im.height == 442 diff --git a/tools/vipsthumbnail.c b/tools/vipsthumbnail.c index 3ff8c38a2f..852cde250c 100644 --- a/tools/vipsthumbnail.c +++ b/tools/vipsthumbnail.c @@ -105,6 +105,8 @@ * 2/10/20 * - support "stdin" as a magic input filename for thumbnail_source * - support ".suffix" as a magic output format for stdout write + * 30/4/25 + * - rename import/export profile args as input/oputput */ #ifdef HAVE_CONFIG_H @@ -131,8 +133,8 @@ static int thumbnail_width = 128; static int thumbnail_height = 128; static VipsSize size_restriction = VIPS_SIZE_BOTH; static char *output_format = "tn_%s.jpg"; -static char *export_profile = NULL; -static char *import_profile = NULL; +static char *output_profile = NULL; +static char *input_profile = NULL; static gboolean linear_processing = FALSE; static gboolean crop_image = FALSE; static gboolean no_rotate_image = FALSE; @@ -159,12 +161,12 @@ static GOptionEntry options[] = { G_OPTION_ARG_STRING, &output_format, N_("output to FORMAT"), N_("FORMAT") }, - { "export-profile", 'e', 0, - G_OPTION_ARG_FILENAME, &export_profile, + { "output-profile", 0, 0, + G_OPTION_ARG_FILENAME, &output_profile, N_("export with PROFILE"), N_("PROFILE") }, - { "import-profile", 'i', 0, - G_OPTION_ARG_FILENAME, &import_profile, + { "input-profile", 0, 0, + G_OPTION_ARG_FILENAME, &input_profile, N_("import untagged images with PROFILE"), N_("PROFILE") }, { "linear", 'a', 0, @@ -187,18 +189,28 @@ static GOptionEntry options[] = { { "version", 'v', 0, G_OPTION_ARG_NONE, &version, N_("print version"), NULL }, - { "format", 'f', G_OPTION_FLAG_HIDDEN, - G_OPTION_ARG_STRING, &output_format, - N_("set output format string to FORMAT"), - N_("FORMAT") }, + /* All deprecated. + */ + { "export-profile", 'e', G_OPTION_FLAG_HIDDEN, + G_OPTION_ARG_FILENAME, &output_profile, + N_("export with PROFILE"), + N_("PROFILE") }, + { "import-profile", 'i', G_OPTION_FLAG_HIDDEN, + G_OPTION_ARG_FILENAME, &input_profile, + N_("import untagged images with PROFILE"), + N_("PROFILE") }, { "eprofile", 0, G_OPTION_FLAG_HIDDEN, - G_OPTION_ARG_FILENAME, &export_profile, + G_OPTION_ARG_FILENAME, &output_profile, N_("export with PROFILE"), N_("PROFILE") }, { "iprofile", 0, G_OPTION_FLAG_HIDDEN, - G_OPTION_ARG_FILENAME, &import_profile, + G_OPTION_ARG_FILENAME, &input_profile, N_("import untagged images with PROFILE"), N_("PROFILE") }, + { "format", 'f', G_OPTION_FLAG_HIDDEN, + G_OPTION_ARG_STRING, &output_format, + N_("set output format string to FORMAT"), + N_("FORMAT") }, { "rotate", 't', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &rotate_image, N_("(deprecated, does nothing)"), NULL }, @@ -321,8 +333,8 @@ thumbnail_process(VipsObject *process, const char *name) "no-rotate", no_rotate_image, "crop", interesting, "linear", linear_processing, - "import-profile", import_profile, - "export-profile", export_profile, + "import-profile", input_profile, + "output-profile", output_profile, "intent", intent, NULL)) { VIPS_UNREF(source); @@ -337,8 +349,8 @@ thumbnail_process(VipsObject *process, const char *name) "no-rotate", no_rotate_image, "crop", interesting, "linear", linear_processing, - "import-profile", import_profile, - "export-profile", export_profile, + "import-profile", input_profile, + "output-profile", output_profile, "intent", intent, NULL)) return -1; From e397dbc5c278f1e617376f2dd0b42e281fc3c687 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 7 May 2025 15:53:25 +0200 Subject: [PATCH 156/174] doc: minor gi-docgen improvements (#4498) * doc: avoid gi-docgen linking syntax for non-doc comments * doc: port syntax highlighting to Markdown * doc: fix a couple of `seealso` admonitions * doc: fix a couple of broken links --- libvips/arithmetic/complex.c | 2 +- libvips/arithmetic/project.c | 2 +- libvips/arithmetic/round.c | 2 +- libvips/arithmetic/subtract.c | 2 +- libvips/colour/Lab2LabQ.c | 2 +- libvips/colour/LabQ2Lab.c | 2 +- libvips/colour/LabQ2LabS.c | 2 +- libvips/colour/LabQ2sRGB.c | 2 +- libvips/colour/rad2float.c | 2 +- libvips/conversion/cache.c | 2 +- libvips/conversion/flatten.c | 2 +- libvips/conversion/subsample.c | 4 ++-- libvips/convolution/compass.c | 2 +- libvips/convolution/convi.c | 4 ++-- libvips/convolution/spcor.c | 4 ++-- libvips/create/logmat.c | 2 +- libvips/draw/draw_flood.c | 6 +++--- libvips/foreign/jpeg2vips.c | 6 +++--- libvips/foreign/jpegload.c | 6 +++--- libvips/foreign/jpegsave.c | 2 +- libvips/foreign/magick6load.c | 2 +- libvips/foreign/magicksave.c | 2 +- libvips/foreign/quantise.c | 2 +- libvips/foreign/vips2jpeg.c | 2 +- libvips/histogram/hist_entropy.c | 4 ++-- libvips/histogram/hist_match.c | 2 +- libvips/histogram/percent.c | 4 ++-- libvips/iofuncs/buf.c | 2 +- libvips/iofuncs/cache.c | 2 +- libvips/iofuncs/region.c | 6 +++--- libvips/iofuncs/sinkmemory.c | 2 +- libvips/iofuncs/source.c | 6 +++--- libvips/iofuncs/system.c | 2 +- libvips/iofuncs/vips.c | 4 ++-- libvips/resample/interpolate.c | 2 +- libvips/resample/nohalo.cpp | 2 +- libvips/resample/resize.c | 2 +- libvips/resample/similarity.c | 2 +- 38 files changed, 54 insertions(+), 54 deletions(-) diff --git a/libvips/arithmetic/complex.c b/libvips/arithmetic/complex.c index c06a0796d0..442d67e8c4 100644 --- a/libvips/arithmetic/complex.c +++ b/libvips/arithmetic/complex.c @@ -20,7 +20,7 @@ * 19/11/11 * - redo as a class * 21/11/11 - * - add [method@Image.complexget] + * - add vips_complexget() * 29/9/15 * - return 0 for cross-product where one arg is zero */ diff --git a/libvips/arithmetic/project.c b/libvips/arithmetic/project.c index 47f7f38cd7..33c3915f33 100644 --- a/libvips/arithmetic/project.c +++ b/libvips/arithmetic/project.c @@ -6,7 +6,7 @@ * - gtkdoc * - small celanups * 11/9/13 - * - redo as a class, from [method@Image.hist_find] + * - redo as a class, from vips_hist_find() */ /* diff --git a/libvips/arithmetic/round.c b/libvips/arithmetic/round.c index 8b05f06688..1df980dcfa 100644 --- a/libvips/arithmetic/round.c +++ b/libvips/arithmetic/round.c @@ -71,7 +71,7 @@ vips_round_build(VipsObject *object) { VipsUnary *unary = (VipsUnary *) object; - /* Is this one of the int types? Degenerate to [method@Image.copy] if it + /* Is this one of the int types? Degenerate to vips_copy() if it * is. */ if (unary->in && diff --git a/libvips/arithmetic/subtract.c b/libvips/arithmetic/subtract.c index 7f797f807a..3e64f0f9fe 100644 --- a/libvips/arithmetic/subtract.c +++ b/libvips/arithmetic/subtract.c @@ -157,7 +157,7 @@ vips_subtract_buffer(VipsArithmetic *arithmetic, #define DX VIPS_FORMAT_DPCOMPLEX /* Type promotion for subtraction. Sign and value preserving. Make sure these - * match the case statement in [func@subtract_buffer] above. + * match the case statement in vips_subtract_buffer() above. */ static const VipsBandFormat vips_subtract_format_table[10] = { /* Band format: UC C US S UI I F X D DX */ diff --git a/libvips/colour/Lab2LabQ.c b/libvips/colour/Lab2LabQ.c index 9c79f8d88d..429bf4c160 100644 --- a/libvips/colour/Lab2LabQ.c +++ b/libvips/colour/Lab2LabQ.c @@ -161,7 +161,7 @@ vips_Lab2LabQ_init(VipsLab2LabQ *Lab2LabQ) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Convert a Lab three-band float image to LabQ ([enum@Vips.Coding.LABQ)]. + * Convert a Lab three-band float image to LabQ ([enum@Vips.Coding.LABQ]). * * ::: seealso * [method@Image.LabQ2Lab]. diff --git a/libvips/colour/LabQ2Lab.c b/libvips/colour/LabQ2Lab.c index 19a27daf26..8110325b74 100644 --- a/libvips/colour/LabQ2Lab.c +++ b/libvips/colour/LabQ2Lab.c @@ -147,7 +147,7 @@ vips_LabQ2Lab_init(VipsLabQ2Lab *LabQ2Lab) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Unpack a LabQ ([enum@Vips.Coding.LABQ)] image to a three-band float image. + * Unpack a LabQ ([enum@Vips.Coding.LABQ]) image to a three-band float image. * * ::: seealso * [method@Image.LabQ2Lab], [method@Image.LabQ2LabS], [method@Image.rad2float]. diff --git a/libvips/colour/LabQ2LabS.c b/libvips/colour/LabQ2LabS.c index 35c4f649f3..c146ebca70 100644 --- a/libvips/colour/LabQ2LabS.c +++ b/libvips/colour/LabQ2LabS.c @@ -126,7 +126,7 @@ vips_LabQ2LabS_init(VipsLabQ2LabS *LabQ2LabS) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Unpack a LabQ ([enum@Vips.Coding.LABQ)] image to a three-band short image. + * Unpack a LabQ ([enum@Vips.Coding.LABQ]) image to a three-band short image. * * ::: seealso * [method@Image.LabS2LabQ], [method@Image.LabQ2LabS], [method@Image.rad2float]. diff --git a/libvips/colour/LabQ2sRGB.c b/libvips/colour/LabQ2sRGB.c index b17530ef95..bcd06459a3 100644 --- a/libvips/colour/LabQ2sRGB.c +++ b/libvips/colour/LabQ2sRGB.c @@ -573,7 +573,7 @@ vips_LabQ2sRGB_init(VipsLabQ2sRGB *LabQ2sRGB) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Unpack a LabQ ([enum@Vips.Coding.LABQ)] image to a three-band short image. + * Unpack a LabQ ([enum@Vips.Coding.LABQ]) image to a three-band short image. * * ::: seealso * [method@Image.LabS2LabQ], [method@Image.LabQ2sRGB], [method@Image.rad2float]. diff --git a/libvips/colour/rad2float.c b/libvips/colour/rad2float.c index 08c6d2ae96..ede326f414 100644 --- a/libvips/colour/rad2float.c +++ b/libvips/colour/rad2float.c @@ -206,7 +206,7 @@ vips_rad2float_init(VipsRad2float *rad2float) * @out: (out): output image * @...: %NULL-terminated list of optional named arguments * - * Unpack a RAD ([enum@Vips.Coding.RAD)] image to a three-band float image. + * Unpack a RAD ([enum@Vips.Coding.RAD]) image to a three-band float image. * * ::: seealso * [method@Image.float2rad], [method@Image.LabQ2LabS]. diff --git a/libvips/conversion/cache.c b/libvips/conversion/cache.c index 8ac1285098..1a1190502e 100644 --- a/libvips/conversion/cache.c +++ b/libvips/conversion/cache.c @@ -1,4 +1,4 @@ -/* [method@Image.sink_screen] as an operation. +/* vips_sink_screen() as an operation. * * 13/1/12 * - from tilecache.c diff --git a/libvips/conversion/flatten.c b/libvips/conversion/flatten.c index ae07b51915..9a753ab7e2 100644 --- a/libvips/conversion/flatten.c +++ b/libvips/conversion/flatten.c @@ -6,7 +6,7 @@ * 4/1/14 * - better rounding * 9/5/15 - * - add max_alpha to match [method@Image.premultiply] etc. + * - add max_alpha to match vips_premultiply() etc. * 25/5/16 * - max_alpha defaults to 65535 for RGB16/GREY16 * 12/9/21 diff --git a/libvips/conversion/subsample.c b/libvips/conversion/subsample.c index 521e88f3ab..281a6e2879 100644 --- a/libvips/conversion/subsample.c +++ b/libvips/conversion/subsample.c @@ -14,7 +14,7 @@ * 2/11/13 * - add @point to force point sample mode * 22/1/16 - * - remove SEQUENTIAL hint, it confuses [method@Image.sequential] + * - remove SEQUENTIAL hint, it confuses vips_sequential() */ /* @@ -260,7 +260,7 @@ vips_subsample_class_init(VipsSubsampleClass *class) vobject_class->build = vips_subsample_build; /* We don't work well as sequential: we can easily skip the first few - * scanlines, and that confuses [method@Image.sequential]. + * scanlines, and that confuses vips_sequential(). */ VIPS_ARG_IMAGE(class, "input", 1, diff --git a/libvips/convolution/compass.c b/libvips/convolution/compass.c index 103c6f3e3f..10a60b42c0 100644 --- a/libvips/convolution/compass.c +++ b/libvips/convolution/compass.c @@ -1,7 +1,7 @@ /* repeatedly convolve with a rotating mask * * 23/10/13 - * - from [method@Image.conv] + * - from vips_conv() * 8/5/17 * - default to float ... int will often lose precision and should not be * the default diff --git a/libvips/convolution/convi.c b/libvips/convolution/convi.c index f0834ec0ed..4f4a584530 100644 --- a/libvips/convolution/convi.c +++ b/libvips/convolution/convi.c @@ -1270,9 +1270,9 @@ vips_convi_init(VipsConvi *convi) * @mask is converted to an integer mask with rint() of each element, rint of * scale and rint of offset. Each output pixel is then calculated as * - * |[ + * ``` * sigma[i]{pixel[i] * mask[i]} / scale + offset - * ]| + * ``` * * The output image always has the same [enum@BandFormat] as the input image. * diff --git a/libvips/convolution/spcor.c b/libvips/convolution/spcor.c index 8a52dfe8c6..992c16921b 100644 --- a/libvips/convolution/spcor.c +++ b/libvips/convolution/spcor.c @@ -345,12 +345,12 @@ vips_spcor_init(VipsSpcor *spcor) * * The correlation coefficient is calculated as: * - * |[ + * ``` * sumij (ref(i,j)-mean(ref))(inkl(i,j)-mean(inkl)) * c(k,l) = ------------------------------------------------ * sqrt(sumij (ref(i,j)-mean(ref))^2) * * sqrt(sumij (inkl(i,j)-mean(inkl))^2) - * ]| + * ``` * * where inkl is the area of @in centred at position (k,l). * diff --git a/libvips/create/logmat.c b/libvips/create/logmat.c index 0f5aeb8880..4b7d186523 100644 --- a/libvips/create/logmat.c +++ b/libvips/create/logmat.c @@ -15,7 +15,7 @@ * 20/10/13 * - redone as a class from logmat.c * 16/12/14 - * - default to int output to match [method@Image.conv] + * - default to int output to match vips_conv() * - use @precision, not @integer */ diff --git a/libvips/draw/draw_flood.c b/libvips/draw/draw_flood.c index 02be8ffb17..da40fee57f 100644 --- a/libvips/draw/draw_flood.c +++ b/libvips/draw/draw_flood.c @@ -103,8 +103,8 @@ typedef struct _Buffer { } Buffer; /* What we track during a flood. We have this in a separate struct so that we - * can support [func@_draw_flood_direct] ... a fast path for - * [method@Image.labelregions] that avoids all of the GObject call overhead. This + * can support vips__draw_flood_direct() ... a fast path for + * vips_labelregions() that avoids all of the GObject call overhead. This * gives a huge speedup, >x10 in many cases. */ typedef struct _Flood { @@ -623,7 +623,7 @@ vips_draw_flood_init(VipsDrawFlood *draw_flood) { } -/* Direct path to flood for [method@Image.labelregions]. We need to avoid the function +/* Direct path to flood for vips_labelregions(). We need to avoid the function * dispatch system for speed. * * Equivalent to: diff --git a/libvips/foreign/jpeg2vips.c b/libvips/foreign/jpeg2vips.c index cc5e5224f8..b1db668056 100644 --- a/libvips/foreign/jpeg2vips.c +++ b/libvips/foreign/jpeg2vips.c @@ -62,7 +62,7 @@ * 16/10/14 * - add "autorotate" option * 20/1/15 - * - don't call jpe[func@GLib.finish_decompress], all it does is read and check + * - don't call jpeg_finish_decompress(), all it does is read and check * the tail of the file * 26/2/15 * - close the jpeg read down early for a header read ... this saves an @@ -421,9 +421,9 @@ readjpeg_free(ReadJpeg *jpeg) jpeg->eman.pub.num_warnings = 0; } - /* Don't call jpe[func@GLib.finish_decompress]. It just checks the tail of the + /* Don't call jpeg_finish_decompress(). It just checks the tail of the * file and who cares about that. All mem is freed in - * jpe[func@GLib.destroy_decompress]. + * jpeg_destroy_decompress(). */ /* I don't think this can fail. It's harmless to call many times. diff --git a/libvips/foreign/jpegload.c b/libvips/foreign/jpegload.c index 951721b944..6847ab152c 100644 --- a/libvips/foreign/jpegload.c +++ b/libvips/foreign/jpegload.c @@ -470,12 +470,12 @@ vips_foreign_load_jpeg_buffer_init(VipsForeignLoadJpegBuffer *buffer) * * Example: * - * ```C - * vips_jpegload("fred.jpg", &out, + * ```c + * vips_jpegload("fred.jpg", &out, * "shrink", 8, * "fail_on", VIPS_FAIL_ON_TRUNCATED, * NULL); - * ```C + * ``` * * Any embedded ICC profiles are ignored: you always just get the RGB from * the file. Instead, the embedded profile will be attached to the image as diff --git a/libvips/foreign/jpegsave.c b/libvips/foreign/jpegsave.c index bd448ea9e8..271744dcb9 100644 --- a/libvips/foreign/jpegsave.c +++ b/libvips/foreign/jpegsave.c @@ -155,7 +155,7 @@ vips_foreign_save_jpeg_class_init(VipsForeignSaveJpegClass *class) foreign_class->suffs = vips__jpeg_suffs; - /* See also [func@Foreign.save_tiff_build] when saving JPEG in TIFF. + /* See also vips_foreign_save_tiff_build() when saving JPEG in TIFF. */ save_class->saveable = VIPS_SAVEABLE_RGB_CMYK; save_class->format_table = bandfmt_jpeg; diff --git a/libvips/foreign/magick6load.c b/libvips/foreign/magick6load.c index 8f047dba58..61fcf7fba1 100644 --- a/libvips/foreign/magick6load.c +++ b/libvips/foreign/magick6load.c @@ -5,7 +5,7 @@ * 3/2/03 JC * - some InitializeMagick() fail with NULL arg * 2/11/04 - * - im_magick2[func@header] also checks sensible width/height + * - im_magick2vips_header() also checks sensible width/height * 28/10/05 * - copy attributes to meta * - write many-frame images as a big column if all frames have identical diff --git a/libvips/foreign/magicksave.c b/libvips/foreign/magicksave.c index eda091b826..b740467bd0 100644 --- a/libvips/foreign/magicksave.c +++ b/libvips/foreign/magicksave.c @@ -5,7 +5,7 @@ * - fix GraphicsMagick support * 17/2/19 * - support ICC, XMP, EXIF, IPTC metadata - * - write with a single call to [method@Image.sink_disc] + * - write with a single call to vips_sink_disc() * 29/6/19 * - support "strip" option * 6/7/19 [deftomat] diff --git a/libvips/foreign/quantise.c b/libvips/foreign/quantise.c index 0b1e194cde..62d79b96bc 100644 --- a/libvips/foreign/quantise.c +++ b/libvips/foreign/quantise.c @@ -87,7 +87,7 @@ vips__quantise_image_quantize(VipsQuantiseImage *const input_image, return liq_image_quantize(input_image, options, result_output); } -/* Like [func@_quantise_image_quantize], but make a fixed palette that won't +/* Like vips__quantise_image_quantize(), but make a fixed palette that won't * get remapped during dithering. */ VipsQuantiseError diff --git a/libvips/foreign/vips2jpeg.c b/libvips/foreign/vips2jpeg.c index cce1ab2298..9e5226b864 100644 --- a/libvips/foreign/vips2jpeg.c +++ b/libvips/foreign/vips2jpeg.c @@ -520,7 +520,7 @@ write_jpeg_block(VipsRegion *region, VipsRect *area, void *a) write->row_pointer[y] = (JSAMPROW) VIPS_REGION_ADDR(region, area->left, area->top + y); - /* Catch any longjmp()s from jpe[func@GLib.write_scanlines] here. + /* Catch any longjmp()s from jpeg_write_scanlines() here. */ if (setjmp(write->eman.jmp)) return -1; diff --git a/libvips/histogram/hist_entropy.c b/libvips/histogram/hist_entropy.c index cadcbab712..794366edc5 100644 --- a/libvips/histogram/hist_entropy.c +++ b/libvips/histogram/hist_entropy.c @@ -134,9 +134,9 @@ vips_hist_entropy_init(VipsHistEntropy *entropy) * * Estimate image entropy from a histogram. Entropy is calculated as: * - * |[ + * ``` * -sum(p * log2(p)) - * ]| + * ``` * * where p is histogram-value / sum-of-histogram-values. * diff --git a/libvips/histogram/hist_match.c b/libvips/histogram/hist_match.c index e6d5a97908..978cd8b8bb 100644 --- a/libvips/histogram/hist_match.c +++ b/libvips/histogram/hist_match.c @@ -188,7 +188,7 @@ vips_hist_match_init(VipsHistMatch *match) * * ::: seealso * [method@Image.maplut], [method@Image.hist_find], [method@Image.hist_norm], - * [method@Image.hist_cum]. + * [method@Image.hist_cum]. * * Returns: 0 on success, -1 on error */ diff --git a/libvips/histogram/percent.c b/libvips/histogram/percent.c index f07b77641b..4199bd9b41 100644 --- a/libvips/histogram/percent.c +++ b/libvips/histogram/percent.c @@ -141,10 +141,10 @@ vips_percent_init(VipsPercent *percent) * [method@Image.percent] returns (through the @threshold parameter) the threshold * below which there are @percent values of @in. For example: * - * |[ + * ```bash * $ vips percent k2.jpg 90 * 214 - * ]| + * ``` * * Means that 90% of pixels in `k2.jpg` have a value less than 214. * diff --git a/libvips/iofuncs/buf.c b/libvips/iofuncs/buf.c index e45684c3bb..ab30ea0797 100644 --- a/libvips/iofuncs/buf.c +++ b/libvips/iofuncs/buf.c @@ -275,7 +275,7 @@ vips_buf_appendns(VipsBuf *buf, const char *str, int sz) cpy = VIPS_MIN(n, avail); - /* Can't use [func@GLib.strlcpy] here, we don't want to drop the end of the + /* Can't use g_strlcpy() here, we don't want to drop the end of the * string. * * gcc10.3 (I think?) issues a false-positive warning about this. diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index 39145399db..4df328f91f 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -42,7 +42,7 @@ what about delayed writes ... do we ever write in close? we shouldn't, should do in evalend or written or somesuch - use [func@GLib.param_values_cmp] instead of value_equal()? + use g_param_values_cmp() instead of value_equal()? */ diff --git a/libvips/iofuncs/region.c b/libvips/iofuncs/region.c index 15bdcba096..7e169f6f05 100644 --- a/libvips/iofuncs/region.c +++ b/libvips/iofuncs/region.c @@ -356,14 +356,14 @@ vips_region_summary(VipsObject *object, VipsBuf *buf) /* If a region is being created in one thread (eg. the main thread) and then * used in another (eg. a worker thread), the new thread needs to tell VIPS - * to stop sanity [func@GLib.assert] fails. The previous owner needs to - * [func@_region_no_ownership] before we can call this. + * to stop sanity g_assert() fails. The previous owner needs to + * vips__region_no_ownership() before we can call this. */ void vips__region_take_ownership(VipsRegion *region) { /* Lock so that there's a memory barrier with the thread doing the - * [func@_region_no_ownership] before us. + * vips__region_no_ownership() before us. */ VIPS_GATE_START("vips__region_take_ownership: wait"); diff --git a/libvips/iofuncs/sinkmemory.c b/libvips/iofuncs/sinkmemory.c index 5045b5fee0..2abf833af7 100644 --- a/libvips/iofuncs/sinkmemory.c +++ b/libvips/iofuncs/sinkmemory.c @@ -76,7 +76,7 @@ typedef struct _SinkMemory { SinkMemoryArea *old_area; /* A region covering the whole of the output image ... we write to - * this from many workers with [method@Region.prepare_to]. + * this from many workers with vips_region_prepare_to(). */ VipsRegion *region; } SinkMemory; diff --git a/libvips/iofuncs/source.c b/libvips/iofuncs/source.c index e679e55ffa..bff7c25d0c 100644 --- a/libvips/iofuncs/source.c +++ b/libvips/iofuncs/source.c @@ -119,7 +119,7 @@ /* -1 on a pipe isn't actually unbounded. Have a limit to prevent * huge sources accidentally filling memory. * - * This can be configured with [func@pipe_read_limit_set]. + * This can be configured with vips_pipe_read_limit_set(). */ static gint64 vips__pipe_read_limit = 1024 * 1024 * 1024; @@ -164,7 +164,7 @@ vips_source_test_seek(VipsSource *source) /* Can we seek this input? * * We need to call the method directly rather than via - * [func@source_seek] etc. or we might trigger seek emulation. + * vips_source_seek() etc. or we might trigger seek emulation. */ if (source->data || class->seek(source, 0, SEEK_CUR) != -1) { @@ -740,7 +740,7 @@ vips_source_decode(VipsSource *source) VIPS_FREEF(g_byte_array_unref, source->sniff); /* Now decode is set, header_bytes will be freed once it's - * exhausted, see [func@source_read]. + * exhausted, see vips_source_read(). */ } diff --git a/libvips/iofuncs/system.c b/libvips/iofuncs/system.c index ec9a1b0408..f6e8137668 100644 --- a/libvips/iofuncs/system.c +++ b/libvips/iofuncs/system.c @@ -7,7 +7,7 @@ * 10/3/03 JC * - out can be NULL * 23/12/04 - * - use [func@GLib.mkstemp] + * - use g_mkstemp() * 8/9/09 * - add .v suffix (thanks Roland) * - use vipsbuf diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index db892bb59c..9e412097a6 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -130,7 +130,7 @@ vips__open_image_read(const char *filename) { int fd; - /* Try to open read-write, so that calls to [method@Image.inplace] will + /* Try to open read-write, so that calls to vips_image_inplace() will * work. When we later mmap this file, we set read-only, so there * is little danger of scrubbing over files we own. */ @@ -170,7 +170,7 @@ vips__open_image_write(const char *filename, gboolean temp) * * This can fail since not all filesystems support it. In this case, * we open as a regular file and rely on the delete-on-close - * mechanism, see [method@Image.delete]. + * mechanism, see vips_image_delete(). */ if (temp) { char *dirname; diff --git a/libvips/resample/interpolate.c b/libvips/resample/interpolate.c index df3da9c97b..51592bfcd4 100644 --- a/libvips/resample/interpolate.c +++ b/libvips/resample/interpolate.c @@ -122,7 +122,7 @@ G_DEFINE_ABSTRACT_TYPE(VipsInterpolate, vips_interpolate, VIPS_TYPE_OBJECT); * * ::: seealso * [callback@InterpolateMethod], [class@Object] or - * [func@Interpolate.bilinear_static]. + * [func@Interpolate.bilinear_static]. */ #ifdef DEBUG diff --git a/libvips/resample/nohalo.cpp b/libvips/resample/nohalo.cpp index 92f1e01ea1..8096a2aefc 100644 --- a/libvips/resample/nohalo.cpp +++ b/libvips/resample/nohalo.cpp @@ -230,7 +230,7 @@ * http://doi.acm.org/10.1145/1557626.1557657. */ -/* Uncomment to enable bounds checking for [func@REGION_ADDR]. +/* Uncomment to enable bounds checking for VIPS_REGION_ADDR(). */ #define DEBUG diff --git a/libvips/resample/resize.c b/libvips/resample/resize.c index 4a949bf40e..ccbc880085 100644 --- a/libvips/resample/resize.c +++ b/libvips/resample/resize.c @@ -370,7 +370,7 @@ vips_resize_class_init(VipsResizeClass *class) G_STRUCT_OFFSET(VipsResize, idy), -10000000.0, 10000000.0, 0.0); - /* It's a kernel now we use vips_reduce() not [method@Image.affine]. + /* It's a kernel now we use vips_reduce() not vips_affine(). */ VIPS_ARG_INTERPOLATE(class, "interpolate", 2, _("Interpolate"), diff --git a/libvips/resample/similarity.c b/libvips/resample/similarity.c index 770ad55a41..5eeb12abeb 100644 --- a/libvips/resample/similarity.c +++ b/libvips/resample/similarity.c @@ -1,4 +1,4 @@ -/* simple wrapper over [method@Image.affine] to make scale / rotate easy from the +/* simple wrapper over vips_affine() to make scale / rotate easy from the * command-line * * 3/10/13 From e86d807e141bc3fa640467a020b1269ee93cb20a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 7 May 2025 15:00:30 +0100 Subject: [PATCH 157/174] doc clarification --- doc/developer-checklist.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/developer-checklist.md b/doc/developer-checklist.md index 86aa3f61a5..3c73497748 100644 --- a/doc/developer-checklist.md +++ b/doc/developer-checklist.md @@ -1,4 +1,4 @@ -Title: Using > Checklist for libvips users +Title: Using > Checklist for programmers using libvips libvips is a slightly unusual library and you may need to take some of its stranger features into account when you design software that uses it. From 27ab9b058dffd290a35a012c822004e216a21b84 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 7 May 2025 18:24:55 +0100 Subject: [PATCH 158/174] revise VipsSaveable * start testing and fixing SAVEABLE vips__foreign_convert_saveable() doesn't seem to work for all image types, start testing it more carefully. test_matrix tests matrixsave, which uses SAVEABLE_MONO ... test conversion of all image types * add VipsSaveableFlags a bit saner ... and deprecate VipsSaveable * existing tests pass * remove dbg code * start adding more tests * rename VipsSaveable as VipsForeignSaveable a bit more consistent * more tests * more VipsSaveable enum back into the public API since pyvips needs it * Alias VipsSaveable to VipsForeignSaveable * Update ChangeLog Co-authored-by: Kleis Auke Wolthuizen * fix the CI fail vips_image_guess_format() could return a bad format for VIPS_INTERPRETATION_ERROR. Fixes a fuzzing fail. --------- Co-authored-by: Kleis Auke Wolthuizen --- ChangeLog | 1 + libvips/conversion/cast.c | 3 +- libvips/foreign/cgifsave.c | 3 +- libvips/foreign/csvsave.c | 2 +- libvips/foreign/dzsave.c | 8 +- libvips/foreign/fitssave.c | 2 +- libvips/foreign/foreign.c | 416 +++++++++++------------- libvips/foreign/heifsave.c | 3 +- libvips/foreign/jp2ksave.c | 2 +- libvips/foreign/jpegsave.c | 5 +- libvips/foreign/jxlsave.c | 4 +- libvips/foreign/matrixsave.c | 2 +- libvips/foreign/niftisave.c | 2 +- libvips/foreign/pngsave.c | 5 +- libvips/foreign/ppmsave.c | 2 +- libvips/foreign/radsave.c | 6 +- libvips/foreign/rawsave.c | 2 +- libvips/foreign/spngsave.c | 5 +- libvips/foreign/tiffsave.c | 7 +- libvips/foreign/vips2magick.c | 2 +- libvips/foreign/vipssave.c | 2 +- libvips/foreign/webpsave.c | 3 +- libvips/include/vips/almostdeprecated.h | 18 + libvips/include/vips/enumtypes.c.in | 8 + libvips/include/vips/enumtypes.h.in | 4 + libvips/include/vips/foreign.h | 38 +-- libvips/include/vips/internal.h | 2 +- libvips/iofuncs/buf.c | 12 +- libvips/iofuncs/header.c | 12 +- test/test-suite/test_foreign.py | 32 +- 30 files changed, 322 insertions(+), 291 deletions(-) diff --git a/ChangeLog b/ChangeLog index e906a300d8..9b14727956 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,6 +26,7 @@ master - rename `thumbnail`'s export/import profile options as input/output for consistency - restore vips_remosaic(), it was not being linked +- deprecate VipsSaveable, add VipsForeignSaveable 8.16.1 diff --git a/libvips/conversion/cast.c b/libvips/conversion/cast.c index 9eb908a464..7fbf307b69 100644 --- a/libvips/conversion/cast.c +++ b/libvips/conversion/cast.c @@ -488,8 +488,7 @@ vips_cast_build(VipsObject *object) if (cast->shift && !vips_band_format_isint(in->BandFmt) && vips_band_format_isint(cast->format)) { - if (vips_cast(in, &t[1], - vips_image_guess_format(in), NULL)) + if (vips_cast(in, &t[1], vips_image_guess_format(in), NULL)) return -1; in = t[1]; } diff --git a/libvips/foreign/cgifsave.c b/libvips/foreign/cgifsave.c index 7298e4fbda..6ad0bf6bc3 100644 --- a/libvips/foreign/cgifsave.c +++ b/libvips/foreign/cgifsave.c @@ -885,7 +885,8 @@ vips_foreign_save_cgif_class_init(VipsForeignSaveCgifClass *class) foreign_class->suffs = vips__save_cgif_suffs; - save_class->saveable = VIPS_SAVEABLE_RGBA_ONLY; + save_class->saveable = + VIPS_FOREIGN_SAVEABLE_RGB | VIPS_FOREIGN_SAVEABLE_ALPHA; save_class->format_table = bandfmt_gif; VIPS_ARG_DOUBLE(class, "dither", 10, diff --git a/libvips/foreign/csvsave.c b/libvips/foreign/csvsave.c index 69e273db1e..61e6ea85af 100644 --- a/libvips/foreign/csvsave.c +++ b/libvips/foreign/csvsave.c @@ -217,7 +217,7 @@ vips_foreign_save_csv_class_init(VipsForeignSaveCsvClass *class) foreign_class->suffs = vips_foreign_save_csv_suffs; - save_class->saveable = VIPS_SAVEABLE_MONO; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_MONO; VIPS_ARG_STRING(class, "separator", 13, _("Separator"), diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index 8235da46e1..05eafcea27 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -2054,8 +2054,10 @@ vips_foreign_save_dz_build(VipsObject *object) coding[VIPS_CODING_NONE] = TRUE; if (vips__foreign_convert_saveable(save->ready, &z, - VIPS_SAVEABLE_RGB_CMYK, bandfmt_dzsave, coding, - save->background)) + VIPS_FOREIGN_SAVEABLE_MONO | + VIPS_FOREIGN_SAVEABLE_RGB | + VIPS_FOREIGN_SAVEABLE_CMYK, + bandfmt_dzsave, coding, save->background)) return -1; VIPS_UNREF(save->ready); @@ -2321,7 +2323,7 @@ vips_foreign_save_dz_class_init(VipsForeignSaveDzClass *class) foreign_class->suffs = dz_suffs; - save_class->saveable = VIPS_SAVEABLE_ANY; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_ANY; save_class->format_table = bandfmt_dz; save_class->coding[VIPS_CODING_LABQ] = TRUE; diff --git a/libvips/foreign/fitssave.c b/libvips/foreign/fitssave.c index 427f9d4e56..51dce1e140 100644 --- a/libvips/foreign/fitssave.c +++ b/libvips/foreign/fitssave.c @@ -136,7 +136,7 @@ vips_foreign_save_fits_class_init(VipsForeignSaveFitsClass *class) foreign_class->suffs = vips__fits_suffs; - save_class->saveable = VIPS_SAVEABLE_ANY; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_ANY; save_class->format_table = bandfmt_fits; VIPS_ARG_STRING(class, "filename", 1, diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 57a2da8035..88807976df 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -317,7 +317,7 @@ * * foreign_class->suffs = vips__foreign_csv_suffs; * - * save_class->saveable = VIPS_SAVEABLE_MONO; + * save_class->saveable = VIPS_FOREIGN_SAVEABLE_MONO; * // no need to define ->format_table, we don't want the input * // cast for us * @@ -783,11 +783,6 @@ vips_foreign_find_load_source(VipsSource *source) return NULL; } - /* All source loaders should be NOCACHE. - */ - g_assert(VIPS_OPERATION_CLASS(load_class)->flags & - VIPS_OPERATION_NOCACHE); - return G_OBJECT_CLASS_NAME(load_class); } @@ -1350,8 +1345,12 @@ vips_foreign_save_summary_class(VipsObjectClass *object_class, VipsBuf *buf) VIPS_OBJECT_CLASS(vips_foreign_save_parent_class) ->summary_class(object_class, buf); - vips_buf_appendf(buf, ", %s", - vips_enum_nick(VIPS_TYPE_SAVEABLE, class->saveable)); + GValue value = { 0 }; + g_value_init(&value, VIPS_TYPE_FOREIGN_SAVEABLE); + g_value_set_flags(&value, class->saveable); + vips_buf_appends(buf, ", "); + vips_buf_appendgv(buf, &value); + g_value_unset(&value); } static VipsObject * @@ -1374,51 +1373,45 @@ vips_foreign_save_new_from_string(const char *string) return VIPS_OBJECT(save); } -/* Convert an image for saving. +/* Apply a set of saveable flags. + * + * - if the saver supports mono and we have a mono-looking image, we are done + * - if the saver supports CMYK and we have a CMYK-looking image, we are done + * - if this is a CMYK-looking image, import to XYZ + * - go to rgb + * - if the saver supports rgb, we are done + * - if the saver supports cmyk, go to cmyk + * - if the saver supports mono, go to mono */ -int -vips__foreign_convert_saveable(VipsImage *in, VipsImage **ready, - VipsSaveable saveable, VipsBandFormat *format, VipsCoding *coding, - VipsArrayDouble *background) +static int +vips_foreign_apply_saveable(VipsImage *in, VipsImage **ready, + VipsForeignSaveable saveable) { + // is this a 16-bit source image + gboolean sixteenbit = in->BandFmt == VIPS_FORMAT_USHORT; + + VipsImage *out; + VipsInterpretation interpretation; + /* in holds a reference to the output of our chain as we build it. */ g_object_ref(in); - /* For coded images, can this class save the coding we are in now? - * Nothing to do. + /* ANY? we are done. */ - if (in->Coding != VIPS_CODING_NONE && - coding[in->Coding]) { - *ready = in; - return 0; - } - - /* For uncoded images, if this saver supports ANY bands and this - * format we have nothing to do. - */ - if (in->Coding == VIPS_CODING_NONE && - saveable == VIPS_SAVEABLE_ANY && - format[in->BandFmt] == in->BandFmt) { + if (saveable & VIPS_FOREIGN_SAVEABLE_ANY) { *ready = in; return 0; } - /* Otherwise ... we need to decode and then (possibly) recode at the - * end. - */ - /* If this is an VIPS_CODING_LABQ, we can go straight to RGB. */ if (in->Coding == VIPS_CODING_LABQ) { - VipsImage *out; - if (vips_LabQ2sRGB(in, &out, NULL)) { g_object_unref(in); return -1; } g_object_unref(in); - in = out; } @@ -1426,43 +1419,34 @@ vips__foreign_convert_saveable(VipsImage *in, VipsImage **ready, * scRGB or XYZ. */ if (in->Coding == VIPS_CODING_RAD) { - VipsImage *out; - if (vips_rad2float(in, &out, NULL)) { g_object_unref(in); return -1; } g_object_unref(in); - in = out; } - /* If the saver supports RAD, we need to go to scRGB or XYZ. + /* If this is a mono-ish looking image and our saver supports mono, we + * are done. We are not too strict about what a mono image is! We need to + * work for things like "extract_band 1" on an RGB Image. */ - if (coding[VIPS_CODING_RAD]) { - if (in->Type != VIPS_INTERPRETATION_scRGB && - in->Type != VIPS_INTERPRETATION_XYZ) { - VipsImage *out; - - if (vips_colourspace(in, &out, VIPS_INTERPRETATION_scRGB, NULL)) { - g_object_unref(in); - return -1; - } - g_object_unref(in); - - in = out; - } + if ((saveable & VIPS_FOREIGN_SAVEABLE_MONO) && + in->Bands < 3) { + *ready = in; + return 0; } - /* If this image is CMYK and the saver is RGB-only, use lcms to try to - * import to XYZ. + /* CMYK image? Use the sanity-checked interpretation value. */ - if (in->Type == VIPS_INTERPRETATION_CMYK && - in->Bands >= 4 && - (saveable == VIPS_SAVEABLE_RGB || - saveable == VIPS_SAVEABLE_RGBA || - saveable == VIPS_SAVEABLE_RGBA_ONLY)) { - VipsImage *out; + if (vips_image_guess_interpretation(in) == VIPS_INTERPRETATION_CMYK && + in->Bands >= 4) { + /* If our saver supports CMYK we are done, otherwise import to XYZ. + */ + if (saveable & VIPS_FOREIGN_SAVEABLE_CMYK) { + *ready = in; + return 0; + } if (vips_icc_import(in, &out, "pcs", VIPS_PCS_XYZ, @@ -1473,251 +1457,227 @@ vips__foreign_convert_saveable(VipsImage *in, VipsImage **ready, return -1; } g_object_unref(in); - in = out; } - /* If this is something other than CMYK or RAD, and it's not already - * an RGB image, eg. maybe a LAB image, we need to transform - * to RGB. + /* If the saver supports RGB, go to RGB, or RGB16 if this is a ushort + * source. */ - if (!coding[VIPS_CODING_RAD] && - in->Bands >= 3 && - in->Type != VIPS_INTERPRETATION_CMYK && - in->Type != VIPS_INTERPRETATION_sRGB && - in->Type != VIPS_INTERPRETATION_RGB16 && - vips_colourspace_issupported(in) && - (saveable == VIPS_SAVEABLE_RGB || - saveable == VIPS_SAVEABLE_RGBA || - saveable == VIPS_SAVEABLE_RGBA_ONLY || - saveable == VIPS_SAVEABLE_RGB_CMYK)) { - VipsImage *out; - VipsInterpretation interpretation; - - /* Do we make RGB or RGB16? We don't want to squash a 16-bit - * RGB down to 8 bits if the saver supports 16. - */ - if (vips_band_format_is8bit(format[in->BandFmt])) - interpretation = VIPS_INTERPRETATION_sRGB; - else - interpretation = VIPS_INTERPRETATION_RGB16; + if (saveable & VIPS_FOREIGN_SAVEABLE_RGB) { + interpretation = sixteenbit ? + VIPS_INTERPRETATION_RGB16 : VIPS_INTERPRETATION_sRGB; if (vips_colourspace(in, &out, interpretation, NULL)) { g_object_unref(in); return -1; } g_object_unref(in); - in = out; + + *ready = in; + return 0; } - /* VIPS_SAVEABLE_RGBA_ONLY does not support mono types ... convert - * to sRGB. + /* If the saver supports CMYK, go to RGB, or RGB16 if this is a ushort + * source. */ - if (!coding[VIPS_CODING_RAD] && - in->Bands < 3 && - saveable == VIPS_SAVEABLE_RGBA_ONLY) { - VipsImage *out; - VipsInterpretation interpretation; - - /* Do we make RGB or RGB16? We don't want to squash a 16-bit - * RGB down to 8 bits if the saver supports 16. - */ - if (vips_band_format_is8bit(format[in->BandFmt])) - interpretation = VIPS_INTERPRETATION_sRGB; - else - interpretation = VIPS_INTERPRETATION_RGB16; - - if (vips_colourspace(in, &out, interpretation, NULL)) { + if (saveable & VIPS_FOREIGN_SAVEABLE_CMYK) { + if (vips_icc_export(in, &out, + "output-profile", "cmyk", + "depth", sixteenbit ? 16 : 8, + NULL)) { g_object_unref(in); return -1; } g_object_unref(in); - in = out; + + *ready = in; + return 0; } - /* Get the bands right. We must do this after all colourspace - * transforms, since they can change the number of bands. + /* If the saver supports mono, go to B_W, or GREY16 if this is a ushort + * source. */ - if (in->Coding == VIPS_CODING_NONE) { - /* Do we need to flatten out an alpha channel? There needs to - * be an alpha there now, and this writer needs to not support - * alpha. - */ - if ((in->Bands == 2 || - (in->Bands == 4 && - in->Type != VIPS_INTERPRETATION_CMYK)) && - (saveable == VIPS_SAVEABLE_MONO || - saveable == VIPS_SAVEABLE_RGB || - saveable == VIPS_SAVEABLE_RGB_CMYK)) { - VipsImage *out; - - if (vips_flatten(in, &out, - "background", background, - NULL)) { - g_object_unref(in); - return -1; - } - g_object_unref(in); + if (saveable & VIPS_FOREIGN_SAVEABLE_MONO) { + interpretation = sixteenbit ? + VIPS_INTERPRETATION_GREY16 : VIPS_INTERPRETATION_B_W; - in = out; + if (vips_colourspace(in, &out, interpretation, NULL)) { + g_object_unref(in); + return -1; } + g_object_unref(in); + in = out; - /* Other alpha removal strategies ... just drop the extra - * bands. - */ - - else if (in->Bands > 3 && - (saveable == VIPS_SAVEABLE_RGB || - (saveable == VIPS_SAVEABLE_RGB_CMYK && - in->Type != VIPS_INTERPRETATION_CMYK))) { - VipsImage *out; - - /* Don't let 4 bands though unless the image really is - * a CMYK. - * - * Consider a RGBA png being saved as JPG. We can - * write CMYK jpg, but we mustn't do that for RGBA - * images. - */ - if (vips_extract_band(in, &out, 0, - "n", 3, - NULL)) { - g_object_unref(in); - return -1; - } - g_object_unref(in); + *ready = in; + return 0; + } - in = out; - } - else if (in->Bands > 4 && - ((saveable == VIPS_SAVEABLE_RGB_CMYK && - in->Type == VIPS_INTERPRETATION_CMYK) || - saveable == VIPS_SAVEABLE_RGBA || - saveable == VIPS_SAVEABLE_RGBA_ONLY)) { - VipsImage *out; + vips_error("VipsForeignSave", _("saver does not support any output type")); + return -1; +} - if (vips_extract_band(in, &out, 0, - "n", 4, - NULL)) { - g_object_unref(in); - return -1; - } - g_object_unref(in); +/* Do all the colourspace conversions to get an image ready for saving. Don't + * finalize alpha or numeric format. + */ +int +vips__foreign_convert_saveable(VipsImage *in, VipsImage **ready, + VipsForeignSaveable saveable, VipsBandFormat *format, VipsCoding *coding, + VipsArrayDouble *background) +{ + VipsBandFormat original_format = in->BandFmt; - in = out; - } - else if (in->Bands > 1 && - saveable == VIPS_SAVEABLE_MONO) { - VipsImage *out; + VipsImage *out; - if (vips_extract_band(in, &out, 0, NULL)) { - g_object_unref(in); - return -1; - } - g_object_unref(in); + /* in holds a reference to the output of our chain as we build it. + */ + g_object_ref(in); - in = out; - } + /* For coded images, can this class save the coding we are in now? + * Nothing to do. + */ + if (in->Coding != VIPS_CODING_NONE && + coding[in->Coding]) { + *ready = in; + return 0; + } - /* Else we have VIPS_SAVEABLE_ANY and we don't chop bands down. - */ + /* For uncoded images, if this saver supports ANY and this + * format, we have nothing to do. + */ + if (in->Coding == VIPS_CODING_NONE && + (saveable & VIPS_FOREIGN_SAVEABLE_ANY) && + format[in->BandFmt] == in->BandFmt) { + *ready = in; + return 0; } - /* Handle the ushort interpretations. - * - * RGB16 and GREY16 use 0-65535 for black-white. If we have an image - * tagged like this, and it has more than 8 bits (we leave crazy uchar - * images tagged as RGB16 alone), we'll need to get it ready for the - * saver. + /* Otherwise ... we need to decode and then (possibly) recode at the + * end. */ - if ((in->Type == VIPS_INTERPRETATION_RGB16 || - in->Type == VIPS_INTERPRETATION_GREY16) && - !vips_band_format_is8bit(in->BandFmt)) { - /* If the saver supports ushort, cast to ushort. It may be - * float at the moment, for example. - * - * If the saver does not support ushort, automatically shift - * it down. This is the behaviour we want for saving an RGB16 - * image as JPG, for example. - */ - if (format[VIPS_FORMAT_USHORT] == VIPS_FORMAT_USHORT) { - VipsImage *out; - if (vips_cast(in, &out, VIPS_FORMAT_USHORT, NULL)) { - g_object_unref(in); - return -1; - } + /* Apply saveable conversions to get mono/rgb/cmyk. + */ + if (vips_foreign_apply_saveable(in, &out, saveable)) { + g_object_unref(in); + return -1; + } + g_object_unref(in); + in = out; + + /* Flatten alpha, if the saver does not support it. + */ + if (in->Coding == VIPS_CODING_NONE && + vips_image_hasalpha(in) && + !(saveable & VIPS_FOREIGN_SAVEABLE_ALPHA)) { + if (vips_flatten(in, &out, + "background", background, + NULL)) { g_object_unref(in); + return -1; + } + g_object_unref(in); + in = out; + } - in = out; + /* There might be more than one alpha ... drop any remaining excess + * bands. + */ + if (in->Coding == VIPS_CODING_NONE) { + int max_bands; + + // use a sanity-checked interpretation + max_bands = 0; + switch (vips_image_guess_interpretation(in)) { + case VIPS_INTERPRETATION_B_W: + case VIPS_INTERPRETATION_GREY16: + max_bands = 1; + break; + + case VIPS_INTERPRETATION_RGB: + case VIPS_INTERPRETATION_CMC: + case VIPS_INTERPRETATION_LCH: + case VIPS_INTERPRETATION_LABS: + case VIPS_INTERPRETATION_sRGB: + case VIPS_INTERPRETATION_YXY: + case VIPS_INTERPRETATION_XYZ: + case VIPS_INTERPRETATION_LAB: + case VIPS_INTERPRETATION_RGB16: + case VIPS_INTERPRETATION_scRGB: + case VIPS_INTERPRETATION_HSV: + max_bands = 3; + break; + + case VIPS_INTERPRETATION_CMYK: + max_bands = 4; + break; + + default: } - else { - VipsImage *out; - if (vips_rshift_const1(in, &out, 8, NULL)) { - g_object_unref(in); - return -1; - } - g_object_unref(in); + if (saveable & VIPS_FOREIGN_SAVEABLE_ALPHA) + max_bands += 1; - in = out; + if (saveable & VIPS_FOREIGN_SAVEABLE_ANY) + max_bands = in->Bands; - /* That could have produced an int image ... make sure - * we are now uchar. - */ - if (vips_cast(in, &out, VIPS_FORMAT_UCHAR, NULL)) { + if (max_bands > 0 && + in->Bands > max_bands) { + if (vips_extract_band(in, &out, 0, + "n", max_bands, + NULL)) { g_object_unref(in); return -1; } g_object_unref(in); - in = out; } } - /* Cast to the output format. + /* Convert to the format the saver likes, based on the original format. */ - { - VipsImage *out; - - if (vips_cast(in, &out, format[in->BandFmt], NULL)) { + if (in->Coding == VIPS_CODING_NONE && + format) { + if (vips_cast(in, &out, format[original_format], + "shift", TRUE, + NULL)) { g_object_unref(in); return -1; } g_object_unref(in); - in = out; } /* Does this class want a coded image? Search the coding table for the * first one. */ - if (coding[VIPS_CODING_NONE]) { - /* Already NONE, nothing to do. + if (coding[in->Coding]) { + /* Already there, nothing to do. */ } else if (coding[VIPS_CODING_LABQ]) { - VipsImage *out; - if (vips_Lab2LabQ(in, &out, NULL)) { g_object_unref(in); return -1; } g_object_unref(in); - in = out; } else if (coding[VIPS_CODING_RAD]) { - VipsImage *out; - if (vips_float2rad(in, &out, NULL)) { g_object_unref(in); return -1; } g_object_unref(in); - + in = out; + } + else if (coding[VIPS_CODING_NONE]) { + if (vips_image_decode(in, &out)) { + g_object_unref(in); + return -1; + } + g_object_unref(in); in = out; } diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index 91d0359c61..533ad8fa41 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -767,7 +767,8 @@ vips_foreign_save_heif_class_init(VipsForeignSaveHeifClass *class) object_class->description = _("save image in HEIF format"); object_class->build = vips_foreign_save_heif_build; - save_class->saveable = VIPS_SAVEABLE_RGBA_ONLY; + save_class->saveable = + VIPS_FOREIGN_SAVEABLE_RGB | VIPS_FOREIGN_SAVEABLE_ALPHA; save_class->format_table = vips_heif_bandfmt; VIPS_ARG_INT(class, "Q", 10, diff --git a/libvips/foreign/jp2ksave.c b/libvips/foreign/jp2ksave.c index e7eb432405..6f2229c2c2 100644 --- a/libvips/foreign/jp2ksave.c +++ b/libvips/foreign/jp2ksave.c @@ -965,7 +965,7 @@ vips_foreign_save_jp2k_class_init(VipsForeignSaveJp2kClass *class) foreign_class->suffs = vips__jp2k_suffs; - save_class->saveable = VIPS_SAVEABLE_ANY; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_ANY; VIPS_ARG_INT(class, "tile_width", 11, _("Tile width"), diff --git a/libvips/foreign/jpegsave.c b/libvips/foreign/jpegsave.c index 271744dcb9..ed331bec7f 100644 --- a/libvips/foreign/jpegsave.c +++ b/libvips/foreign/jpegsave.c @@ -157,7 +157,10 @@ vips_foreign_save_jpeg_class_init(VipsForeignSaveJpegClass *class) /* See also vips_foreign_save_tiff_build() when saving JPEG in TIFF. */ - save_class->saveable = VIPS_SAVEABLE_RGB_CMYK; + save_class->saveable = + VIPS_FOREIGN_SAVEABLE_MONO | + VIPS_FOREIGN_SAVEABLE_RGB | + VIPS_FOREIGN_SAVEABLE_CMYK; save_class->format_table = bandfmt_jpeg; VIPS_ARG_INT(class, "Q", 10, diff --git a/libvips/foreign/jxlsave.c b/libvips/foreign/jxlsave.c index 4339eaf9fd..e6e7ad94fa 100644 --- a/libvips/foreign/jxlsave.c +++ b/libvips/foreign/jxlsave.c @@ -546,7 +546,7 @@ vips_foreign_save_jxl_build(VipsObject *object) return -1; in = t[0]; - /* Mimics VIPS_SAVEABLE_RGBA. + /* Mimics VIPS_FOREIGN_SAVEABLE_RGB | VIPS_FOREIGN_SAVEABLE_ALPHA. * FIXME: add support encoding images with > 4 bands. */ if (in->Bands > 4) { @@ -805,7 +805,7 @@ vips_foreign_save_jxl_class_init(VipsForeignSaveJxlClass *class) foreign_class->suffs = vips__jxl_suffs; - save_class->saveable = VIPS_SAVEABLE_ANY; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_ANY; save_class->format_table = bandfmt_jxl; VIPS_ARG_INT(class, "tier", 10, diff --git a/libvips/foreign/matrixsave.c b/libvips/foreign/matrixsave.c index 3e3145baf9..2907898e3c 100644 --- a/libvips/foreign/matrixsave.c +++ b/libvips/foreign/matrixsave.c @@ -177,7 +177,7 @@ vips_foreign_save_matrix_class_init(VipsForeignSaveMatrixClass *class) foreign_class->suffs = vips_foreign_save_matrix_suffs; - save_class->saveable = VIPS_SAVEABLE_MONO; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_MONO; save_class->format_table = bandfmt_matrix; } diff --git a/libvips/foreign/niftisave.c b/libvips/foreign/niftisave.c index f92ca6b053..68643e8238 100644 --- a/libvips/foreign/niftisave.c +++ b/libvips/foreign/niftisave.c @@ -434,7 +434,7 @@ vips_foreign_save_nifti_class_init(VipsForeignSaveNiftiClass *class) foreign_class->suffs = vips_foreign_nifti_suffs; - save_class->saveable = VIPS_SAVEABLE_ANY; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_ANY; save_class->format_table = vips_nifti_bandfmt; VIPS_ARG_STRING(class, "filename", 1, diff --git a/libvips/foreign/pngsave.c b/libvips/foreign/pngsave.c index dc96ad9df1..b9cab4e86c 100644 --- a/libvips/foreign/pngsave.c +++ b/libvips/foreign/pngsave.c @@ -204,7 +204,10 @@ vips_foreign_save_png_class_init(VipsForeignSavePngClass *class) foreign_class->suffs = vips__png_suffs; - save_class->saveable = VIPS_SAVEABLE_RGBA; + save_class->saveable = + VIPS_FOREIGN_SAVEABLE_MONO | + VIPS_FOREIGN_SAVEABLE_RGB | + VIPS_FOREIGN_SAVEABLE_ALPHA; save_class->format_table = bandfmt_png; VIPS_ARG_INT(class, "compression", 6, diff --git a/libvips/foreign/ppmsave.c b/libvips/foreign/ppmsave.c index 9a4779db98..5ea885d418 100644 --- a/libvips/foreign/ppmsave.c +++ b/libvips/foreign/ppmsave.c @@ -499,7 +499,7 @@ vips_foreign_save_ppm_class_init(VipsForeignSavePpmClass *class) object_class->description = _("save to ppm"); object_class->build = vips_foreign_save_ppm_build; - save_class->saveable = VIPS_SAVEABLE_ANY; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_ANY; save_class->format_table = bandfmt_ppm; VIPS_ARG_ENUM(class, "format", 2, diff --git a/libvips/foreign/radsave.c b/libvips/foreign/radsave.c index 4ad6074843..0ed3ac6083 100644 --- a/libvips/foreign/radsave.c +++ b/libvips/foreign/radsave.c @@ -93,7 +93,8 @@ vips_foreign_save_rad_class_init(VipsForeignSaveRadClass *class) foreign_class->suffs = vips__rad_suffs; - save_class->saveable = VIPS_SAVEABLE_RGB; + save_class->saveable = + VIPS_FOREIGN_SAVEABLE_MONO | VIPS_FOREIGN_SAVEABLE_RGB; save_class->format_table = vips_foreign_save_rad_format_table; save_class->coding[VIPS_CODING_NONE] = FALSE; save_class->coding[VIPS_CODING_RAD] = TRUE; @@ -123,7 +124,8 @@ vips_foreign_save_rad_file_build(VipsObject *object) VipsTarget *target; - if (VIPS_OBJECT_CLASS(vips_foreign_save_rad_file_parent_class)->build(object)) + if (VIPS_OBJECT_CLASS(vips_foreign_save_rad_file_parent_class)-> + build(object)) return -1; if (!(target = vips_target_new_to_file(file->filename))) diff --git a/libvips/foreign/rawsave.c b/libvips/foreign/rawsave.c index b137e5bebd..18abf45cfb 100644 --- a/libvips/foreign/rawsave.c +++ b/libvips/foreign/rawsave.c @@ -138,7 +138,7 @@ vips_foreign_save_raw_class_init(VipsForeignSaveRawClass *class) object_class->description = _("save image to raw"); object_class->build = vips_foreign_save_raw_build; - save_class->saveable = VIPS_SAVEABLE_ANY; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_ANY; } static void diff --git a/libvips/foreign/spngsave.c b/libvips/foreign/spngsave.c index de2884d4e6..befc79c37a 100644 --- a/libvips/foreign/spngsave.c +++ b/libvips/foreign/spngsave.c @@ -682,7 +682,10 @@ vips_foreign_save_spng_class_init(VipsForeignSaveSpngClass *class) foreign_class->suffs = vips__png_suffs; - save_class->saveable = VIPS_SAVEABLE_RGBA; + save_class->saveable = + VIPS_FOREIGN_SAVEABLE_MONO | + VIPS_FOREIGN_SAVEABLE_RGB | + VIPS_FOREIGN_SAVEABLE_ALPHA; save_class->format_table = bandfmt_spng; VIPS_ARG_INT(class, "compression", 6, diff --git a/libvips/foreign/tiffsave.c b/libvips/foreign/tiffsave.c index ea979cde9d..89ea48b538 100644 --- a/libvips/foreign/tiffsave.c +++ b/libvips/foreign/tiffsave.c @@ -163,7 +163,10 @@ vips_foreign_save_tiff_build(VipsObject *object) /* See also vips_foreign_save_jpeg_class_init(). */ if (vips__foreign_convert_saveable(ready, &x, - VIPS_SAVEABLE_RGB_CMYK, bandfmt_jpeg, class->coding, + VIPS_FOREIGN_SAVEABLE_MONO | + VIPS_FOREIGN_SAVEABLE_RGB | + VIPS_FOREIGN_SAVEABLE_CMYK, + bandfmt_jpeg, class->coding, save->background)) { VIPS_UNREF(ready); return -1; @@ -250,7 +253,7 @@ vips_foreign_save_tiff_class_init(VipsForeignSaveTiffClass *class) foreign_class->suffs = vips__foreign_tiff_suffs; - save_class->saveable = VIPS_SAVEABLE_ANY; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_ANY; save_class->coding[VIPS_CODING_LABQ] = TRUE; VIPS_ARG_ENUM(class, "compression", 6, diff --git a/libvips/foreign/vips2magick.c b/libvips/foreign/vips2magick.c index 7cd150899f..bd14093f3c 100644 --- a/libvips/foreign/vips2magick.c +++ b/libvips/foreign/vips2magick.c @@ -475,7 +475,7 @@ vips_foreign_save_magick_class_init(VipsForeignSaveMagickClass *class) foreign_class->priority = -100; foreign_class->suffs = vips__save_magick_suffs; - save_class->saveable = VIPS_SAVEABLE_ANY; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_ANY; save_class->format_table = bandfmt_magick; VIPS_ARG_STRING(class, "format", 2, diff --git a/libvips/foreign/vipssave.c b/libvips/foreign/vipssave.c index b3033955df..0c4cc5bc6b 100644 --- a/libvips/foreign/vipssave.c +++ b/libvips/foreign/vipssave.c @@ -143,7 +143,7 @@ vips_foreign_save_vips_class_init(VipsForeignSaveVipsClass *class) foreign_class->suffs = vips__suffs; - save_class->saveable = VIPS_SAVEABLE_ANY; + save_class->saveable = VIPS_FOREIGN_SAVEABLE_ANY; for (i = 0; i < VIPS_CODING_LAST; i++) save_class->coding[i] = TRUE; } diff --git a/libvips/foreign/webpsave.c b/libvips/foreign/webpsave.c index 67e07cf4fd..a7667bec8e 100644 --- a/libvips/foreign/webpsave.c +++ b/libvips/foreign/webpsave.c @@ -821,7 +821,8 @@ vips_foreign_save_webp_class_init(VipsForeignSaveWebpClass *class) foreign_class->suffs = vips__save_webp_suffs; - save_class->saveable = VIPS_SAVEABLE_RGBA_ONLY; + save_class->saveable = + VIPS_FOREIGN_SAVEABLE_RGB | VIPS_FOREIGN_SAVEABLE_ALPHA; save_class->format_table = bandfmt_webp; VIPS_ARG_INT(class, "Q", 10, diff --git a/libvips/include/vips/almostdeprecated.h b/libvips/include/vips/almostdeprecated.h index 7fbfb09ab9..d62de53fa2 100644 --- a/libvips/include/vips/almostdeprecated.h +++ b/libvips/include/vips/almostdeprecated.h @@ -470,6 +470,24 @@ VIPS_DEPRECATED_FOR(g_snprintf) int vips_snprintf(char *str, size_t size, const char *format, ...) G_GNUC_PRINTF(3, 4); +/* This has been deprecated and replaced by VipsForeignSaveable. + */ +typedef enum /*< skip >*/ { + VIPS_SAVEABLE_MONO = + VIPS_FOREIGN_SAVEABLE_MONO, + VIPS_SAVEABLE_RGB = + VIPS_FOREIGN_SAVEABLE_MONO | VIPS_FOREIGN_SAVEABLE_RGB, + VIPS_SAVEABLE_RGBA = + VIPS_SAVEABLE_RGB | VIPS_FOREIGN_SAVEABLE_ALPHA, + VIPS_SAVEABLE_RGBA_ONLY = + VIPS_FOREIGN_SAVEABLE_RGB | VIPS_FOREIGN_SAVEABLE_ALPHA, + VIPS_SAVEABLE_RGB_CMYK = + VIPS_SAVEABLE_RGB | VIPS_FOREIGN_SAVEABLE_CMYK, + VIPS_SAVEABLE_ANY = + VIPS_FOREIGN_SAVEABLE_ANY, + VIPS_SAVEABLE_LAST = 99, +} VipsSaveable; + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/enumtypes.c.in b/libvips/include/vips/enumtypes.c.in index f57755dd57..77d0eed944 100644 --- a/libvips/include/vips/enumtypes.c.in +++ b/libvips/include/vips/enumtypes.c.in @@ -5,6 +5,14 @@ #include #endif /*HAVE_CONFIG_H*/ #include + +/* Alias for backwards compatibility. + */ +GType +vips_saveable_get_type(void) +{ + return vips_foreign_saveable_get_type(); +} /*** END file-header ***/ /*** BEGIN file-production ***/ diff --git a/libvips/include/vips/enumtypes.h.in b/libvips/include/vips/enumtypes.h.in index 83bf63c095..708a041abc 100644 --- a/libvips/include/vips/enumtypes.h.in +++ b/libvips/include/vips/enumtypes.h.in @@ -4,6 +4,10 @@ G_BEGIN_DECLS +VIPS_API +GType vips_saveable_get_type(void) G_GNUC_CONST; +#define VIPS_TYPE_SAVEABLE (vips_saveable_get_type()) + /*** END file-header ***/ /*** BEGIN file-production ***/ diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index 8242861cdc..c09093874e 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -308,25 +308,25 @@ void vips_foreign_load_invalidate(VipsImage *image); VIPS_TYPE_FOREIGN_SAVE, VipsForeignSaveClass)) /** - * VipsSaveable: - * @VIPS_SAVEABLE_MONO: 1 band (eg. CSV) - * @VIPS_SAVEABLE_RGB: 1 or 3 bands (eg. PPM) - * @VIPS_SAVEABLE_RGBA: 1, 2, 3 or 4 bands (eg. PNG) - * @VIPS_SAVEABLE_RGBA_ONLY: 3 or 4 bands (eg. WEBP) - * @VIPS_SAVEABLE_RGB_CMYK: 1, 3 or 4 bands (eg. JPEG) - * @VIPS_SAVEABLE_ANY: any number of bands (eg. TIFF) + * VipsForeignSaveable: + * @VIPS_FOREIGN_SAVEABLE_MONO: 1 band + * @VIPS_FOREIGN_SAVEABLE_RGB: 3 bands + * @VIPS_FOREIGN_SAVEABLE_CMYK: 4 bands + * @VIPS_FOREIGN_SAVEABLE_ALPHA: an extra band + * @VIPS_FOREIGN_SAVEABLE_ANY: saver supports everything (eg. TIFF) + * + * The set of image types supported by a saver. * * See also: #VipsForeignSave. */ -typedef enum { - VIPS_SAVEABLE_MONO, - VIPS_SAVEABLE_RGB, - VIPS_SAVEABLE_RGBA, - VIPS_SAVEABLE_RGBA_ONLY, - VIPS_SAVEABLE_RGB_CMYK, - VIPS_SAVEABLE_ANY, - VIPS_SAVEABLE_LAST -} VipsSaveable; +typedef enum /*< flags >*/ { + VIPS_FOREIGN_SAVEABLE_MONO = 1, + VIPS_FOREIGN_SAVEABLE_RGB = 2, + VIPS_FOREIGN_SAVEABLE_CMYK = 4, + VIPS_FOREIGN_SAVEABLE_ALPHA = 8, + VIPS_FOREIGN_SAVEABLE_ANY = 16, + VIPS_FOREIGN_SAVEABLE_ALL = 31, +} VipsForeignSaveable; /** * VipsForeignKeep: @@ -401,11 +401,11 @@ typedef struct _VipsForeignSaveClass { /* How this format treats bands. * - * @saveable describes the bands that your saver can handle. For + * @saveable describes the image types that your saver can handle. For * example, PPM images can have 1 or 3 bands (mono or RGB), so it - * uses #VIPS_SAVEABLE_RGB. + * uses VIPS_SAVEABLE_FLAGS_MONO | VIPS_SAVEABLE_FLAGS_RGB. */ - VipsSaveable saveable; + VipsForeignSaveable saveable; /* How this format treats band formats. * diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 6b1ec3ed93..f27caa79f1 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -345,7 +345,7 @@ typedef struct _VipsImagePixels { } VipsImagePixels; int vips__foreign_convert_saveable(VipsImage *in, VipsImage **ready, - VipsSaveable saveable, VipsBandFormat *format, VipsCoding *coding, + VipsForeignSaveable saveable, VipsBandFormat *format, VipsCoding *coding, VipsArrayDouble *background); int vips_foreign_load(const char *filename, VipsImage **out, ...) diff --git a/libvips/iofuncs/buf.c b/libvips/iofuncs/buf.c index ab30ea0797..b01e022580 100644 --- a/libvips/iofuncs/buf.c +++ b/libvips/iofuncs/buf.c @@ -361,8 +361,7 @@ vips_buf_change(VipsBuf *buf, const char *old, const char *new) /* Move tail of buffer to make right-size space for new. */ - memmove(buf->base + i + nlen, buf->base + i + olen, - buf->i - i - olen); + memmove(buf->base + i + nlen, buf->base + i + olen, buf->i - i - olen); /* Copy new in. */ @@ -541,8 +540,7 @@ vips_buf_appendgv(VipsBuf *buf, GValue *value) } break; case G_TYPE_INT: - result = vips_buf_appendf(buf, - "%d", g_value_get_int(value)); + result = vips_buf_appendf(buf, "%d", g_value_get_int(value)); handled = TRUE; break; @@ -553,8 +551,7 @@ vips_buf_appendgv(VipsBuf *buf, GValue *value) break; case G_TYPE_DOUBLE: - result = vips_buf_appendf(buf, - "%g", g_value_get_double(value)); + result = vips_buf_appendf(buf, "%g", g_value_get_double(value)); handled = TRUE; break; @@ -635,8 +632,7 @@ vips_buf_appendgv(VipsBuf *buf, GValue *value) arr = vips_value_get_array_image(value, &n); for (i = 0; i < n; i++) { - vips_object_summary(VIPS_OBJECT(arr[i]), - buf); + vips_object_summary(VIPS_OBJECT(arr[i]), buf); result = vips_buf_appends(buf, " "); } handled = TRUE; diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 0ffae26993..6e090b5de5 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -450,12 +450,6 @@ vips_image_guess_format(const VipsImage *image) format = VIPS_FORMAT_UCHAR; switch (image->Type) { - case VIPS_INTERPRETATION_B_W: - case VIPS_INTERPRETATION_HISTOGRAM: - case VIPS_INTERPRETATION_MULTIBAND: - format = image->BandFmt; - break; - case VIPS_INTERPRETATION_FOURIER: if (image->BandFmt == VIPS_FORMAT_DOUBLE || image->BandFmt == VIPS_FORMAT_DPCOMPLEX) @@ -506,8 +500,12 @@ vips_image_guess_format(const VipsImage *image) format = VIPS_FORMAT_FLOAT; break; + case VIPS_INTERPRETATION_B_W: + case VIPS_INTERPRETATION_HISTOGRAM: + case VIPS_INTERPRETATION_MULTIBAND: default: - format = VIPS_FORMAT_NOTSET; + // for eg. INTERPRETATION_ERROR, stick with the format we have + format = image->BandFmt; break; } diff --git a/test/test-suite/test_foreign.py b/test/test-suite/test_foreign.py index bfa85db321..a1c65277f6 100644 --- a/test/test-suite/test_foreign.py +++ b/test/test-suite/test_foreign.py @@ -27,6 +27,14 @@ def setup_class(cls): im = pyvips.Image.new_from_file(GIF_FILE) cls.onebit = im[1] > 128 + all = [cls.mono, cls.colour, cls.cmyk] + # and alpha variants of all of them + alpha = [x.bandjoin(255) for x in all] + # and with a second alpha + alpha2 = [x.bandjoin(255) for x in alpha] + + cls.all = all + alpha + alpha2 + @classmethod def teardown_class(cls): shutil.rmtree(cls.tempdir, ignore_errors=True) @@ -35,6 +43,7 @@ def teardown_class(cls): cls.mono = None cls.cmyk = None cls.onebit = None + cls.all = None # we have test files for formats which have a clear standard def file_loader(self, loader, test_file, validate): @@ -148,6 +157,10 @@ def jpeg_valid(im): self.save_load_buffer("jpegsave_buffer", "jpegload_buffer", self.colour, 80) + for image in self.all: + target = pyvips.Target.new_to_memory() + image.jpegsave_target(target) + # see if we have exif parsing: our test image has this field x = pyvips.Image.new_from_file(JPEG_FILE) if x.get_typeof("exif-ifd0-Orientation") != 0: @@ -422,6 +435,10 @@ def png_valid(im): self.save_load_file(".png", "[interlace]", self.colour) self.save_load_file(".png", "[interlace]", self.mono) + for image in self.all: + target = pyvips.Target.new_to_memory() + image.pngsave_target(target) + def png_indexed_valid(im): a = im(10, 10) assert_almost_equal_objects(a, [148.0, 131.0, 109.0]) @@ -432,7 +449,8 @@ def png_indexed_valid(im): assert im.get("palette") == 1 self.file_loader("pngload", PNG_INDEXED_FILE, png_indexed_valid) - self.buffer_loader("pngload_buffer", PNG_INDEXED_FILE, png_indexed_valid) + self.buffer_loader("pngload_buffer", + PNG_INDEXED_FILE, png_indexed_valid) # size of a regular mono PNG len_mono = len(self.mono.write_to_buffer(".png")) @@ -482,7 +500,8 @@ def png_indexed_valid(im): "exif-ifd0-ImageDescription", "test description") im2 = pyvips.Image.new_from_buffer( im1.write_to_buffer(".png"), "") - assert im2.get("exif-ifd0-ImageDescription").startswith("test description") + assert im2.get("exif-ifd0-ImageDescription") \ + .startswith("test description") @skip_if_no("tiffload") def test_tiff(self): @@ -497,6 +516,10 @@ def tiff_valid(im): self.file_loader("tiffload", TIF_FILE, tiff_valid) self.buffer_loader("tiffload_buffer", TIF_FILE, tiff_valid) + for image in self.all: + target = pyvips.Target.new_to_memory() + image.tiffsave_target(target) + def tiff1_valid(im): a = im(127, 0) assert_almost_equal_objects(a, [0.0]) @@ -1012,6 +1035,7 @@ def nifti_valid(im): @skip_if_no("openslideload") def test_openslideload(self): + def openslide_valid(im): a = im(10, 10) assert_almost_equal_objects(a, [244, 250, 243, 255]) @@ -1212,6 +1236,10 @@ def test_csv(self): def test_matrix(self): self.save_load("%s.mat", self.mono) + for image in self.all: + target = pyvips.Target.new_to_memory() + image.matrixsave_target(target) + @skip_if_no("ppmload") def test_ppm(self): self.save_load("%s.ppm", self.colour) From b9247d9b9fb118ffcfea7efb313d880055fd4eb9 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 8 May 2025 12:31:49 +0200 Subject: [PATCH 159/174] Ignore VipsSaveable type when generating introspection data (#4501) --- libvips/include/vips/enumtypes.c.in | 16 ++++++++-------- libvips/include/vips/enumtypes.h.in | 10 ++++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/libvips/include/vips/enumtypes.c.in b/libvips/include/vips/enumtypes.c.in index 77d0eed944..8e7f1971ec 100644 --- a/libvips/include/vips/enumtypes.c.in +++ b/libvips/include/vips/enumtypes.c.in @@ -5,14 +5,6 @@ #include #endif /*HAVE_CONFIG_H*/ #include - -/* Alias for backwards compatibility. - */ -GType -vips_saveable_get_type(void) -{ - return vips_foreign_saveable_get_type(); -} /*** END file-header ***/ /*** BEGIN file-production ***/ @@ -46,3 +38,11 @@ GType } /*** END value-tail ***/ +/*** BEGIN file-tail ***/ +/* Deprecated enumerations */ +GType +vips_saveable_get_type(void) +{ + return vips_foreign_saveable_get_type(); +} +/*** END file-tail ***/ diff --git a/libvips/include/vips/enumtypes.h.in b/libvips/include/vips/enumtypes.h.in index 708a041abc..e4acbfaeac 100644 --- a/libvips/include/vips/enumtypes.h.in +++ b/libvips/include/vips/enumtypes.h.in @@ -4,10 +4,6 @@ G_BEGIN_DECLS -VIPS_API -GType vips_saveable_get_type(void) G_GNUC_CONST; -#define VIPS_TYPE_SAVEABLE (vips_saveable_get_type()) - /*** END file-header ***/ /*** BEGIN file-production ***/ @@ -21,6 +17,12 @@ GType @enum_name@_get_type(void) G_GNUC_CONST; /*** END value-header ***/ /*** BEGIN file-tail ***/ +/* Deprecated enumerations */ +#ifndef __GI_SCANNER__ +VIPS_API +GType vips_saveable_get_type(void) G_GNUC_CONST; +#define VIPS_TYPE_SAVEABLE (vips_saveable_get_type()) +#endif /*__GI_SCANNER__*/ G_END_DECLS #endif /*VIPS_ENUM_TYPES_H*/ From a61cb56bd885bcb52e323048e6c44f7230caa5e9 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 8 May 2025 12:32:18 +0200 Subject: [PATCH 160/174] doc: avoid gi-docgen linking syntax for non-doc comments (#4500) --- doc/extending.md | 4 ++-- doc/how-it-works.md | 2 +- doc/using-from-c.md | 2 +- libvips/foreign/heifsave.c | 2 +- libvips/foreign/jpeg2vips.c | 20 ++++++++++---------- libvips/iofuncs/buf.c | 2 +- libvips/iofuncs/cache.c | 4 ++-- libvips/iofuncs/image.c | 6 +++--- libvips/iofuncs/init.c | 4 ++-- libvips/iofuncs/region.c | 4 ++-- libvips/iofuncs/type.c | 6 +++--- libvips/iofuncs/util.c | 2 +- libvips/iofuncs/vips.c | 2 +- 13 files changed, 30 insertions(+), 30 deletions(-) diff --git a/doc/extending.md b/doc/extending.md index e6023afcfe..aeddd45148 100644 --- a/doc/extending.md +++ b/doc/extending.md @@ -149,7 +149,7 @@ negative_build(VipsObject *object) vips_check_format(class->nickname, negative->in, VIPS_FORMAT_UCHAR)) return -1; - g_object_set(object, "out", [ctor@Image.new], NULL); + g_object_set(object, "out", vips_image_new(), NULL); if (vips_image_pipelinev(negative->out, VIPS_DEMAND_STYLE_THINSTRIP, negative->in, NULL)) @@ -206,7 +206,7 @@ negative_generate(VipsRegion *out_region, */ VipsRect *r = &out_region->valid; - /* The sequence value ... the thing returned by [func@start_one]. + /* The sequence value ... the thing returned by vips_start_one(). */ VipsRegion *ir = (VipsRegion *) vseq; diff --git a/doc/how-it-works.md b/doc/how-it-works.md index 7cda89e9e0..757e0cb7bc 100644 --- a/doc/how-it-works.md +++ b/doc/how-it-works.md @@ -42,7 +42,7 @@ if (vips_region_prepare(region, &r)) // add VIPS_REGION_LSKIP() to move down a line VipsPel *pixel = VIPS_REGION_ADDR(region, x, y); -// you can call [method@Region.prepare] many times +// you can call vips_region_prepare() many times // everything in libvips is a GObject ... when you're done, // just free with diff --git a/doc/using-from-c.md b/doc/using-from-c.md index 935375bdde..f1cc106154 100644 --- a/doc/using-from-c.md +++ b/doc/using-from-c.md @@ -264,7 +264,7 @@ main(int argc, char **argv) NULL))) vips_error_exit(NULL); - context = VIPS_OBJECT([ctor@Image.new]); + context = VIPS_OBJECT(vips_image_new()); if (crop_animation(context, image, &x, 10, 10, 500, 500)) { g_object_unref(image); g_object_unref(context); diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index 533ad8fa41..4c20aad203 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -320,7 +320,7 @@ vips_foreign_save_heif_write_page(VipsForeignSaveHeif *heif, int page) #ifdef DEBUG { - GTimer *timer = [func@GLib.timer_new]; + GTimer *timer = g_timer_new(); printf("calling heif_context_encode_image() ...\n"); #endif /*DEBUG*/ diff --git a/libvips/foreign/jpeg2vips.c b/libvips/foreign/jpeg2vips.c index b1db668056..fa5568d335 100644 --- a/libvips/foreign/jpeg2vips.c +++ b/libvips/foreign/jpeg2vips.c @@ -474,8 +474,8 @@ readjpeg_new(VipsSource *source, VipsImage *out, jpeg->unlimited = unlimited; jpeg->cinfo.client_data = jpeg; - /* jpe[func@GLib.create_decompress] can fail on some sanity checks. Don't - * readjpe[func@GLib.free] since we don't want to jpe[func@GLib.destroy_decompress]. + /* jpeg_create_decompress() can fail on some sanity checks. Don't + * readjpeg_free() since we don't want to jpeg_destroy_decompress(). */ if (setjmp(jpeg->eman.jmp)) return NULL; @@ -879,7 +879,7 @@ read_jpeg_generate(VipsRegion *out_region, g_assert(r->height == VIPS_MIN(8, out_region->im->Ysize - r->top)); /* And check that the y position is correct. It should be, since we are - * inside a [method@Image.sequential]. + * inside a vips_sequential(). */ if (r->top != cinfo->output_scanline) { VIPS_GATE_STOP("read_jpeg_generate: work"); @@ -889,14 +889,14 @@ read_jpeg_generate(VipsRegion *out_region, return -1; } - /* Here for longjmp() from [func@_new_error_exit] during - * jpe[func@GLib.read_scanlines]. + /* Here for longjmp() from vips__new_error_exit() during + * jpeg_read_scanlines(). */ if (setjmp(jpeg->eman.jmp)) { VIPS_GATE_STOP("read_jpeg_generate: work"); #ifdef DEBUG - printf("read_jpe[func@GLib.generate: longjmp] exit\n"); + printf("read_jpeg_generate() exit\n"); #endif /*DEBUG*/ return -1; @@ -945,8 +945,8 @@ read_jpeg_image(ReadJpeg *jpeg, VipsImage *out) VipsImage *im; - /* Here for longjmp() from [func@_new_error_exit] during - * jpe[func@GLib.read_header] or jpe[func@GLib.start_decompress]. + /* Here for longjmp() from vips__new_error_exit() during + * jpeg_read_header() or jpeg_start_decompress(). */ if (setjmp(jpeg->eman.jmp)) return -1; @@ -1058,8 +1058,8 @@ vips__jpeg_read_source(VipsSource *source, VipsImage *out, autorotate, unlimited))) return -1; - /* Here for longjmp() from [func@_new_error_exit] during - * cinfo->mem->alloc_small() or jpe[func@GLib.read_header]. + /* Here for longjmp() from vips__new_error_exit() during + * cinfo->mem->alloc_small() or jpeg_read_header(). */ if (setjmp(jpeg->eman.jmp)) return -1; diff --git a/libvips/iofuncs/buf.c b/libvips/iofuncs/buf.c index b01e022580..70d0a81d6b 100644 --- a/libvips/iofuncs/buf.c +++ b/libvips/iofuncs/buf.c @@ -414,7 +414,7 @@ vips_buf_vappendf(VipsBuf *buf, const char *fmt, va_list ap) // -3 to leave space for "..." // not -4, since the terminating \0 will already be on the string written - // by [func@GLib.vsnprintf] + // by g_vsnprintf() avail = buf->mx - buf->i - 3; p = buf->base + buf->i; (void) g_vsnprintf(p, avail, fmt, ap); diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index 4df328f91f..c2ce36ec5a 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -793,7 +793,7 @@ vips_cache_drop_all(void) vips_cache_print_nolock(); /* We can't modify the hash in the callback from - * [func@GLib.hash_table_foreach] and friends. Repeatedly drop the + * g_hash_table_foreach() and friends. Repeatedly drop the * first item instead. */ while ((operation = vips_cache_get_first())) @@ -975,7 +975,7 @@ vips_cache_operation_buildp(VipsOperation **operation) VIPS_UNREF(operation_before); - /* Retrieve the flags again, as [func@Foreign.load_build] may + /* Retrieve the flags again, as vips_foreign_load_build() may * set load->nocache. */ flags = vips_operation_get_flags(*operation); diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index a0d4b1cff8..c5cc5fbe33 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -833,7 +833,7 @@ vips_image_build(VipsObject *object) switch (mode[0]) { case 'v': /* Used by 'r' for native open of vips, see below. Also by - * [method@Image.rewind_output]. + * vips_image_rewind_output(). */ if (vips_image_open_input(image)) return -1; @@ -2931,7 +2931,7 @@ vips_image_write_to_memory(VipsImage *in, size_t *size_out) int vips_image_decode(VipsImage *in, VipsImage **out) { - /* Keep in sync with [func@_vector_to_ink]. + /* Keep in sync with vips__vector_to_ink(). */ if (in->Coding == VIPS_CODING_LABQ) { if (vips_LabQ2Lab(in, out, NULL)) @@ -3588,7 +3588,7 @@ vips__image_wio_output(VipsImage *image) int vips_image_inplace(VipsImage *image) { - /* Do an [method@Image.wio_input]. This will rewind, generate, etc. + /* Do an vips_image_wio_input(). This will rewind, generate, etc. */ if (vips_image_wio_input(image)) return -1; diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 78432515d5..5908917479 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -644,7 +644,7 @@ vips_init(const char *argv0) /* If VIPS_WARNING is defined, suppress all warning messages from vips. * - * Libraries should not call [func@GLib.log_set_handler], it is + * Libraries should not call g_log_set_handler(), it is * supposed to be for the application layer, but this can be awkward to * set up if you are using libvips from something like Ruby. Allow this * env var hack as a workaround. @@ -675,7 +675,7 @@ void vips_check_init(void) { /* Pass in a nonsense name for argv0 ... this init path is only here - * for old programs which are missing an [func@init] call. We need + * for old programs which are missing an vips_init() call. We need * i18n set up before we can translate. */ if (vips_init("vips")) diff --git a/libvips/iofuncs/region.c b/libvips/iofuncs/region.c index 7e169f6f05..dc41c099b8 100644 --- a/libvips/iofuncs/region.c +++ b/libvips/iofuncs/region.c @@ -1897,7 +1897,7 @@ vips_region_prepare_to(VipsRegion *reg, * was). * * We need this extra thing here because, unlike - * [method@Region.prepare], we don't [method@Region.buffer] dest before + * vips_region_prepare(), we don't vips_region_buffer() dest before * writing it. */ dest->invalid = FALSE; @@ -1905,7 +1905,7 @@ vips_region_prepare_to(VipsRegion *reg, return 0; } -/* Don't use this, use [func@reorder_prepare_many] instead. +/* Don't use this, use vips_reorder_prepare_many() instead. */ int vips_region_prepare_many(VipsRegion **reg, const VipsRect *r) diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index 155cf837df..cf03a7a4fd 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -1478,7 +1478,7 @@ transform_g_string_array_image(const GValue *src_value, GValue *dest_value) str = g_value_dup_string(src_value); /* We can't get access here, just assume nothing. See the special case - * in [method@Object.new_from_string] for how we usually get this right. + * in vips_object_new_from_string() for how we usually get this right. */ if (!(array_image = vips_array_image_new_from_string(str, 0))) { /* Set the dest to length zero to indicate error. @@ -1765,7 +1765,7 @@ vips_value_get_array(const GValue *value, VipsArea *area; /* Can't check value type, because we may get called from - * [func@*_get_type]. + * vips_*_get_type(). */ if (!(area = g_value_get_boxed(value))) @@ -1945,7 +1945,7 @@ vips_value_set_array_object(GValue *value, int n) vips_area_unref(area); } -/* Make the types we need for basic functioning. Called from [func@init]. +/* Make the types we need for basic functioning. Called from vips_init(). */ void vips__meta_init_types(void) diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index 42804a94b0..a51792817f 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -339,7 +339,7 @@ vips_iscasepostfix(const char *a, const char *b) } /* Test for string a starts string b. a is a known-good string, b may be - * random data. Use [func@GLib.str_has_prefix] when both strings are non-NULL and + * random data. Use g_str_has_prefix() when both strings are non-NULL and * NULL-terminated. */ gboolean diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index 9e412097a6..879006aa9c 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -932,7 +932,7 @@ vips__xml_properties_meta(VipsImage *image, } /* Make the xml we write to vips-properties in dzsave, or to TIFF. A simple - * dump of all vips metadata. Free with [func@GLib.free]. + * dump of all vips metadata. Free with g_free(). */ char * vips__xml_properties(VipsImage *image) From d0c4d1304fca19b4866d4845169bb1dde131cbdb Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 8 May 2025 12:32:37 +0200 Subject: [PATCH 161/174] doc: port remainder (#4499) * doc: port remainder to gi-docgen linking syntax * doc: port remainder to Markdown --- doc/rename.sed | 11 ++ libvips/arithmetic/abs.c | 2 +- libvips/arithmetic/add.c | 2 +- libvips/arithmetic/avg.c | 2 +- libvips/arithmetic/boolean.c | 36 ++-- libvips/arithmetic/clamp.c | 6 +- libvips/arithmetic/complex.c | 20 +-- libvips/arithmetic/deviate.c | 2 +- libvips/arithmetic/divide.c | 2 +- libvips/arithmetic/find_trim.c | 6 +- libvips/arithmetic/getpoint.c | 2 +- libvips/arithmetic/hist_find.c | 2 +- libvips/arithmetic/hist_find_indexed.c | 4 +- libvips/arithmetic/hist_find_ndim.c | 2 +- libvips/arithmetic/hough_circle.c | 2 +- libvips/arithmetic/hough_line.c | 2 +- libvips/arithmetic/invert.c | 2 +- libvips/arithmetic/linear.c | 4 +- libvips/arithmetic/math.c | 34 ++-- libvips/arithmetic/math2.c | 24 +-- libvips/arithmetic/max.c | 2 +- libvips/arithmetic/maxpair.c | 2 +- libvips/arithmetic/measure.c | 2 +- libvips/arithmetic/min.c | 2 +- libvips/arithmetic/minpair.c | 2 +- libvips/arithmetic/multiply.c | 2 +- libvips/arithmetic/profile.c | 2 +- libvips/arithmetic/project.c | 2 +- libvips/arithmetic/relational.c | 42 ++--- libvips/arithmetic/remainder.c | 6 +- libvips/arithmetic/round.c | 8 +- libvips/arithmetic/sign.c | 2 +- libvips/arithmetic/stats.c | 2 +- libvips/arithmetic/subtract.c | 2 +- libvips/arithmetic/sum.c | 2 +- libvips/colour/CMYK2XYZ.c | 2 +- libvips/colour/HSV2sRGB.c | 2 +- libvips/colour/LCh2Lab.c | 2 +- libvips/colour/LCh2UCS.c | 2 +- libvips/colour/Lab2LCh.c | 2 +- libvips/colour/Lab2LabQ.c | 2 +- libvips/colour/Lab2LabS.c | 2 +- libvips/colour/Lab2XYZ.c | 2 +- libvips/colour/LabQ2Lab.c | 2 +- libvips/colour/LabQ2LabS.c | 2 +- libvips/colour/LabQ2sRGB.c | 2 +- libvips/colour/LabS2Lab.c | 2 +- libvips/colour/LabS2LabQ.c | 2 +- libvips/colour/UCS2LCh.c | 2 +- libvips/colour/XYZ2CMYK.c | 2 +- libvips/colour/XYZ2Lab.c | 2 +- libvips/colour/XYZ2Yxy.c | 2 +- libvips/colour/XYZ2scRGB.c | 2 +- libvips/colour/Yxy2XYZ.c | 2 +- libvips/colour/colourspace.c | 4 +- libvips/colour/dE00.c | 2 +- libvips/colour/dE76.c | 2 +- libvips/colour/dECMC.c | 2 +- libvips/colour/float2rad.c | 2 +- libvips/colour/icc_transform.c | 40 ++--- libvips/colour/profile_load.c | 4 +- libvips/colour/rad2float.c | 2 +- libvips/colour/sRGB2HSV.c | 2 +- libvips/colour/sRGB2scRGB.c | 2 +- libvips/colour/scRGB2BW.c | 2 +- libvips/colour/scRGB2XYZ.c | 2 +- libvips/colour/scRGB2sRGB.c | 2 +- libvips/conversion/addalpha.c | 2 +- libvips/conversion/arrayjoin.c | 10 +- libvips/conversion/autorot.c | 6 +- libvips/conversion/bandbool.c | 8 +- libvips/conversion/bandfold.c | 4 +- libvips/conversion/bandjoin.c | 8 +- libvips/conversion/bandmean.c | 2 +- libvips/conversion/bandrank.c | 4 +- libvips/conversion/bandunfold.c | 2 +- libvips/conversion/byteswap.c | 4 +- libvips/conversion/cache.c | 2 +- libvips/conversion/cast.c | 38 ++--- libvips/conversion/conversion.c | 32 ++-- libvips/conversion/copy.c | 18 +- libvips/conversion/embed.c | 10 +- libvips/conversion/extract.c | 8 +- libvips/conversion/falsecolour.c | 2 +- libvips/conversion/flatten.c | 4 +- libvips/conversion/flip.c | 2 +- libvips/conversion/gamma.c | 4 +- libvips/conversion/grid.c | 2 +- libvips/conversion/ifthenelse.c | 6 +- libvips/conversion/insert.c | 6 +- libvips/conversion/join.c | 8 +- libvips/conversion/msb.c | 4 +- libvips/conversion/premultiply.c | 4 +- libvips/conversion/recomb.c | 2 +- libvips/conversion/replicate.c | 2 +- libvips/conversion/rot.c | 8 +- libvips/conversion/rot45.c | 2 +- libvips/conversion/scale.c | 6 +- libvips/conversion/sequential.c | 4 +- libvips/conversion/smartcrop.c | 8 +- libvips/conversion/subsample.c | 4 +- libvips/conversion/switch.c | 2 +- libvips/conversion/tilecache.c | 24 +-- libvips/conversion/transpose3d.c | 10 +- libvips/conversion/unpremultiply.c | 6 +- libvips/conversion/wrap.c | 2 +- libvips/conversion/zoom.c | 2 +- libvips/convolution/canny.c | 4 +- libvips/convolution/compass.c | 10 +- libvips/convolution/conv.c | 6 +- libvips/convolution/conva.c | 6 +- libvips/convolution/convasep.c | 4 +- libvips/convolution/convf.c | 2 +- libvips/convolution/convi.c | 2 +- libvips/convolution/convsep.c | 6 +- libvips/convolution/edge.c | 6 +- libvips/convolution/fastcor.c | 2 +- libvips/convolution/gaussblur.c | 2 +- libvips/convolution/sharpen.c | 14 +- libvips/convolution/spcor.c | 2 +- libvips/create/black.c | 4 +- libvips/create/buildlut.c | 2 +- libvips/create/eye.c | 6 +- libvips/create/fractsurf.c | 2 +- libvips/create/gaussmat.c | 4 +- libvips/create/gaussnoise.c | 6 +- libvips/create/grey.c | 4 +- libvips/create/identity.c | 8 +- libvips/create/invertlut.c | 4 +- libvips/create/logmat.c | 4 +- libvips/create/mask_butterworth.c | 10 +- libvips/create/mask_butterworth_band.c | 10 +- libvips/create/mask_butterworth_ring.c | 10 +- libvips/create/mask_fractal.c | 10 +- libvips/create/mask_gaussian.c | 10 +- libvips/create/mask_gaussian_band.c | 10 +- libvips/create/mask_gaussian_ring.c | 10 +- libvips/create/mask_ideal.c | 10 +- libvips/create/mask_ideal_band.c | 10 +- libvips/create/mask_ideal_ring.c | 10 +- libvips/create/perlin.c | 6 +- libvips/create/sdf.c | 4 +- libvips/create/sines.c | 8 +- libvips/create/text.c | 24 +-- libvips/create/tonelut.c | 22 +-- libvips/create/worley.c | 4 +- libvips/create/xyz.c | 8 +- libvips/create/zone.c | 4 +- libvips/draw/draw_circle.c | 10 +- libvips/draw/draw_flood.c | 24 +-- libvips/draw/draw_image.c | 2 +- libvips/draw/draw_line.c | 4 +- libvips/draw/draw_mask.c | 4 +- libvips/draw/draw_rect.c | 12 +- libvips/draw/draw_smudge.c | 2 +- libvips/foreign/analyzeload.c | 4 +- libvips/foreign/cgifsave.c | 62 +++---- libvips/foreign/csvload.c | 24 +-- libvips/foreign/csvsave.c | 4 +- libvips/foreign/dzsave.c | 62 +++---- libvips/foreign/fitsload.c | 6 +- libvips/foreign/fitssave.c | 2 +- libvips/foreign/foreign.c | 212 ++++++++++++------------ libvips/foreign/jp2kload.c | 22 +-- libvips/foreign/jp2ksave.c | 30 ++-- libvips/foreign/jpegload.c | 34 ++-- libvips/foreign/jpegsave.c | 80 ++++----- libvips/foreign/magickload.c | 14 +- libvips/foreign/magicksave.c | 24 +-- libvips/foreign/matload.c | 4 +- libvips/foreign/matrixload.c | 4 +- libvips/foreign/matrixsave.c | 6 +- libvips/foreign/niftiload.c | 6 +- libvips/foreign/niftisave.c | 2 +- libvips/foreign/nsgifload.c | 22 +-- libvips/foreign/openexrload.c | 4 +- libvips/foreign/pngload.c | 16 +- libvips/foreign/pngsave.c | 54 +++--- libvips/foreign/ppmload.c | 6 +- libvips/foreign/ppmsave.c | 14 +- libvips/foreign/radload.c | 8 +- libvips/foreign/radsave.c | 6 +- libvips/foreign/rawload.c | 6 +- libvips/foreign/rawsave.c | 6 +- libvips/foreign/svgload.c | 34 ++-- libvips/foreign/tiffload.c | 56 +++---- libvips/foreign/tiffsave.c | 114 ++++++------- libvips/foreign/vipsload.c | 4 +- libvips/foreign/vipssave.c | 4 +- libvips/foreign/webpload.c | 26 +-- libvips/foreign/webpsave.c | 114 ++++++------- libvips/freqfilt/freqmult.c | 2 +- libvips/freqfilt/fwfft.c | 2 +- libvips/freqfilt/invfft.c | 4 +- libvips/freqfilt/phasecor.c | 2 +- libvips/freqfilt/spectrum.c | 2 +- libvips/histogram/case.c | 2 +- libvips/histogram/hist_cum.c | 2 +- libvips/histogram/hist_entropy.c | 2 +- libvips/histogram/hist_equal.c | 4 +- libvips/histogram/hist_ismonotonic.c | 2 +- libvips/histogram/hist_local.c | 4 +- libvips/histogram/hist_match.c | 2 +- libvips/histogram/hist_norm.c | 2 +- libvips/histogram/hist_plot.c | 2 +- libvips/histogram/maplut.c | 4 +- libvips/histogram/percent.c | 2 +- libvips/histogram/stdif.c | 10 +- libvips/include/vips/almostdeprecated.h | 2 +- libvips/include/vips/arithmetic.h | 68 ++++---- libvips/include/vips/foreign.h | 24 +-- libvips/include/vips/type.h | 16 +- libvips/iofuncs/buf.c | 30 ++-- libvips/iofuncs/cache.c | 4 +- libvips/iofuncs/dbuf.c | 14 +- libvips/iofuncs/error.c | 18 +- libvips/iofuncs/gate.c | 2 +- libvips/iofuncs/generate.c | 20 +-- libvips/iofuncs/image.c | 82 ++++----- libvips/iofuncs/memory.c | 24 +-- libvips/iofuncs/object.c | 50 +++--- libvips/iofuncs/operation.c | 6 +- libvips/iofuncs/rect.c | 10 +- libvips/iofuncs/sbuf.c | 10 +- libvips/iofuncs/sinkdisc.c | 10 +- libvips/iofuncs/sinkscreen.c | 2 +- libvips/iofuncs/source.c | 6 +- libvips/iofuncs/sourcecustom.c | 8 +- libvips/iofuncs/system.c | 4 +- libvips/iofuncs/targetcustom.c | 12 +- libvips/iofuncs/thread.c | 2 +- libvips/iofuncs/threadpool.c | 6 +- libvips/iofuncs/type.c | 25 +-- libvips/iofuncs/util.c | 20 +-- libvips/morphology/countlines.c | 2 +- libvips/morphology/labelregions.c | 4 +- libvips/morphology/morph.c | 2 +- libvips/morphology/nearest.c | 2 +- libvips/morphology/rank.c | 4 +- libvips/mosaicing/global_balance.c | 6 +- libvips/mosaicing/match.c | 10 +- libvips/mosaicing/matrixinvert.c | 2 +- libvips/mosaicing/matrixmultiply.c | 2 +- libvips/mosaicing/merge.c | 4 +- libvips/mosaicing/mosaic.c | 22 +-- libvips/mosaicing/mosaic1.c | 12 +- libvips/mosaicing/remosaic.c | 2 +- libvips/resample/affine.c | 12 +- libvips/resample/mapim.c | 6 +- libvips/resample/quadratic.c | 2 +- libvips/resample/reduce.c | 4 +- libvips/resample/reduceh.cpp | 4 +- libvips/resample/reducev.cpp | 4 +- libvips/resample/resize.c | 6 +- libvips/resample/shrink.c | 4 +- libvips/resample/shrinkh.c | 4 +- libvips/resample/shrinkv.c | 4 +- libvips/resample/similarity.c | 26 +-- libvips/resample/thumbnail.c | 72 ++++---- 259 files changed, 1418 insertions(+), 1408 deletions(-) diff --git a/doc/rename.sed b/doc/rename.sed index 6c08db2ba4..662542b523 100644 --- a/doc/rename.sed +++ b/doc/rename.sed @@ -518,6 +518,17 @@ s/g_object_\([^(]*\)()/[method@GObject.Object.\1]/g s/%GValue/[struct@GObject.Value]/g s/%GObject/[class@GObject.Object]/g s/%GThread/[struct@GLib.Thread]/g +s/%GType/[alias@GObject.Type]/g +s/%NULL/`NULL`/g +s/%TRUE/`TRUE`/g +s/%FALSE/`FALSE`/g +s/%gint64/`gint64`/g +s/%guint64/`guint64`/g +s/%gint/`gint`/g +s/%gboolean/`gboolean`/g +s/%gdouble/`gdouble`/g +s/%gchararray/`gchararray`/g +s/%gpointer/`gpointer`/g s/%GInputStream/[class@Gio.InputStream]/g s/%GInput/[class@Gio.Input]/g s/%GSList/[struct@GLib.SList]/g diff --git a/libvips/arithmetic/abs.c b/libvips/arithmetic/abs.c index 9801f64b0d..90f52faa8e 100644 --- a/libvips/arithmetic/abs.c +++ b/libvips/arithmetic/abs.c @@ -214,7 +214,7 @@ vips_abs_init(VipsAbs *abs) * vips_abs: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation finds the absolute value of an image. It does a copy for * unsigned integer types, negate for negative values in diff --git a/libvips/arithmetic/add.c b/libvips/arithmetic/add.c index c638b2847a..351dcc6420 100644 --- a/libvips/arithmetic/add.c +++ b/libvips/arithmetic/add.c @@ -192,7 +192,7 @@ vips_add_init(VipsAdd *add) * @left: input image * @right: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation calculates @in1 + @in2 and writes the result to @out. * diff --git a/libvips/arithmetic/avg.c b/libvips/arithmetic/avg.c index dd6d658320..45e8117cb6 100644 --- a/libvips/arithmetic/avg.c +++ b/libvips/arithmetic/avg.c @@ -248,7 +248,7 @@ vips_avg_init(VipsAvg *avg) * vips_avg: (method) * @in: input [class@Image] * @out: (out): output pixel average - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation finds the average value in an image. It operates on all * bands of the input image: use [method@Image.stats] if you need to calculate an diff --git a/libvips/arithmetic/boolean.c b/libvips/arithmetic/boolean.c index 1eb9d27b0a..dc9a54a1ab 100644 --- a/libvips/arithmetic/boolean.c +++ b/libvips/arithmetic/boolean.c @@ -300,7 +300,7 @@ vips_booleanv(VipsImage *left, VipsImage *right, VipsImage **out, * @right: right-hand input [class@Image] * @out: (out): output [class@Image] * @boolean: boolean operation to perform - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform various boolean operations on pairs of images. * @@ -344,7 +344,7 @@ vips_boolean(VipsImage *left, VipsImage *right, VipsImage **out, * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.AND] on a pair of images. See * [method@Image.boolean]. @@ -370,7 +370,7 @@ vips_andimage(VipsImage *left, VipsImage *right, VipsImage **out, ...) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.OR] on a pair of images. See * [method@Image.boolean]. @@ -396,7 +396,7 @@ vips_orimage(VipsImage *left, VipsImage *right, VipsImage **out, ...) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.EOR] on a pair of images. See * [method@Image.boolean]. @@ -422,7 +422,7 @@ vips_eorimage(VipsImage *left, VipsImage *right, VipsImage **out, ...) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.LSHIFT] on a pair of images. See * [method@Image.boolean]. @@ -448,7 +448,7 @@ vips_lshift(VipsImage *left, VipsImage *right, VipsImage **out, ...) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.RSHIFT] on a pair of images. See * [method@Image.boolean]. @@ -617,7 +617,7 @@ vips_boolean_constv(VipsImage *in, VipsImage **out, * @boolean: boolean operation to perform * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform various boolean operations on an image against an array of * constants. @@ -656,7 +656,7 @@ vips_boolean_const(VipsImage *in, VipsImage **out, * @out: (out): output image * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.AND] on an image and an array of constants. * See [method@Image.boolean_const]. @@ -687,7 +687,7 @@ vips_andimage_const(VipsImage *in, VipsImage **out, * @out: (out): output image * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.OR] on an image and an array of constants. * See [method@Image.boolean_const]. @@ -718,7 +718,7 @@ vips_orimage_const(VipsImage *in, VipsImage **out, * @out: (out): output image * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.EOR] on an image and an array of constants. * See [method@Image.boolean_const]. @@ -749,7 +749,7 @@ vips_eorimage_const(VipsImage *in, VipsImage **out, * @out: (out): output image * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.LSHIFT] on an image and an array of constants. * See [method@Image.boolean_const]. @@ -779,7 +779,7 @@ vips_lshift_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @out: (out): output image * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.LSHIFT] on an image and an array of constants. * See [method@Image.boolean_const]. @@ -809,7 +809,7 @@ vips_rshift_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @out: (out): output image * @boolean: boolean operation to perform * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform various boolean operations on an image with a single constant. See * [method@Image.boolean_const]. @@ -838,7 +838,7 @@ vips_boolean_const1(VipsImage *in, VipsImage **out, * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.AND] on an image and a constant. * See [method@Image.boolean_const1]. @@ -867,7 +867,7 @@ vips_andimage_const1(VipsImage *in, VipsImage **out, double c, ...) * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.OR] on an image and a constant. * See [method@Image.boolean_const1]. @@ -896,7 +896,7 @@ vips_orimage_const1(VipsImage *in, VipsImage **out, double c, ...) * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.EOR] on an image and a constant. * See [method@Image.boolean_const1]. @@ -925,7 +925,7 @@ vips_eorimage_const1(VipsImage *in, VipsImage **out, double c, ...) * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.LSHIFT] on an image and a constant. * See [method@Image.boolean_const1]. @@ -954,7 +954,7 @@ vips_lshift_const1(VipsImage *in, VipsImage **out, double c, ...) * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.RSHIFT] on an image and a constant. * See [method@Image.boolean_const1]. diff --git a/libvips/arithmetic/clamp.c b/libvips/arithmetic/clamp.c index 4d51fdbf3d..be22b47998 100644 --- a/libvips/arithmetic/clamp.c +++ b/libvips/arithmetic/clamp.c @@ -184,15 +184,15 @@ vips_clamp_init(VipsClamp *clamp) * vips_clamp: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation clamps pixel values to a range, by default 0 - 1. * * Use @min and @max to change the range. * * ::: tip "Optional arguments" - * * @min: %gdouble, minimum value - * * @max: %gdouble, maximum value + * * @min: `gdouble`, minimum value + * * @max: `gdouble`, maximum value * * ::: seealso * [method@Image.sign], [method@Image.abs], [ctor@Image.sdf]. diff --git a/libvips/arithmetic/complex.c b/libvips/arithmetic/complex.c index 442d67e8c4..1ff9649ce2 100644 --- a/libvips/arithmetic/complex.c +++ b/libvips/arithmetic/complex.c @@ -279,7 +279,7 @@ vips_complexv(VipsImage *in, VipsImage **out, * @in: input [class@Image] * @out: (out): output [class@Image] * @cmplx: complex operation to perform - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform various operations on complex images. * @@ -305,7 +305,7 @@ vips_complex(VipsImage *in, VipsImage **out, VipsOperationComplex cmplx, ...) * vips_polar: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationComplex.POLAR] on an image. See [method@Image.complex]. * @@ -328,7 +328,7 @@ vips_polar(VipsImage *in, VipsImage **out, ...) * vips_rect: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationComplex.RECT] on an image. See [method@Image.complex]. * @@ -351,7 +351,7 @@ vips_rect(VipsImage *in, VipsImage **out, ...) * vips_conj: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationComplex.CONJ] on an image. See [method@Image.complex]. * @@ -561,7 +561,7 @@ vips_complex2v(VipsImage *left, VipsImage *right, VipsImage **out, * @right: input [class@Image] * @out: (out): output [class@Image] * @cmplx: complex2 operation to perform - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform various binary operations on complex images. * @@ -589,7 +589,7 @@ vips_complex2(VipsImage *left, VipsImage *right, VipsImage **out, * @left: input [class@Image] * @right: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationComplex2.CROSS_PHASE] on an image. * See [method@Image.complex2]. @@ -793,7 +793,7 @@ vips_complexgetv(VipsImage *in, VipsImage **out, * @in: input [class@Image] * @out: (out): output [class@Image] * @get: complex operation to perform - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Get components of complex images. * @@ -821,7 +821,7 @@ vips_complexget(VipsImage *in, VipsImage **out, * vips_real: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationComplexget.REAL] on an image. See [method@Image.complexget]. * @@ -845,7 +845,7 @@ vips_real(VipsImage *in, VipsImage **out, ...) * vips_imag: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationComplexget.IMAG] on an image. See [method@Image.complexget]. * @@ -994,7 +994,7 @@ vips_complexform_init(VipsComplexform *complexform) * @left: input image * @right: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Compose two real images to make a complex image. If either @left or @right * are [enum@Vips.BandFormat.DOUBLE], @out is [enum@Vips.BandFormat.DPCOMPLEX]. Otherwise @out diff --git a/libvips/arithmetic/deviate.c b/libvips/arithmetic/deviate.c index 639c80c16d..168992a109 100644 --- a/libvips/arithmetic/deviate.c +++ b/libvips/arithmetic/deviate.c @@ -250,7 +250,7 @@ vips_deviate_init(VipsDeviate *deviate) * vips_deviate: (method) * @in: input [class@Image] * @out: (out): output pixel standard deviation - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation finds the standard deviation of all pixels in @in. It * operates on all bands of the input image: use [method@Image.stats] if you need diff --git a/libvips/arithmetic/divide.c b/libvips/arithmetic/divide.c index 7644b90b6a..9bf007fa2e 100644 --- a/libvips/arithmetic/divide.c +++ b/libvips/arithmetic/divide.c @@ -224,7 +224,7 @@ vips_divide_init(VipsDivide *divide) * @left: input image * @right: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation calculates @in1 / @in2 and writes the result to @out. If any * pixels in @in2 are zero, the corresponding pixel in @out is also zero. diff --git a/libvips/arithmetic/find_trim.c b/libvips/arithmetic/find_trim.c index f7af45c515..85d2d3b4c6 100644 --- a/libvips/arithmetic/find_trim.c +++ b/libvips/arithmetic/find_trim.c @@ -254,7 +254,7 @@ vips_find_trim_init(VipsFindTrim *find_trim) * @top: (out): output top edge * @width: (out): output width * @height: (out): output height - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Search @in for the bounding box of the non-background area. * @@ -281,9 +281,9 @@ vips_find_trim_init(VipsFindTrim *find_trim) * The image needs to be at least 3x3 pixels in size. * * ::: tip "Optional arguments" - * * @threshold: %gdouble, background / object threshold + * * @threshold: `gdouble`, background / object threshold * * @background: [struct@ArrayDouble], background colour - * * @line_art: %gboolean, enable line art mode + * * @line_art: `gboolean`, enable line art mode * * ::: seealso * [method@Image.getpoint], [method@Image.extract_area], [method@Image.smartcrop]. diff --git a/libvips/arithmetic/getpoint.c b/libvips/arithmetic/getpoint.c index 73ed2b1094..0a0e20456a 100644 --- a/libvips/arithmetic/getpoint.c +++ b/libvips/arithmetic/getpoint.c @@ -196,7 +196,7 @@ vips_getpoint_init(VipsGetpoint *getpoint) * @n: length of output vector * @x: position to read * @y: position to read - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Reads a single pixel on an image. * diff --git a/libvips/arithmetic/hist_find.c b/libvips/arithmetic/hist_find.c index fc67898f07..9f697653a1 100644 --- a/libvips/arithmetic/hist_find.c +++ b/libvips/arithmetic/hist_find.c @@ -451,7 +451,7 @@ vips_hist_find_init(VipsHistFind *hist_find) * vips_hist_find: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Find the histogram of @in. Find the histogram for band @band (producing a * one-band histogram), or for all bands (producing an n-band histogram) if diff --git a/libvips/arithmetic/hist_find_indexed.c b/libvips/arithmetic/hist_find_indexed.c index fad61a47ec..d34163bed1 100644 --- a/libvips/arithmetic/hist_find_indexed.c +++ b/libvips/arithmetic/hist_find_indexed.c @@ -496,7 +496,7 @@ vips_hist_find_indexed_init(VipsHistFindIndexed *indexed) * @in: input [class@Image] * @index: input index [class@Image] * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * * Make a histogram of @in, but use image @index to pick the bins. In other @@ -518,7 +518,7 @@ vips_hist_find_indexed_init(VipsHistFindIndexed *indexed) * example. * * ::: tip "Optional arguments" - * * @combine: #VipsCombine, combine bins like this + * * @combine: [enum@Combine], combine bins like this * * ::: seealso * [method@Image.hist_find], [method@Image.labelregions]. diff --git a/libvips/arithmetic/hist_find_ndim.c b/libvips/arithmetic/hist_find_ndim.c index bb35016cd3..620d88e624 100644 --- a/libvips/arithmetic/hist_find_ndim.c +++ b/libvips/arithmetic/hist_find_ndim.c @@ -333,7 +333,7 @@ vips_hist_find_ndim_init(VipsHistFindNDim *ndim) * vips_hist_find_ndim: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make a one, two or three dimensional histogram of a 1, 2 or * 3 band image. Divide each axis into @bins bins .. ie. diff --git a/libvips/arithmetic/hough_circle.c b/libvips/arithmetic/hough_circle.c index 8c538bd113..5d4481f0fd 100644 --- a/libvips/arithmetic/hough_circle.c +++ b/libvips/arithmetic/hough_circle.c @@ -263,7 +263,7 @@ vips_hough_circle_init(VipsHoughCircle *hough_circle) * vips_hough_circle: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Find the circular Hough transform of an image. @in must be one band, with * non-zero pixels for image edges. @out is three-band, with the third channel diff --git a/libvips/arithmetic/hough_line.c b/libvips/arithmetic/hough_line.c index 7b1df999e8..20f6d6956b 100644 --- a/libvips/arithmetic/hough_line.c +++ b/libvips/arithmetic/hough_line.c @@ -169,7 +169,7 @@ vips_hough_line_init(VipsHoughLine *hough_line) * vips_hough_line: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Find the line Hough transform for @in. @in must have one band. @out has one * band, with pixels being the number of votes for that line. The X dimension diff --git a/libvips/arithmetic/invert.c b/libvips/arithmetic/invert.c index 8e12df6481..22b3961ac3 100644 --- a/libvips/arithmetic/invert.c +++ b/libvips/arithmetic/invert.c @@ -191,7 +191,7 @@ vips_invert_init(VipsInvert *invert) * vips_invert: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * For unsigned formats, this operation calculates (max - @in), eg. (255 - * @in) for uchar. For signed and float formats, this operation calculates (-1 diff --git a/libvips/arithmetic/linear.c b/libvips/arithmetic/linear.c index 6b2861fe7f..10e3308b22 100644 --- a/libvips/arithmetic/linear.c +++ b/libvips/arithmetic/linear.c @@ -503,7 +503,7 @@ vips_linearv(VipsImage *in, VipsImage **out, * @a: (array length=n): array of constants for multiplication * @b: (array length=n): array of constants for addition * @n: length of constant arrays - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Pass an image through a linear transform, ie. (@out = @in * @a + @b). Output * is float for integer input, double for double input, complex for @@ -545,7 +545,7 @@ vips_linear(VipsImage *in, VipsImage **out, * @out: (out): output image * @a: constant for multiplication * @b: constant for addition - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Run [method@Image.linear] with a single constant. * diff --git a/libvips/arithmetic/math.c b/libvips/arithmetic/math.c index 8dcea0dda7..243f435921 100644 --- a/libvips/arithmetic/math.c +++ b/libvips/arithmetic/math.c @@ -281,7 +281,7 @@ vips_mathv(VipsImage *in, VipsImage **out, VipsOperationMath math, va_list ap) * @in: input [class@Image] * @out: (out): output [class@Image] * @math: math operation to perform - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform various functions in -lm, the maths library, on images. * @@ -312,7 +312,7 @@ vips_math(VipsImage *in, VipsImage **out, VipsOperationMath math, ...) * vips_sin: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.SIN] on an image. See [method@Image.math]. * @@ -335,7 +335,7 @@ vips_sin(VipsImage *in, VipsImage **out, ...) * vips_cos: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.COS] on an image. See [method@Image.math]. * @@ -358,7 +358,7 @@ vips_cos(VipsImage *in, VipsImage **out, ...) * vips_tan: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.TAN] on an image. See [method@Image.math]. * @@ -381,7 +381,7 @@ vips_tan(VipsImage *in, VipsImage **out, ...) * vips_asin: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.ASIN] on an image. See [method@Image.math]. * @@ -404,7 +404,7 @@ vips_asin(VipsImage *in, VipsImage **out, ...) * vips_acos: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.ACOS] on an image. See [method@Image.math]. * @@ -427,7 +427,7 @@ vips_acos(VipsImage *in, VipsImage **out, ...) * vips_atan: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.ATAN] on an image. See [method@Image.math]. * @@ -450,7 +450,7 @@ vips_atan(VipsImage *in, VipsImage **out, ...) * vips_sinh: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.SINH] on an image. See [method@Image.math]. * @@ -473,7 +473,7 @@ vips_sinh(VipsImage *in, VipsImage **out, ...) * vips_cosh: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.COSH] on an image. See [method@Image.math]. * @@ -496,7 +496,7 @@ vips_cosh(VipsImage *in, VipsImage **out, ...) * vips_tanh: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.TANH] on an image. See [method@Image.math]. * @@ -519,7 +519,7 @@ vips_tanh(VipsImage *in, VipsImage **out, ...) * vips_asinh: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.ASINH] on an image. See [method@Image.math]. * @@ -542,7 +542,7 @@ vips_asinh(VipsImage *in, VipsImage **out, ...) * vips_acosh: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.ACOSH] on an image. See [method@Image.math]. * @@ -565,7 +565,7 @@ vips_acosh(VipsImage *in, VipsImage **out, ...) * vips_atanh: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.ATANH] on an image. See [method@Image.math]. * @@ -588,7 +588,7 @@ vips_atanh(VipsImage *in, VipsImage **out, ...) * vips_log: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.LOG] on an image. See [method@Image.math]. * @@ -611,7 +611,7 @@ vips_log(VipsImage *in, VipsImage **out, ...) * vips_log10: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.LOG10] on an image. See [method@Image.math]. * @@ -634,7 +634,7 @@ vips_log10(VipsImage *in, VipsImage **out, ...) * vips_exp: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.EXP] on an image. See [method@Image.math]. * @@ -657,7 +657,7 @@ vips_exp(VipsImage *in, VipsImage **out, ...) * vips_exp10: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath.EXP10] on an image. See [method@Image.math]. * diff --git a/libvips/arithmetic/math2.c b/libvips/arithmetic/math2.c index 96c3eae484..3f4c83e041 100644 --- a/libvips/arithmetic/math2.c +++ b/libvips/arithmetic/math2.c @@ -263,7 +263,7 @@ vips_math2v(VipsImage *left, VipsImage *right, VipsImage **out, * @right: right-hand input [class@Image] * @out: (out): output [class@Image] * @math2: math operation to perform - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation calculates a 2-ary maths operation on a pair of images * and writes the result to @out. The images may have any @@ -310,7 +310,7 @@ vips_math2(VipsImage *left, VipsImage *right, VipsImage **out, * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath2.POW] on a pair of images. See * [method@Image.math2]. @@ -335,7 +335,7 @@ vips_pow(VipsImage *left, VipsImage *right, VipsImage **out, ...) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath2.WOP] on a pair of images. See * [method@Image.math2]. @@ -360,7 +360,7 @@ vips_wop(VipsImage *left, VipsImage *right, VipsImage **out, ...) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath2.ATAN2] on a pair of images. See * [method@Image.math2]. @@ -509,7 +509,7 @@ vips_math2_constv(VipsImage *in, VipsImage **out, * @math2: math operation to perform * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation calculates various 2-ary maths operations on an image and * an array of constants and writes the result to @out. @@ -552,7 +552,7 @@ vips_math2_const(VipsImage *in, VipsImage **out, * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath2.POW] on an image and a constant. See * [method@Image.math2_const]. @@ -579,7 +579,7 @@ vips_pow_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath2.WOP] on an image and a constant. See * [method@Image.math2_const]. @@ -606,7 +606,7 @@ vips_wop_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath2.ATAN2] on an image and a constant. See * [method@Image.math2_const]. @@ -633,7 +633,7 @@ vips_atan2_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @out: (out): output image * @math2: math operation to perform * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation calculates various 2-ary maths operations on an image and * a constant. See [method@Image.math2_const]. @@ -659,7 +659,7 @@ vips_math2_const1(VipsImage *in, VipsImage **out, * @in: left-hand input [class@Image] * @out: (out): output [class@Image] * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath2.POW] on an image and a constant. See * [method@Image.math2_const]. @@ -685,7 +685,7 @@ vips_pow_const1(VipsImage *in, VipsImage **out, double c, ...) * @in: left-hand input [class@Image] * @out: (out): output [class@Image] * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath2.WOP] on an image and a constant. See * [method@Image.math2_const]. @@ -711,7 +711,7 @@ vips_wop_const1(VipsImage *in, VipsImage **out, double c, ...) * @in: left-hand input [class@Image] * @out: (out): output [class@Image] * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationMath2.ATAN2] on an image and a constant. See * [method@Image.math2_const]. diff --git a/libvips/arithmetic/max.c b/libvips/arithmetic/max.c index 9eaa80a9e6..212b9ff9bf 100644 --- a/libvips/arithmetic/max.c +++ b/libvips/arithmetic/max.c @@ -508,7 +508,7 @@ vips_max_init(VipsMax *max) * vips_max: (method) * @in: input [class@Image] * @out: (out): output pixel maximum - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation finds the maximum value in an image. * diff --git a/libvips/arithmetic/maxpair.c b/libvips/arithmetic/maxpair.c index e6492c7ed4..88dc55c1f7 100644 --- a/libvips/arithmetic/maxpair.c +++ b/libvips/arithmetic/maxpair.c @@ -165,7 +165,7 @@ vips_maxpair_init(VipsMaxpair *maxpair) * @left: input image * @right: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * For each pixel, pick the maximum of a pair of images. * diff --git a/libvips/arithmetic/measure.c b/libvips/arithmetic/measure.c index 0d747441a5..73045bf322 100644 --- a/libvips/arithmetic/measure.c +++ b/libvips/arithmetic/measure.c @@ -257,7 +257,7 @@ vips_measure_init(VipsMeasure *measure) * @out: (out): array of measurements * @h: patches across chart * @v: patches down chart - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Analyse a grid of colour patches, producing an array of patch averages. * The mask has a row for each measured patch and a column for each image diff --git a/libvips/arithmetic/min.c b/libvips/arithmetic/min.c index e8f651fa94..411c07933a 100644 --- a/libvips/arithmetic/min.c +++ b/libvips/arithmetic/min.c @@ -508,7 +508,7 @@ vips_min_init(VipsMin *min) * vips_min: (method) * @in: input [class@Image] * @out: (out): output pixel minimum - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation finds the minimum value in an image. * diff --git a/libvips/arithmetic/minpair.c b/libvips/arithmetic/minpair.c index adaec5830b..e120f01cab 100644 --- a/libvips/arithmetic/minpair.c +++ b/libvips/arithmetic/minpair.c @@ -165,7 +165,7 @@ vips_minpair_init(VipsMinpair *minpair) * @left: input image * @right: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * For each pixel, pick the minimum of a pair of images. * diff --git a/libvips/arithmetic/multiply.c b/libvips/arithmetic/multiply.c index 8656847d09..f0f082ff97 100644 --- a/libvips/arithmetic/multiply.c +++ b/libvips/arithmetic/multiply.c @@ -209,7 +209,7 @@ vips_multiply_init(VipsMultiply *multiply) * @left: left-hand image * @right: right-hand image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation calculates @left * @right and writes the result to @out. * diff --git a/libvips/arithmetic/profile.c b/libvips/arithmetic/profile.c index 940f419a82..0cd35de628 100644 --- a/libvips/arithmetic/profile.c +++ b/libvips/arithmetic/profile.c @@ -320,7 +320,7 @@ vips_profile_init(VipsProfile *profile) * @in: input image * @columns: (out): distances from top edge * @rows: (out): distances from left edge - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * [method@Image.profile] searches inward from the edge of @in and finds the * first non-zero pixel. Pixels in @columns have the distance from the top edge diff --git a/libvips/arithmetic/project.c b/libvips/arithmetic/project.c index 33c3915f33..e6d5173c8c 100644 --- a/libvips/arithmetic/project.c +++ b/libvips/arithmetic/project.c @@ -351,7 +351,7 @@ vips_project_init(VipsProject *project) * @in: input image * @columns: (out): sums of columns * @rows: (out): sums of rows - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Find the horizontal and vertical projections of an image, ie. the sum * of every row of pixels, and the sum of every column of pixels. The output diff --git a/libvips/arithmetic/relational.c b/libvips/arithmetic/relational.c index 7a30e32b3a..54ad5a615a 100644 --- a/libvips/arithmetic/relational.c +++ b/libvips/arithmetic/relational.c @@ -270,7 +270,7 @@ vips_relationalv(VipsImage *left, VipsImage *right, VipsImage **out, * @right: right-hand input [class@Image] * @out: (out): output [class@Image] * @relational: relational operation to perform - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform various relational operations on pairs of images. * @@ -319,7 +319,7 @@ vips_relational(VipsImage *left, VipsImage *right, VipsImage **out, * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.EQUAL] on a pair of images. See * [method@Image.relational]. @@ -345,7 +345,7 @@ vips_equal(VipsImage *left, VipsImage *right, VipsImage **out, ...) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.NOTEQ] on a pair of images. See * [method@Image.relational]. @@ -371,7 +371,7 @@ vips_notequal(VipsImage *left, VipsImage *right, VipsImage **out, ...) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.MORE] on a pair of images. See * [method@Image.relational]. @@ -397,7 +397,7 @@ vips_more(VipsImage *left, VipsImage *right, VipsImage **out, ...) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.MOREEQ] on a pair of images. See * [method@Image.relational]. @@ -423,7 +423,7 @@ vips_moreeq(VipsImage *left, VipsImage *right, VipsImage **out, ...) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.LESS] on a pair of images. See * [method@Image.relational]. @@ -449,7 +449,7 @@ vips_less(VipsImage *left, VipsImage *right, VipsImage **out, ...) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.LESSEQ] on a pair of images. See * [method@Image.relational]. @@ -652,7 +652,7 @@ vips_relational_constv(VipsImage *in, VipsImage **out, * @relational: relational operation to perform * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform various relational operations on an image and an array of * constants. @@ -691,7 +691,7 @@ vips_relational_const(VipsImage *in, VipsImage **out, * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.EQUAL] on an image and a constant. See * [method@Image.relational_const]. @@ -718,7 +718,7 @@ vips_equal_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.NOTEQ] on an image and a constant. See * [method@Image.relational_const]. @@ -746,7 +746,7 @@ vips_notequal_const(VipsImage *in, VipsImage **out, * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.LESS] on an image and a constant. See * [method@Image.relational_const]. @@ -773,7 +773,7 @@ vips_less_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.LESSEQ] on an image and a constant. See * [method@Image.relational_const]. @@ -800,7 +800,7 @@ vips_lesseq_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.MORE] on an image and a constant. See * [method@Image.relational_const]. @@ -827,7 +827,7 @@ vips_more_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @out: (out): output [class@Image] * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.MOREEQ] on an image and a constant. See * [method@Image.relational_const]. @@ -854,7 +854,7 @@ vips_moreeq_const(VipsImage *in, VipsImage **out, const double *c, int n, ...) * @out: (out): output image * @relational: relational operation to perform * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform various relational operations on an image and a constant. See * [method@Image.relational_const]. @@ -883,7 +883,7 @@ vips_relational_const1(VipsImage *in, VipsImage **out, * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.EQUAL] on an image and a constant. See * [method@Image.relational_const]. @@ -909,7 +909,7 @@ vips_equal_const1(VipsImage *in, VipsImage **out, double c, ...) * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.NOTEQ] on an image and a constant. See * [method@Image.relational_const]. @@ -935,7 +935,7 @@ vips_notequal_const1(VipsImage *in, VipsImage **out, double c, ...) * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.LESS] on an image and a constant. See * [method@Image.relational_const]. @@ -961,7 +961,7 @@ vips_less_const1(VipsImage *in, VipsImage **out, double c, ...) * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.LESSEQ] on an image and a constant. See * [method@Image.relational_const]. @@ -987,7 +987,7 @@ vips_lesseq_const1(VipsImage *in, VipsImage **out, double c, ...) * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.MORE] on an image and a constant. See * [method@Image.relational_const]. @@ -1013,7 +1013,7 @@ vips_more_const1(VipsImage *in, VipsImage **out, double c, ...) * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationRelational.MOREEQ] on an image and a constant. See * [method@Image.relational_const]. diff --git a/libvips/arithmetic/remainder.c b/libvips/arithmetic/remainder.c index 28a59fb164..52f2f5ca34 100644 --- a/libvips/arithmetic/remainder.c +++ b/libvips/arithmetic/remainder.c @@ -208,7 +208,7 @@ vips_remainder_init(VipsRemainder *remainder) * @left: left-hand input [class@Image] * @right: right-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation calculates @left % @right (remainder after integer division) * and writes the result to @out. The images may have any @@ -391,7 +391,7 @@ vips_remainder_constv(VipsImage *in, VipsImage **out, * @out: (out): output image * @c: (array length=n): array of constants * @n: number of constants in @c - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation calculates @in % @c (remainder after division by an * array of constants) @@ -431,7 +431,7 @@ vips_remainder_const(VipsImage *in, VipsImage **out, * @in: input image * @out: (out): output image * @c: constant - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation calculates @in % @c (remainder after division by a * constant) diff --git a/libvips/arithmetic/round.c b/libvips/arithmetic/round.c index 1df980dcfa..361f283665 100644 --- a/libvips/arithmetic/round.c +++ b/libvips/arithmetic/round.c @@ -202,7 +202,7 @@ vips_roundv(VipsImage *in, VipsImage **out, * @in: input [class@Image] * @out: (out): output [class@Image] * @round: [class@Operation]Round rounding operation to perform - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Round to an integral value. * @@ -234,7 +234,7 @@ vips_round(VipsImage *in, VipsImage **out, VipsOperationRound round, ...) * vips_floor: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Round to an integral value with [enum@Vips.OperationRound.FLOOR]. See * [method@Image.round]. @@ -258,7 +258,7 @@ vips_floor(VipsImage *in, VipsImage **out, ...) * vips_ceil: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Round to an integral value with [enum@Vips.OperationRound.CEIL]. See * [method@Image.round]. @@ -282,7 +282,7 @@ vips_ceil(VipsImage *in, VipsImage **out, ...) * vips_rint: (method) * @in: input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Round to an integral value with [enum@Vips.OperationRound.RINT]. See * [method@Image.round]. diff --git a/libvips/arithmetic/sign.c b/libvips/arithmetic/sign.c index 564fde6f56..f580a7d167 100644 --- a/libvips/arithmetic/sign.c +++ b/libvips/arithmetic/sign.c @@ -187,7 +187,7 @@ vips_sign_init(VipsSign *sign) * vips_sign: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Finds the unit vector in the direction of the pixel value. For non-complex * images, it returns a signed char image with values -1, 0, and 1 for negative, diff --git a/libvips/arithmetic/stats.c b/libvips/arithmetic/stats.c index c45f609042..a6b826cbbb 100644 --- a/libvips/arithmetic/stats.c +++ b/libvips/arithmetic/stats.c @@ -454,7 +454,7 @@ vips_stats_init(VipsStats *stats) * vips_stats: (method) * @in: image to scan * @out: (out): image of statistics - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Find many image statistics in a single pass through the data. @out is a * one-band [enum@Vips.BandFormat.DOUBLE] image of at least 10 columns by n + 1 diff --git a/libvips/arithmetic/subtract.c b/libvips/arithmetic/subtract.c index 3e64f0f9fe..b53968bfc8 100644 --- a/libvips/arithmetic/subtract.c +++ b/libvips/arithmetic/subtract.c @@ -188,7 +188,7 @@ vips_subtract_init(VipsSubtract *subtract) * @in1: input image * @in2: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation calculates @in1 - @in2 and writes the result to @out. * diff --git a/libvips/arithmetic/sum.c b/libvips/arithmetic/sum.c index d568c69fbc..1fdca1aa77 100644 --- a/libvips/arithmetic/sum.c +++ b/libvips/arithmetic/sum.c @@ -176,7 +176,7 @@ vips_sumv(VipsImage **in, VipsImage **out, int n, va_list ap) * @in: (array length=n): array of input images * @out: (out): output image * @n: number of input images - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation sums all images in @in and writes the result to @out. * diff --git a/libvips/colour/CMYK2XYZ.c b/libvips/colour/CMYK2XYZ.c index 7e132205f1..8269a1d0e5 100644 --- a/libvips/colour/CMYK2XYZ.c +++ b/libvips/colour/CMYK2XYZ.c @@ -206,7 +206,7 @@ vips_CMYK2XYZ_init(VipsCMYK2XYZ *CMYK2XYZ) * vips_CMYK2XYZ: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn CMYK to XYZ. If the image has an embedded ICC profile this will be * used for the conversion. If there is no embedded profile, a generic diff --git a/libvips/colour/HSV2sRGB.c b/libvips/colour/HSV2sRGB.c index 6c1f560475..0e22e8ab5b 100644 --- a/libvips/colour/HSV2sRGB.c +++ b/libvips/colour/HSV2sRGB.c @@ -134,7 +134,7 @@ vips_HSV2sRGB_init(VipsHSV2sRGB *HSV2sRGB) * vips_HSV2sRGB: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert HSV to sRGB. * diff --git a/libvips/colour/LCh2Lab.c b/libvips/colour/LCh2Lab.c index c37dd9246a..2b1313be38 100644 --- a/libvips/colour/LCh2Lab.c +++ b/libvips/colour/LCh2Lab.c @@ -125,7 +125,7 @@ vips_LCh2Lab_init(VipsLCh2Lab *LCh2Lab) * vips_LCh2Lab: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn LCh to Lab. * diff --git a/libvips/colour/LCh2UCS.c b/libvips/colour/LCh2UCS.c index 33ab537f2f..dfd7b167bf 100644 --- a/libvips/colour/LCh2UCS.c +++ b/libvips/colour/LCh2UCS.c @@ -220,7 +220,7 @@ vips_LCh2CMC_init(VipsLCh2CMC *LCh2CMC) * vips_LCh2CMC: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn LCh to CMC. * diff --git a/libvips/colour/Lab2LCh.c b/libvips/colour/Lab2LCh.c index 2f34238089..42b43ae7d0 100644 --- a/libvips/colour/Lab2LCh.c +++ b/libvips/colour/Lab2LCh.c @@ -146,7 +146,7 @@ vips_Lab2LCh_init(VipsLab2LCh *Lab2LCh) * vips_Lab2LCh: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn Lab to LCh. * diff --git a/libvips/colour/Lab2LabQ.c b/libvips/colour/Lab2LabQ.c index 429bf4c160..16694c20ab 100644 --- a/libvips/colour/Lab2LabQ.c +++ b/libvips/colour/Lab2LabQ.c @@ -159,7 +159,7 @@ vips_Lab2LabQ_init(VipsLab2LabQ *Lab2LabQ) * vips_Lab2LabQ: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert a Lab three-band float image to LabQ ([enum@Vips.Coding.LABQ]). * diff --git a/libvips/colour/Lab2LabS.c b/libvips/colour/Lab2LabS.c index 46ff14701b..4f1d99d785 100644 --- a/libvips/colour/Lab2LabS.c +++ b/libvips/colour/Lab2LabS.c @@ -103,7 +103,7 @@ vips_Lab2LabS_init(VipsLab2LabS *Lab2LabS) * vips_Lab2LabS: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn Lab to LabS, signed 16-bit int fixed point. * diff --git a/libvips/colour/Lab2XYZ.c b/libvips/colour/Lab2XYZ.c index 973fc94812..a9c374a047 100644 --- a/libvips/colour/Lab2XYZ.c +++ b/libvips/colour/Lab2XYZ.c @@ -203,7 +203,7 @@ vips_Lab2XYZ_init(VipsLab2XYZ *Lab2XYZ) * vips_Lab2XYZ: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn Lab to XYZ. The colour temperature defaults to D65, but can be * specified with @temp. diff --git a/libvips/colour/LabQ2Lab.c b/libvips/colour/LabQ2Lab.c index 8110325b74..50dee85ca6 100644 --- a/libvips/colour/LabQ2Lab.c +++ b/libvips/colour/LabQ2Lab.c @@ -145,7 +145,7 @@ vips_LabQ2Lab_init(VipsLabQ2Lab *LabQ2Lab) * vips_LabQ2Lab: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Unpack a LabQ ([enum@Vips.Coding.LABQ]) image to a three-band float image. * diff --git a/libvips/colour/LabQ2LabS.c b/libvips/colour/LabQ2LabS.c index c146ebca70..b2e604de7e 100644 --- a/libvips/colour/LabQ2LabS.c +++ b/libvips/colour/LabQ2LabS.c @@ -124,7 +124,7 @@ vips_LabQ2LabS_init(VipsLabQ2LabS *LabQ2LabS) * vips_LabQ2LabS: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Unpack a LabQ ([enum@Vips.Coding.LABQ]) image to a three-band short image. * diff --git a/libvips/colour/LabQ2sRGB.c b/libvips/colour/LabQ2sRGB.c index bcd06459a3..a09cb15521 100644 --- a/libvips/colour/LabQ2sRGB.c +++ b/libvips/colour/LabQ2sRGB.c @@ -571,7 +571,7 @@ vips_LabQ2sRGB_init(VipsLabQ2sRGB *LabQ2sRGB) * vips_LabQ2sRGB: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Unpack a LabQ ([enum@Vips.Coding.LABQ]) image to a three-band short image. * diff --git a/libvips/colour/LabS2Lab.c b/libvips/colour/LabS2Lab.c index 0f37529d89..8aeae9be52 100644 --- a/libvips/colour/LabS2Lab.c +++ b/libvips/colour/LabS2Lab.c @@ -99,7 +99,7 @@ vips_LabS2Lab_init(VipsLabS2Lab *LabS2Lab) * vips_LabS2Lab: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert a LabS three-band signed short image to a three-band float image. * diff --git a/libvips/colour/LabS2LabQ.c b/libvips/colour/LabS2LabQ.c index 9be79149d4..89f90834ba 100644 --- a/libvips/colour/LabS2LabQ.c +++ b/libvips/colour/LabS2LabQ.c @@ -149,7 +149,7 @@ vips_LabS2LabQ_init(VipsLabS2LabQ *LabS2LabQ) * vips_LabS2LabQ: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert a LabS three-band signed short image to LabQ * diff --git a/libvips/colour/UCS2LCh.c b/libvips/colour/UCS2LCh.c index 1649129fc9..6ec874c33f 100644 --- a/libvips/colour/UCS2LCh.c +++ b/libvips/colour/UCS2LCh.c @@ -288,7 +288,7 @@ vips_CMC2LCh_init(VipsCMC2LCh *CMC2LCh) * vips_CMC2LCh: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn LCh to CMC. * diff --git a/libvips/colour/XYZ2CMYK.c b/libvips/colour/XYZ2CMYK.c index a3a22fb42e..08ab51bfc8 100644 --- a/libvips/colour/XYZ2CMYK.c +++ b/libvips/colour/XYZ2CMYK.c @@ -217,7 +217,7 @@ vips_XYZ2CMYK_init(VipsXYZ2CMYK *XYZ2CMYK) * vips_XYZ2CMYK: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn XYZ to CMYK. * diff --git a/libvips/colour/XYZ2Lab.c b/libvips/colour/XYZ2Lab.c index 9f86425da3..7f27809124 100644 --- a/libvips/colour/XYZ2Lab.c +++ b/libvips/colour/XYZ2Lab.c @@ -257,7 +257,7 @@ vips_XYZ2Lab_init(VipsXYZ2Lab *XYZ2Lab) * vips_XYZ2Lab: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn XYZ to Lab, optionally specifying the colour temperature. @temp * defaults to D65. diff --git a/libvips/colour/XYZ2Yxy.c b/libvips/colour/XYZ2Yxy.c index ffc30c3b87..793680d650 100644 --- a/libvips/colour/XYZ2Yxy.c +++ b/libvips/colour/XYZ2Yxy.c @@ -112,7 +112,7 @@ vips_XYZ2Yxy_init(VipsXYZ2Yxy *XYZ2Yxy) * vips_XYZ2Yxy: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn XYZ to Yxy. * diff --git a/libvips/colour/XYZ2scRGB.c b/libvips/colour/XYZ2scRGB.c index a882d85747..0dfbc17f7d 100644 --- a/libvips/colour/XYZ2scRGB.c +++ b/libvips/colour/XYZ2scRGB.c @@ -117,7 +117,7 @@ vips_XYZ2scRGB_init(VipsXYZ2scRGB *XYZ2scRGB) * vips_XYZ2scRGB: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn XYZ to scRGB. * diff --git a/libvips/colour/Yxy2XYZ.c b/libvips/colour/Yxy2XYZ.c index 2584a8a00c..480f6997c7 100644 --- a/libvips/colour/Yxy2XYZ.c +++ b/libvips/colour/Yxy2XYZ.c @@ -117,7 +117,7 @@ vips_Yxy2XYZ_init(VipsYxy2XYZ *Yxy2XYZ) * vips_Yxy2XYZ: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn XYZ to Yxy. * diff --git a/libvips/colour/colourspace.c b/libvips/colour/colourspace.c index 4c6c3589ec..850bad52a7 100644 --- a/libvips/colour/colourspace.c +++ b/libvips/colour/colourspace.c @@ -426,7 +426,7 @@ static VipsColourRoute vips_colour_routes[] = { * * Test if @image is in a colourspace that [method@Image.colourspace] can process. * - * Returns: %TRUE if @image is in a supported colourspace. + * Returns: `TRUE` if @image is in a supported colourspace. */ gboolean vips_colourspace_issupported(const VipsImage *image) @@ -591,7 +591,7 @@ vips_colourspace_init(VipsColourspace *colourspace) * @in: input image * @out: (out): output image * @space: convert to this colour space - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation looks at the interpretation field of @in (or uses * @source_space, if set) and runs diff --git a/libvips/colour/dE00.c b/libvips/colour/dE00.c index e5a8d5ba4a..4944680476 100644 --- a/libvips/colour/dE00.c +++ b/libvips/colour/dE00.c @@ -251,7 +251,7 @@ vips_dE00_init(VipsdE00 *dE00) * @left: first input image * @right: second input image * @out: output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Calculate dE 00. * diff --git a/libvips/colour/dE76.c b/libvips/colour/dE76.c index b7c85d305c..f70f2a0bf8 100644 --- a/libvips/colour/dE76.c +++ b/libvips/colour/dE76.c @@ -128,7 +128,7 @@ vips_dE76_init(VipsdE76 *dE76) * @left: first input image * @right: second input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Calculate dE 76. * diff --git a/libvips/colour/dECMC.c b/libvips/colour/dECMC.c index ea1ac082ce..fe4e422bbc 100644 --- a/libvips/colour/dECMC.c +++ b/libvips/colour/dECMC.c @@ -76,7 +76,7 @@ vips_dECMC_init(VipsdECMC *dECMC) * @left: first input image * @right: second input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Calculate dE CMC. The input images are transformed to CMC colour space and * the euclidean distance between corresponding pixels calculated. diff --git a/libvips/colour/float2rad.c b/libvips/colour/float2rad.c index dd62579c83..22f8e3bbf5 100644 --- a/libvips/colour/float2rad.c +++ b/libvips/colour/float2rad.c @@ -228,7 +228,7 @@ vips_float2rad_init(VipsFloat2rad *float2rad) * vips_float2rad: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert a three-band float image to Radiance 32-bit packed format. * diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index 28922d5d8b..b3a61d5c7b 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -108,8 +108,8 @@ * @VIPS_INTENT_ABSOLUTE: absolute colorimetric rendering intent * @VIPS_INTENT_AUTO: the rendering intent that the profile suggests * - * The rendering intent. #VIPS_INTENT_ABSOLUTE is best for - * scientific work, #VIPS_INTENT_RELATIVE is usually best for + * The rendering intent. [enum@Vips.Intent.ABSOLUTE] is best for + * scientific work, [enum@Vips.Intent.RELATIVE] is usually best for * accurate communication with other imaging libraries. */ @@ -1438,7 +1438,7 @@ vips_icc_is_compatible_profile(VipsImage *image, * vips_icc_import: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Import an image from device space to D65 LAB with an ICC profile. * @@ -1448,8 +1448,8 @@ vips_icc_is_compatible_profile(VipsImage *image, * * 1. If @embedded is set, libvips will try to use any profile in the input * image metadata. You can test for the presence of an embedded profile - * with [method@Image.get_typeof] with #VIPS_META_ICC_NAME as an - * argument. This will return %GType 0 if there is no profile. + * with [method@Image.get_typeof] with [const@META_ICC_NAME] as an + * argument. This will return [alias@GObject.Type] 0 if there is no profile. * * 2. Otherwise, if @input_profile is set, libvips will try to load a * profile from the named file. This can also be the name of one of the @@ -1464,9 +1464,9 @@ vips_icc_is_compatible_profile(VipsImage *image, * ::: tip "Optional arguments" * * @pcs: [enum@PCS], use XYZ or LAB PCS * * @intent: [enum@Intent], transform with this intent - * * @black_point_compensation: %gboolean, enable black point compensation - * * @embedded: %gboolean, use profile embedded in input image - * * @input_profile: %gchararray, get the input profile from here + * * @black_point_compensation: `gboolean`, enable black point compensation + * * @embedded: `gboolean`, use profile embedded in input image + * * @input_profile: `gchararray`, get the input profile from here * * Returns: 0 on success, -1 on error. */ @@ -1487,7 +1487,7 @@ vips_icc_import(VipsImage *in, VipsImage **out, ...) * vips_icc_export: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Export an image from D65 LAB to device space with an ICC profile. * @@ -1502,9 +1502,9 @@ vips_icc_import(VipsImage *in, VipsImage **out, ...) * ::: tip "Optional arguments" * * @pcs: [enum@PCS], use XYZ or LAB PCS * * @intent: [enum@Intent], transform with this intent - * * @black_point_compensation: %gboolean, enable black point compensation - * * @output_profile: %gchararray, get the output profile from here - * * @depth: %gint, depth of output image in bits + * * @black_point_compensation: `gboolean`, enable black point compensation + * * @output_profile: `gchararray`, get the output profile from here + * * @depth: `gint`, depth of output image in bits * * Returns: 0 on success, -1 on error. */ @@ -1526,7 +1526,7 @@ vips_icc_export(VipsImage *in, VipsImage **out, ...) * @in: input image * @out: (out): output image * @output_profile: get the output profile from here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Transform an image with a pair of ICC profiles. * @@ -1537,8 +1537,8 @@ vips_icc_export(VipsImage *in, VipsImage **out, ...) * * 1. If @embedded is set, libvips will try to use any profile in the input * image metadata. You can test for the presence of an embedded profile - * with [method@Image.get_typeof] with #VIPS_META_ICC_NAME as an - * argument. This will return %GType 0 if there is no profile. + * with [method@Image.get_typeof] with [const@META_ICC_NAME] as an + * argument. This will return [alias@GObject.Type] 0 if there is no profile. * * 2. Otherwise, if @input_profile is set, libvips will try to load a * profile from the named file. This can also be the name of one of the @@ -1552,7 +1552,7 @@ vips_icc_export(VipsImage *in, VipsImage **out, ...) * * @depth defaults to 8, or 16 if @in is a 16-bit image. * - * The output image has the output profile attached to the #VIPS_META_ICC_NAME + * The output image has the output profile attached to the [const@META_ICC_NAME] * field. * * Use [method@Image.icc_import] and [method@Image.icc_export] to do either @@ -1561,10 +1561,10 @@ vips_icc_export(VipsImage *in, VipsImage **out, ...) * ::: tip "Optional arguments" * * @pcs: [enum@PCS], use XYZ or LAB PCS * * @intent: [enum@Intent], transform with this intent - * * @black_point_compensation: %gboolean, enable black point compensation - * * @embedded: %gboolean, use profile embedded in input image - * * @input_profile: %gchararray, get the input profile from here - * * @depth: %gint, depth of output image in bits + * * @black_point_compensation: `gboolean`, enable black point compensation + * * @embedded: `gboolean`, use profile embedded in input image + * * @input_profile: `gchararray`, get the input profile from here + * * @depth: `gint`, depth of output image in bits * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/colour/profile_load.c b/libvips/colour/profile_load.c index 3fa18f4ec2..e3e7090f71 100644 --- a/libvips/colour/profile_load.c +++ b/libvips/colour/profile_load.c @@ -171,13 +171,13 @@ vips_profile_load_init(VipsProfileLoad *load) * vips_profile_load: * @name: name of profile to load * @profile: (out): loaded profile - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Load a named profile. * * Profiles are loaded from four sources: * - * - The special name `"none"` means no profile. @profile will be %NULL in this + * - The special name `"none"` means no profile. @profile will be `NULL` in this * case. * * - @name can be the name of one of the ICC profiles embedded in libvips. diff --git a/libvips/colour/rad2float.c b/libvips/colour/rad2float.c index ede326f414..3a0c7624d5 100644 --- a/libvips/colour/rad2float.c +++ b/libvips/colour/rad2float.c @@ -204,7 +204,7 @@ vips_rad2float_init(VipsRad2float *rad2float) * vips_rad2float: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Unpack a RAD ([enum@Vips.Coding.RAD]) image to a three-band float image. * diff --git a/libvips/colour/sRGB2HSV.c b/libvips/colour/sRGB2HSV.c index 6e764d29a9..e1a6194f45 100644 --- a/libvips/colour/sRGB2HSV.c +++ b/libvips/colour/sRGB2HSV.c @@ -155,7 +155,7 @@ vips_sRGB2HSV_init(VipssRGB2HSV *sRGB2HSV) * vips_sRGB2HSV: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert to HSV. * diff --git a/libvips/colour/sRGB2scRGB.c b/libvips/colour/sRGB2scRGB.c index 0c18247a16..7d668d833f 100644 --- a/libvips/colour/sRGB2scRGB.c +++ b/libvips/colour/sRGB2scRGB.c @@ -152,7 +152,7 @@ vips_sRGB2scRGB_init(VipssRGB2scRGB *sRGB2scRGB) * vips_sRGB2scRGB: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert an sRGB image to scRGB. * diff --git a/libvips/colour/scRGB2BW.c b/libvips/colour/scRGB2BW.c index 49eb52e411..2f108d9fc2 100644 --- a/libvips/colour/scRGB2BW.c +++ b/libvips/colour/scRGB2BW.c @@ -174,7 +174,7 @@ vips_scRGB2BW_init(VipsscRGB2BW *scRGB2BW) * vips_scRGB2BW: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert an scRGB image to greyscale. Set @depth to 16 to get 16-bit output. * diff --git a/libvips/colour/scRGB2XYZ.c b/libvips/colour/scRGB2XYZ.c index 2bcd6a2091..61ca9db732 100644 --- a/libvips/colour/scRGB2XYZ.c +++ b/libvips/colour/scRGB2XYZ.c @@ -102,7 +102,7 @@ vips_scRGB2XYZ_init(VipsscRGB2XYZ *scRGB2XYZ) * vips_scRGB2XYZ: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn XYZ to scRGB. * diff --git a/libvips/colour/scRGB2sRGB.c b/libvips/colour/scRGB2sRGB.c index efcf25fb61..92d17ec376 100644 --- a/libvips/colour/scRGB2sRGB.c +++ b/libvips/colour/scRGB2sRGB.c @@ -201,7 +201,7 @@ vips_scRGB2sRGB_init(VipsscRGB2sRGB *scRGB2sRGB) * vips_scRGB2sRGB: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert an scRGB image to sRGB. Set @depth to 16 to get 16-bit output. * diff --git a/libvips/conversion/addalpha.c b/libvips/conversion/addalpha.c index 6e11b2662a..2025782ca1 100644 --- a/libvips/conversion/addalpha.c +++ b/libvips/conversion/addalpha.c @@ -102,7 +102,7 @@ vips_addalpha_init(VipsAddAlpha *addalpha) * vips_addalpha: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Append an alpha channel. * diff --git a/libvips/conversion/arrayjoin.c b/libvips/conversion/arrayjoin.c index e6139b8836..90081e4d5b 100644 --- a/libvips/conversion/arrayjoin.c +++ b/libvips/conversion/arrayjoin.c @@ -473,7 +473,7 @@ vips_arrayjoinv(VipsImage **in, VipsImage **out, int n, va_list ap) * @in: (array length=n) (transfer none): array of input images * @out: (out): output image * @n: number of input images - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Lay out the images in @in in a grid. The grid is @across images across and * however high is necessary to use up all of @in. Images are set down @@ -505,13 +505,13 @@ vips_arrayjoinv(VipsImage **in, VipsImage **out, int n, va_list ap) * colourspace for compositing. * * ::: tip "Optional arguments" - * * @across: %gint, number of images per row - * * @shim: %gint, space between images, in pixels + * * @across: `gint`, number of images per row + * * @shim: `gint`, space between images, in pixels * * @background: [struct@ArrayDouble], background ink colour * * @halign: [enum@Align], low, centre or high alignment * * @valign: [enum@Align], low, centre or high alignment - * * @hspacing: %gint, horizontal distance between images - * * @vspacing: %gint, vertical distance between images + * * @hspacing: `gint`, horizontal distance between images + * * @vspacing: `gint`, vertical distance between images * * ::: seealso * [method@Image.join], [method@Image.insert], [method@Image.colourspace]. diff --git a/libvips/conversion/autorot.c b/libvips/conversion/autorot.c index f83be2d743..f4f589d34b 100644 --- a/libvips/conversion/autorot.c +++ b/libvips/conversion/autorot.c @@ -235,10 +235,10 @@ vips_autorot_init(VipsAutorot *autorot) * vips_autorot: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Look at the image metadata and rotate and flip the image to make it - * upright. The #VIPS_META_ORIENTATION tag is removed from @out to prevent + * upright. The [const@META_ORIENTATION] tag is removed from @out to prevent * accidental double rotation. * * Read @angle to find the amount the image was rotated by. Read @flip to @@ -246,7 +246,7 @@ vips_autorot_init(VipsAutorot *autorot) * * ::: tip "Optional arguments" * * @angle: output [enum@Angle] the image was rotated by - * * @flip: output %gboolean whether the image was flipped + * * @flip: output `gboolean` whether the image was flipped * * Returns: 0 on success, -1 on error */ diff --git a/libvips/conversion/bandbool.c b/libvips/conversion/bandbool.c index 2709818891..07592cc268 100644 --- a/libvips/conversion/bandbool.c +++ b/libvips/conversion/bandbool.c @@ -261,7 +261,7 @@ vips_bandboolv(VipsImage *in, VipsImage **out, * @in: left-hand input [class@Image] * @out: (out): output [class@Image] * @boolean: boolean operation to perform - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform various boolean operations across the bands of an image. For * example, a three-band uchar image operated on with @@ -301,7 +301,7 @@ vips_bandbool(VipsImage *in, VipsImage **out, * vips_bandand: (method) * @in: left-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.AND] on an image. See * [method@Image.bandbool]. @@ -325,7 +325,7 @@ vips_bandand(VipsImage *in, VipsImage **out, ...) * vips_bandor: (method) * @in: left-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.OR] on an image. See * [method@Image.bandbool]. @@ -349,7 +349,7 @@ vips_bandor(VipsImage *in, VipsImage **out, ...) * vips_bandeor: (method) * @in: left-hand input [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform [enum@Vips.OperationBoolean.EOR] on an image. See * [method@Image.bandbool]. diff --git a/libvips/conversion/bandfold.c b/libvips/conversion/bandfold.c index 7de838af8e..7bd659b935 100644 --- a/libvips/conversion/bandfold.c +++ b/libvips/conversion/bandfold.c @@ -183,7 +183,7 @@ vips_bandfold_init(VipsBandfold *bandfold) * vips_bandfold: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Fold up an image horizontally: width is collapsed into bands. * Use @factor to set how much to fold by: @factor 3, for example, will make @@ -191,7 +191,7 @@ vips_bandfold_init(VipsBandfold *bandfold) * as many bands. By default the whole of the input width is folded up. * * ::: tip "Optional arguments" - * * @factor: %gint, fold by this factor + * * @factor: `gint`, fold by this factor * * ::: seealso * [ctor@Image.csvload], [method@Image.bandunfold]. diff --git a/libvips/conversion/bandjoin.c b/libvips/conversion/bandjoin.c index eee8f97b67..099397131b 100644 --- a/libvips/conversion/bandjoin.c +++ b/libvips/conversion/bandjoin.c @@ -230,7 +230,7 @@ vips_bandjoinv(VipsImage **in, VipsImage **out, int n, va_list ap) * @in: (array length=n) (transfer none): array of input images * @out: (out): output image * @n: number of input images - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Join a set of images together, bandwise. * @@ -269,7 +269,7 @@ vips_bandjoin(VipsImage **in, VipsImage **out, int n, ...) * @in1: first input image * @in2: second input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Join a pair of images together, bandwise. See [func@Image.bandjoin]. * @@ -474,7 +474,7 @@ vips_bandjoin_constv(VipsImage *in, VipsImage **out, * @out: (out): output image * @c: (array length=n): array of constants to append * @n: number of constants - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Append a set of constant bands to an image. * @@ -501,7 +501,7 @@ vips_bandjoin_const(VipsImage *in, VipsImage **out, double *c, int n, ...) * @in: input image * @out: (out): output image * @c: constant to append - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Append a single constant band to an image. * diff --git a/libvips/conversion/bandmean.c b/libvips/conversion/bandmean.c index c5448a865f..535f89ffb1 100644 --- a/libvips/conversion/bandmean.c +++ b/libvips/conversion/bandmean.c @@ -224,7 +224,7 @@ vips_bandmean_init(VipsBandmean *bandmean) * vips_bandmean: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation writes a one-band image where each pixel is the average of * the bands for that pixel in the input image. The output band format is diff --git a/libvips/conversion/bandrank.c b/libvips/conversion/bandrank.c index 9b6c9550c7..41b7b5ec46 100644 --- a/libvips/conversion/bandrank.c +++ b/libvips/conversion/bandrank.c @@ -291,7 +291,7 @@ vips_bandrankv(VipsImage **in, VipsImage **out, int n, va_list ap) * @in: (array length=n): array of input images * @out: (out): output image * @n: number of input images - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Sorts the images @in band-element-wise, then outputs an * image in which each band element is selected from the sorted list by the @@ -311,7 +311,7 @@ vips_bandrankv(VipsImage **in, VipsImage **out, int n, va_list ap) * Smaller input images are expanded by adding black pixels. * * ::: tip "Optional arguments" - * * @index: %gint, pick this index from list of sorted values + * * @index: `gint`, pick this index from list of sorted values * * ::: seealso * [method@Image.rank]. diff --git a/libvips/conversion/bandunfold.c b/libvips/conversion/bandunfold.c index 466bc96cc2..56928e6811 100644 --- a/libvips/conversion/bandunfold.c +++ b/libvips/conversion/bandunfold.c @@ -186,7 +186,7 @@ vips_bandunfold_init(VipsBandunfold *bandunfold) * vips_bandunfold: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Unfold image bands into x axis. * Use @factor to set how much to unfold by: @factor 3, for example, will make diff --git a/libvips/conversion/byteswap.c b/libvips/conversion/byteswap.c index 802e11d5e8..b5f65ab3ba 100644 --- a/libvips/conversion/byteswap.c +++ b/libvips/conversion/byteswap.c @@ -250,7 +250,7 @@ vips_byteswap_init(VipsByteswap *byteswap) * vips_byteswap: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Swap the byte order in an image. * @@ -272,7 +272,7 @@ vips_byteswap(VipsImage *in, VipsImage **out, ...) return result; } -/* Convenience function: swap if @swap is %TRUE, otherwise copy. +/* Convenience function: swap if @swap is `TRUE`, otherwise copy. */ int vips__byteswap_bool(VipsImage *in, VipsImage **out, gboolean swap) diff --git a/libvips/conversion/cache.c b/libvips/conversion/cache.c index 1a1190502e..ab56de929f 100644 --- a/libvips/conversion/cache.c +++ b/libvips/conversion/cache.c @@ -146,7 +146,7 @@ vips_cache_init(VipsCache *cache) * vips_cache: * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation behaves rather like [method@Image.copy] between images * @in and @out, except that it keeps a cache of computed pixels. diff --git a/libvips/conversion/cast.c b/libvips/conversion/cast.c index 7fbf307b69..e362d343d0 100644 --- a/libvips/conversion/cast.c +++ b/libvips/conversion/cast.c @@ -562,20 +562,20 @@ vips_castv(VipsImage *in, VipsImage **out, VipsBandFormat format, va_list ap) * @in: input image * @out: (out): output image * @format: format to convert to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert @in to @format. You can convert between any pair of formats. * Floats are truncated (not rounded). Out of range values are clipped. * * Casting from complex to real returns the real part. * - * If @shift is %TRUE, integer values are shifted up and down. For example, + * If @shift is `TRUE`, integer values are shifted up and down. For example, * casting from unsigned 8 bit to unsigned 16 bit would * shift every value left by 8 bits. The bottom bit is copied into the new * bits, so 255 would become 65535. * * ::: tip "Optional arguments" - * * @shift: %gboolean, integer values are shifted + * * @shift: `gboolean`, integer values are shifted * * ::: seealso * [method@Image.scale], [method@Image.complexform], [method@Image.real], @@ -600,12 +600,12 @@ vips_cast(VipsImage *in, VipsImage **out, VipsBandFormat format, ...) * vips_cast_uchar: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert @in to [enum@Vips.BandFormat.UCHAR]. See [method@Image.cast]. * * ::: tip "Optional arguments" - * * @shift: %gboolean, integer values are shifted + * * @shift: `gboolean`, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -626,12 +626,12 @@ vips_cast_uchar(VipsImage *in, VipsImage **out, ...) * vips_cast_char: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert @in to [enum@Vips.BandFormat.CHAR]. See [method@Image.cast]. * * ::: tip "Optional arguments" - * * @shift: %gboolean, integer values are shifted + * * @shift: `gboolean`, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -652,12 +652,12 @@ vips_cast_char(VipsImage *in, VipsImage **out, ...) * vips_cast_ushort: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert @in to [enum@Vips.BandFormat.USHORT]. See [method@Image.cast]. * * ::: tip "Optional arguments" - * * @shift: %gboolean, integer values are shifted + * * @shift: `gboolean`, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -678,12 +678,12 @@ vips_cast_ushort(VipsImage *in, VipsImage **out, ...) * vips_cast_short: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert @in to [enum@Vips.BandFormat.SHORT]. See [method@Image.cast]. * * ::: tip "Optional arguments" - * * @shift: %gboolean, integer values are shifted + * * @shift: `gboolean`, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -704,12 +704,12 @@ vips_cast_short(VipsImage *in, VipsImage **out, ...) * vips_cast_uint: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert @in to [enum@Vips.BandFormat.UINT]. See [method@Image.cast]. * * ::: tip "Optional arguments" - * * @shift: %gboolean, integer values are shifted + * * @shift: `gboolean`, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -730,12 +730,12 @@ vips_cast_uint(VipsImage *in, VipsImage **out, ...) * vips_cast_int: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert @in to [enum@Vips.BandFormat.INT]. See [method@Image.cast]. * * ::: tip "Optional arguments" - * * @shift: %gboolean, integer values are shifted + * * @shift: `gboolean`, integer values are shifted * * Returns: 0 on success, -1 on error */ @@ -756,7 +756,7 @@ vips_cast_int(VipsImage *in, VipsImage **out, ...) * vips_cast_float: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert @in to [enum@Vips.BandFormat.FLOAT]. See [method@Image.cast]. * @@ -779,7 +779,7 @@ vips_cast_float(VipsImage *in, VipsImage **out, ...) * vips_cast_double: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert @in to [enum@Vips.BandFormat.DOUBLE]. See [method@Image.cast]. * @@ -802,7 +802,7 @@ vips_cast_double(VipsImage *in, VipsImage **out, ...) * vips_cast_complex: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert @in to [enum@Vips.BandFormat.COMPLEX]. See [method@Image.cast]. * @@ -825,7 +825,7 @@ vips_cast_complex(VipsImage *in, VipsImage **out, ...) * vips_cast_dpcomplex: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert @in to [enum@Vips.BandFormat.DPCOMPLEX]. See [method@Image.cast]. * diff --git a/libvips/conversion/conversion.c b/libvips/conversion/conversion.c index bffd426ae4..72b6d9d885 100644 --- a/libvips/conversion/conversion.c +++ b/libvips/conversion/conversion.c @@ -54,14 +54,14 @@ * @in: (array length=n) (transfer none): array of input images * @out: (out): output image * @n: number of input images - * @mode: array of (@n - 1) #VipsBlendMode - * @...: %NULL-terminated list of optional named arguments + * @mode: array of (@n - 1) [enum@BlendMode] + * @...: `NULL`-terminated list of optional named arguments * * Composite an array of images together. * * Images are placed in a stack, with @in[0] at the bottom and @in[@n - 1] at * the top. Pixels are blended together working from the bottom upwards, with - * the blend mode at each step being set by the corresponding #VipsBlendMode + * the blend mode at each step being set by the corresponding [enum@BlendMode] * in @mode. * * Images are transformed to a compositing space before processing. This is @@ -93,7 +93,7 @@ * * ::: tip "Optional arguments" * * @compositing_space: [enum@Interpretation] to composite in - * * @premultiplied: %gboolean, images are already premultiplied + * * @premultiplied: `gboolean`, images are already premultiplied * * @x: [struct@ArrayInt], array of (@n - 1) x coordinates * * @y: [struct@ArrayInt], array of (@n - 1) y coordinates * @@ -109,15 +109,15 @@ * @overlay: second input image * @out: (out): output image * @mode: composite with this blend mode - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Composite @overlay on top of @base with @mode. See [func@Image.composite]. * * ::: tip "Optional arguments" * * @compositing_space: [enum@Interpretation] to composite in - * * @premultiplied: %gboolean, images are already premultiplied - * * @x: %gint, position of overlay - * * @y: %gint, position of overlay + * * @premultiplied: `gboolean`, images are already premultiplied + * * @x: `gint`, position of overlay + * * @y: `gint`, position of overlay * * Returns: 0 on success, -1 on error */ @@ -204,8 +204,8 @@ * by [method@Image.smartcrop], for example, to decide what parts of the image to * keep. * - * #VIPS_INTERESTING_NONE and #VIPS_INTERESTING_LOW mean the same -- the - * crop is positioned at the top or left. #VIPS_INTERESTING_HIGH positions at + * [enum@Vips.Interesting.NONE] and [enum@Vips.Interesting.LOW] mean the same -- the + * crop is positioned at the top or left. [enum@Vips.Interesting.HIGH] positions at * the bottom or right. * * ::: seealso @@ -260,19 +260,19 @@ * When the edges of an image are extended, you can specify * how you want the extension done. * - * #VIPS_EXTEND_BLACK --- new pixels are black, ie. all bits are zero. + * [enum@Vips.Extend.BLACK] --- new pixels are black, ie. all bits are zero. * - * #VIPS_EXTEND_COPY --- each new pixel takes the value of the nearest edge + * [enum@Vips.Extend.COPY] --- each new pixel takes the value of the nearest edge * pixel * - * #VIPS_EXTEND_REPEAT --- the image is tiled to fill the new area + * [enum@Vips.Extend.REPEAT] --- the image is tiled to fill the new area * - * #VIPS_EXTEND_MIRROR --- the image is reflected and tiled to reduce hash + * [enum@Vips.Extend.MIRROR] --- the image is reflected and tiled to reduce hash * edges * - * #VIPS_EXTEND_WHITE --- new pixels are white, ie. all bits are set + * [enum@Vips.Extend.WHITE] --- new pixels are white, ie. all bits are set * - * #VIPS_EXTEND_BACKGROUND --- colour set from the @background property + * [enum@Vips.Extend.BACKGROUND] --- colour set from the @background property * * We have to specify the exact value of each enum member since we have to * keep these frozen for back compat with vips7. diff --git a/libvips/conversion/copy.c b/libvips/conversion/copy.c index 40174bab57..2191546aa8 100644 --- a/libvips/conversion/copy.c +++ b/libvips/conversion/copy.c @@ -362,7 +362,7 @@ vips_copy_init(VipsCopy *copy) * vips_copy: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Copy an image, optionally modifying the header. VIPS copies images by * copying pointers, so this operation is instant, even for very large images. @@ -373,16 +373,16 @@ vips_copy_init(VipsCopy *copy) * cannot change a 100 x 100 RGB image into a 300 x 100 mono image. * * ::: tip "Optional arguments" - * * @width: %gint, set image width - * * @height: %gint, set image height - * * @bands: %gint, set image bands + * * @width: `gint`, set image width + * * @height: `gint`, set image height + * * @bands: `gint`, set image bands * * @format: [enum@BandFormat], set image format * * @coding: [enum@Coding], set image coding * * @interpretation: [enum@Interpretation], set image interpretation - * * @xres: %gdouble, set image xres - * * @yres: %gdouble, set image yres - * * @xoffset: %gint, set image xoffset - * * @yoffset: %gint, set image yoffset + * * @xres: `gdouble`, set image xres + * * @yres: `gdouble`, set image yres + * * @xoffset: `gint`, set image xoffset + * * @yoffset: `gint`, set image yoffset * * ::: seealso * [method@Image.byteswap], [method@Image.bandfold], @@ -407,7 +407,7 @@ vips_copy(VipsImage *in, VipsImage **out, ...) * vips_copy_file: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * A simple convenience function to copy an image to a file, then copy * again to output. If the image is already a file, just copy straight diff --git a/libvips/conversion/embed.c b/libvips/conversion/embed.c index a33c6b08bb..3620ebb51b 100644 --- a/libvips/conversion/embed.c +++ b/libvips/conversion/embed.c @@ -680,7 +680,7 @@ vips_embed_init(VipsEmbed *embed) * @y: place @in at this y position in @out * @width: @out should be this many pixels across * @height: @out should be this many pixels down - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * The opposite of [method@Image.extract_area]: embed @in within an image of * size @width by @height at position @x, @y. @@ -688,7 +688,7 @@ vips_embed_init(VipsEmbed *embed) * @extend controls what appears in the new pels, see [enum@Extend]. * * ::: tip "Optional arguments" - * * @extend: [enum@Extend] to generate the edge pixels (default: black) + * * @extend: [enum@Extend] to generate the edge pixels (default: [enum@Vips.Extend.BLACK]) * * @background: [struct@ArrayDouble] colour for edge pixels * * ::: seealso @@ -827,15 +827,15 @@ vips_gravity_init(VipsGravity *gravity) * @direction: place @in at this direction in @out * @width: @out should be this many pixels across * @height: @out should be this many pixels down - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * The opposite of [method@Image.extract_area]: place @in within an image of * size @width by @height at a certain gravity. * - * @extend controls what appears in the new pels, see #VipsExtend. + * @extend controls what appears in the new pels, see [enum@Extend]. * * ::: tip "Optional arguments" - * * @extend: #VipsExtend to generate the edge pixels (default: black) + * * @extend: [enum@Extend] to generate the edge pixels (default: [enum@Vips.Extend.BLACK]) * * @background: [struct@ArrayDouble] colour for edge pixels * * ::: seealso diff --git a/libvips/conversion/extract.c b/libvips/conversion/extract.c index 407c831bb7..1307d27aa9 100644 --- a/libvips/conversion/extract.c +++ b/libvips/conversion/extract.c @@ -246,7 +246,7 @@ vips_extract_area_init(VipsExtractArea *extract) * @top: top edge of area to extract * @width: width of area to extract * @height: height of area to extract - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Extract an area from an image. The area must fit within @in. * @@ -305,7 +305,7 @@ vips_crop_get_type(void) * @top: top edge of area to extract * @width: width of area to extract * @height: height of area to extract - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * A synonym for [method@Image.extract_area]. * @@ -462,14 +462,14 @@ vips_extract_band_init(VipsExtractBand *extract) * @in: input image * @out: (out): output image * @band: index of first band to extract - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Extract a band or bands from an image. Extracting out of range is an error. * * @n defaults to 1. * * ::: tip "Optional arguments" - * * @n: %gint, number of bands to extract + * * @n: `gint`, number of bands to extract * * ::: seealso * [method@Image.extract_area]. diff --git a/libvips/conversion/falsecolour.c b/libvips/conversion/falsecolour.c index 0e9f62b2f6..dfed8f85d8 100644 --- a/libvips/conversion/falsecolour.c +++ b/libvips/conversion/falsecolour.c @@ -392,7 +392,7 @@ vips_falsecolour_init(VipsFalsecolour *falsecolour) * vips_falsecolour: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Force @in to 1 band, 8-bit, then transform to * a 3-band 8-bit image with a false colour diff --git a/libvips/conversion/flatten.c b/libvips/conversion/flatten.c index 9a753ab7e2..de6a7e9353 100644 --- a/libvips/conversion/flatten.c +++ b/libvips/conversion/flatten.c @@ -444,7 +444,7 @@ vips_flatten_init(VipsFlatten *flatten) * vips_flatten: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Take the last band of @in as an alpha and use it to blend the * remaining channels with @background. @@ -461,7 +461,7 @@ vips_flatten_init(VipsFlatten *flatten) * * ::: tip "Optional arguments" * * @background: [struct@ArrayDouble] colour for new pixels - * * @max_alpha: %gdouble, maximum value for alpha + * * @max_alpha: `gdouble`, maximum value for alpha * * ::: seealso * [method@Image.premultiply], [ctor@Image.pngload]. diff --git a/libvips/conversion/flip.c b/libvips/conversion/flip.c index 152b07af26..3cd160dd16 100644 --- a/libvips/conversion/flip.c +++ b/libvips/conversion/flip.c @@ -260,7 +260,7 @@ vips_flip_init(VipsFlip *flip) * @in: input image * @out: (out): output image * @direction: flip horizontally or vertically - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Flips an image left-right or up-down. * diff --git a/libvips/conversion/gamma.c b/libvips/conversion/gamma.c index 3eddea1ea8..cb57f8356f 100644 --- a/libvips/conversion/gamma.c +++ b/libvips/conversion/gamma.c @@ -162,13 +162,13 @@ vips_gamma_init(VipsGamma *gamma) * vips_gamma: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Calculate @in ** (1 / @exponent), normalising to the maximum range of the * input type. For float types use 1.0 as the maximum. * * ::: tip "Optional arguments" - * * @exponent: %gdouble, gamma, default 1.0 / 2.4 + * * @exponent: `gdouble`, gamma, default 1.0 / 2.4 * * ::: seealso * [ctor@Image.identity], [method@Image.pow_const1], [method@Image.maplut] diff --git a/libvips/conversion/grid.c b/libvips/conversion/grid.c index 75c02d8b27..759b54eef4 100644 --- a/libvips/conversion/grid.c +++ b/libvips/conversion/grid.c @@ -238,7 +238,7 @@ vips_grid_init(VipsGrid *grid) * @tile_height: chop into tiles this high * @across: tiles across * @down: tiles down - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Chop a tall thin image up into a set of tiles, lay the tiles out in a grid. * diff --git a/libvips/conversion/ifthenelse.c b/libvips/conversion/ifthenelse.c index a6de3e81d9..265af4a1e3 100644 --- a/libvips/conversion/ifthenelse.c +++ b/libvips/conversion/ifthenelse.c @@ -562,7 +562,7 @@ vips_ifthenelse_init(VipsIfthenelse *ifthenelse) * @in1: then [class@Image] * @in2: else [class@Image] * @out: (out): output [class@Image] - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation scans the condition image @cond * and uses it to select pixels from either the then image @in1 or the else @@ -578,7 +578,7 @@ vips_ifthenelse_init(VipsIfthenelse *ifthenelse) * If the images differ in size, the smaller images are enlarged to match the * largest by adding zero pixels along the bottom and right. * - * If @blend is %TRUE, then values in @out are smoothly blended between @in1 + * If @blend is `TRUE`, then values in @out are smoothly blended between @in1 * and @in2 using the formula: * * ``` @@ -586,7 +586,7 @@ vips_ifthenelse_init(VipsIfthenelse *ifthenelse) * ``` * * ::: tip "Optional arguments" - * * @blend: %gboolean, blend smoothly between @in1 and @in2 + * * @blend: `gboolean`, blend smoothly between @in1 and @in2 * * ::: seealso * [method@Image.equal]. diff --git a/libvips/conversion/insert.c b/libvips/conversion/insert.c index 3ef12cdfac..92f787f112 100644 --- a/libvips/conversion/insert.c +++ b/libvips/conversion/insert.c @@ -518,11 +518,11 @@ vips_insert_init(VipsInsert *insert) * @out: (out): output image * @x: left position of @sub * @y: top position of @sub - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Insert @sub into @main at position @x, @y. * - * Normally @out shows the whole of @main. If @expand is #TRUE then @out is + * Normally @out shows the whole of @main. If @expand is `TRUE` then @out is * made large enough to hold all of @main and @sub. * Any areas of @out not coming from * either @main or @sub are set to @background (default 0). @@ -540,7 +540,7 @@ vips_insert_init(VipsInsert *insert) * [arithmetic](libvips-arithmetic.html)). * * ::: tip "Optional arguments" - * * @expand: %gdouble, expand output to hold whole of both images + * * @expand: `gdouble`, expand output to hold whole of both images * * @background: [struct@ArrayDouble], colour for new pixels * * ::: seealso diff --git a/libvips/conversion/join.c b/libvips/conversion/join.c index 148b5aa980..f0c181b976 100644 --- a/libvips/conversion/join.c +++ b/libvips/conversion/join.c @@ -293,13 +293,13 @@ vips_join_init(VipsJoin *join) * @in2: second input image * @out: (out): output image * @direction: join horizontally or vertically - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Join @in1 and @in2 together, left-right or up-down depending on the value * of @direction. * * If one is taller or wider than the - * other, @out will be has high as the smaller. If @expand is %TRUE, then + * other, @out will be has high as the smaller. If @expand is `TRUE`, then * the output will be expanded to contain all of the input pixels. * * Use @align to set the edge that the images align on. By default, they align @@ -323,9 +323,9 @@ vips_join_init(VipsJoin *join) * grid, [func@Image.arrayjoin] is a better choice. * * ::: tip "Optional arguments" - * * @expand: %gboolean, %TRUE to expand the output image to hold all of + * * @expand: `gboolean`, `TRUE` to expand the output image to hold all of * the input pixels - * * @shim: %gint, space between images, in pixels + * * @shim: `gint`, space between images, in pixels * * @background: [struct@ArrayDouble], background ink colour * * @align: [enumAlign], low, centre or high alignment * diff --git a/libvips/conversion/msb.c b/libvips/conversion/msb.c index fe89700177..d0d83711b8 100644 --- a/libvips/conversion/msb.c +++ b/libvips/conversion/msb.c @@ -267,7 +267,7 @@ vips_msb_init(VipsMsb *msb) * vips_msb: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Turn any integer image to 8-bit unsigned char by discarding all but the most * significant byte. Signed values are converted to unsigned by adding 128. @@ -277,7 +277,7 @@ vips_msb_init(VipsMsb *msb) * This operator also works for LABQ coding. * * ::: tip "Optional arguments" - * * @band: %gint, msb just this band + * * @band: `gint`, msb just this band * * ::: seealso * [method@Image.scale], [method@Image.cast]. diff --git a/libvips/conversion/premultiply.c b/libvips/conversion/premultiply.c index cafb8c2b10..31910f5e50 100644 --- a/libvips/conversion/premultiply.c +++ b/libvips/conversion/premultiply.c @@ -281,7 +281,7 @@ vips_premultiply_init(VipsPremultiply *premultiply) * vips_premultiply: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Premultiplies any alpha channel. * @@ -309,7 +309,7 @@ vips_premultiply_init(VipsPremultiply *premultiply) * Non-complex images only. * * ::: tip "Optional arguments" - * * @max_alpha: %gdouble, maximum value for alpha + * * @max_alpha: `gdouble`, maximum value for alpha * * ::: seealso * [method@Image.unpremultiply], [method@Image.flatten]. diff --git a/libvips/conversion/recomb.c b/libvips/conversion/recomb.c index e0d4f9efdf..b5c3b9c6b3 100644 --- a/libvips/conversion/recomb.c +++ b/libvips/conversion/recomb.c @@ -243,7 +243,7 @@ vips_recomb_init(VipsRecomb *recomb) * @in: input image * @out: (out): output image * @m: recombination matrix - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation recombines an image's bands. Each pixel in @in is treated as * an n-element vector, where n is the number of bands in @in, and multiplied by diff --git a/libvips/conversion/replicate.c b/libvips/conversion/replicate.c index 5a0c8727e6..b828f589ad 100644 --- a/libvips/conversion/replicate.c +++ b/libvips/conversion/replicate.c @@ -224,7 +224,7 @@ vips_replicate_init(VipsReplicate *replicate) * @out: (out): output image * @across: repeat input this many times across * @down: repeat input this many times down - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Repeats an image many times. * diff --git a/libvips/conversion/rot.c b/libvips/conversion/rot.c index 310e26157c..0daf1ecad7 100644 --- a/libvips/conversion/rot.c +++ b/libvips/conversion/rot.c @@ -391,7 +391,7 @@ vips_rotv(VipsImage *in, VipsImage **out, VipsAngle angle, va_list ap) * @in: input image * @out: (out): output image * @angle: rotation angle - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Rotate @in by a multiple of 90 degrees. * @@ -420,7 +420,7 @@ vips_rot(VipsImage *in, VipsImage **out, VipsAngle angle, ...) * vips_rot90: (method) * @in: input image * @out: output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Rotate @in by 90 degrees clockwise. A convenience function over [method@Image.rot]. * @@ -446,7 +446,7 @@ vips_rot90(VipsImage *in, VipsImage **out, ...) * vips_rot180: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Rotate @in by 180 degrees. A convenience function over [method@Image.rot]. * @@ -472,7 +472,7 @@ vips_rot180(VipsImage *in, VipsImage **out, ...) * vips_rot270: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Rotate @in by 270 degrees clockwise. A convenience function over [method@Image.rot]. * diff --git a/libvips/conversion/rot45.c b/libvips/conversion/rot45.c index 8c712d869d..6a754796b5 100644 --- a/libvips/conversion/rot45.c +++ b/libvips/conversion/rot45.c @@ -288,7 +288,7 @@ vips_rot45_init(VipsRot45 *rot45) * vips_rot45: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Rotate @in by a multiple of 45 degrees. Odd-length sides and square images * only. diff --git a/libvips/conversion/scale.c b/libvips/conversion/scale.c index 7a2c5f7e33..3170fa1967 100644 --- a/libvips/conversion/scale.c +++ b/libvips/conversion/scale.c @@ -182,7 +182,7 @@ vips_scale_init(VipsScale *scale) * vips_scale: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Search the image for the maximum and minimum value, then return the image * as unsigned 8-bit, scaled so that the maximum value is 255 and the @@ -192,8 +192,8 @@ vips_scale_init(VipsScale *scale) * then scale so max == 255. By default, @exp is 0.25. * * ::: tip "Optional arguments" - * * @log: %gboolean, log scale pixels - * * @exp: %gdouble, exponent for log scale + * * @log: `gboolean`, log scale pixels + * * @exp: `gdouble`, exponent for log scale * * ::: seealso * [method@Image.cast]. diff --git a/libvips/conversion/sequential.c b/libvips/conversion/sequential.c index 5e2ea258a8..341334d2bd 100644 --- a/libvips/conversion/sequential.c +++ b/libvips/conversion/sequential.c @@ -280,7 +280,7 @@ vips_sequential_init(VipsSequential *sequential) * vips_sequential: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation behaves rather like [method@Image.copy] between images * @in and @out, except that it checks that pixels on @in are only requested @@ -291,7 +291,7 @@ vips_sequential_init(VipsSequential *sequential) * [method@Image.sequential] uses. The default value is 1. * * ::: tip "Optional arguments" - * * @tile_height: %gint, height of cache strips + * * @tile_height: `gint`, height of cache strips * * ::: seealso * [method@Image.linecache], [method@Image.tilecache]. diff --git a/libvips/conversion/smartcrop.c b/libvips/conversion/smartcrop.c index 40a5b59b80..481fdbc4bb 100644 --- a/libvips/conversion/smartcrop.c +++ b/libvips/conversion/smartcrop.c @@ -491,7 +491,7 @@ vips_smartcrop_init(VipsSmartcrop *smartcrop) * @out: (out): output image * @width: width of area to extract * @height: height of area to extract - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Crop an image down to a specified width and height by removing boring parts. * @@ -504,10 +504,10 @@ vips_smartcrop_init(VipsSmartcrop *smartcrop) * ::: tip "Optional arguments" * * @interesting: [enum@Interesting] to use to find interesting areas * (default: [enum@Vips.Interesting.ATTENTION]) - * * @premultiplied: %gboolean, input image already has premultiplied alpha - * * @attention_x: %gint, horizontal position of attention centre when + * * @premultiplied: `gboolean`, input image already has premultiplied alpha + * * @attention_x: `gint`, horizontal position of attention centre when * using attention based cropping (output) - * * @attention_y: %gint, vertical position of attention centre when + * * @attention_y: `gint`, vertical position of attention centre when * using attention based cropping (output) * * ::: seealso diff --git a/libvips/conversion/subsample.c b/libvips/conversion/subsample.c index 281a6e2879..c5a6b06caf 100644 --- a/libvips/conversion/subsample.c +++ b/libvips/conversion/subsample.c @@ -302,7 +302,7 @@ vips_subsample_init(VipsSubsample *subsample) * @out: (out): output image * @xfac: horizontal shrink factor * @yfac: vertical shrink factor - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Subsample an image by an integer fraction. This is fast, nearest-neighbour * shrink. @@ -315,7 +315,7 @@ vips_subsample_init(VipsSubsample *subsample) * if the previous operations in the pipeline are very slow. * * ::: tip "Optional arguments" - * * @point: %gboolean, turn on point sample mode + * * @point: `gboolean`, turn on point sample mode * * ::: seealso * [method@Image.affine], [method@Image.shrink], [method@Image.zoom]. diff --git a/libvips/conversion/switch.c b/libvips/conversion/switch.c index 0b47864660..199edd3c06 100644 --- a/libvips/conversion/switch.c +++ b/libvips/conversion/switch.c @@ -228,7 +228,7 @@ vips_switchv(VipsImage **tests, VipsImage **out, int n, va_list ap) * @tests: (array length=n): test these images * @out: (out): output index image * @n: number of input images - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * The @tests images are evaluated and at each point the index of the first * non-zero value is written to @out. If all @tests are false, the value diff --git a/libvips/conversion/tilecache.c b/libvips/conversion/tilecache.c index 9bba127eef..f18895c92f 100644 --- a/libvips/conversion/tilecache.c +++ b/libvips/conversion/tilecache.c @@ -820,7 +820,7 @@ vips_tile_cache_init(VipsTileCache *cache) * vips_tilecache: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * * This operation behaves rather like [method@Image.copy] between images @@ -841,19 +841,19 @@ vips_tile_cache_init(VipsTileCache *cache) * will cache up to 1,000 tiles. @access defaults to [enum@Vips.Access.RANDOM]. * * Normally, only a single thread at once is allowed to calculate tiles. If - * you set @threaded to %TRUE, [method@Image.tilecache] will allow many + * you set @threaded to `TRUE`, [method@Image.tilecache] will allow many * threads to calculate tiles at once, and share the cache between them. * * Normally the cache is dropped when computation finishes. Set @persistent to - * %TRUE to keep the cache between computations. + * `TRUE` to keep the cache between computations. * * ::: tip "Optional arguments" - * * @tile_width: %gint, width of tiles in cache - * * @tile_height: %gint, height of tiles in cache - * * @max_tiles: %gint, maximum number of tiles to cache + * * @tile_width: `gint`, width of tiles in cache + * * @tile_height: `gint`, height of tiles in cache + * * @max_tiles: `gint`, maximum number of tiles to cache * * @access: [enum@Access], hint expected access pattern - * * @threaded: %gboolean, allow many threads - * * @persistent: %gboolean, don't drop cache at end of computation + * * @threaded: `gboolean`, allow many threads + * * @persistent: `gboolean`, don't drop cache at end of computation * * ::: seealso * [method@Image.linecache]. @@ -994,7 +994,7 @@ vips_line_cache_init(VipsLineCache *cache) * vips_linecache: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation behaves rather like [method@Image.copy] between images * @in and @out, except that it keeps a cache of computed scanlines. @@ -1013,13 +1013,13 @@ vips_line_cache_init(VipsLineCache *cache) * [method@Image.linecache] uses. The default is 1 (a single scanline). * * Normally, only a single thread at once is allowed to calculate tiles. If - * you set @threaded to %TRUE, [method@Image.linecache] will allow many + * you set @threaded to `TRUE`, [method@Image.linecache] will allow many * threads to calculate tiles at once and share the cache between them. * * ::: tip "Optional arguments" * * @access: [enum@Access], hint expected access pattern - * * @tile_height: %gint, height of tiles in cache - * * @threaded: %gboolean, allow many threads + * * @tile_height: `gint`, height of tiles in cache + * * @threaded: `gboolean`, allow many threads * * ::: seealso * [method@Image.tilecache]. diff --git a/libvips/conversion/transpose3d.c b/libvips/conversion/transpose3d.c index 37d26d1de0..8334c0691a 100644 --- a/libvips/conversion/transpose3d.c +++ b/libvips/conversion/transpose3d.c @@ -186,24 +186,24 @@ vips_transpose3d_init(VipsTranspose3d *transpose3d) * vips_transpose3d: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Transpose a volumetric image. * * Volumetric images are very tall, thin images, with the metadata item - * #VIPS_META_PAGE_HEIGHT set to the height of each sub-image. + * [const@META_PAGE_HEIGHT] set to the height of each sub-image. * * This operation swaps the two major dimensions, so that page N in the * output contains the Nth scanline, in order, from each input page. * - * You can override the #VIPS_META_PAGE_HEIGHT metadata item with the optional + * You can override the [const@META_PAGE_HEIGHT] metadata item with the optional * @page_height parameter. * - * #VIPS_META_PAGE_HEIGHT in the output image is the number of pages in the + * [const@META_PAGE_HEIGHT] in the output image is the number of pages in the * input image. * * ::: tip "Optional arguments" - * * @page_height: %gint, size of each input page + * * @page_height: `gint`, size of each input page * * ::: seealso * [method@Image.grid]. diff --git a/libvips/conversion/unpremultiply.c b/libvips/conversion/unpremultiply.c index ba5aa6ec90..80bdb7d8ce 100644 --- a/libvips/conversion/unpremultiply.c +++ b/libvips/conversion/unpremultiply.c @@ -350,7 +350,7 @@ vips_unpremultiply_init(VipsUnpremultiply *unpremultiply) * vips_unpremultiply: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Unpremultiplies any alpha channel. * @@ -380,8 +380,8 @@ vips_unpremultiply_init(VipsUnpremultiply *unpremultiply) * Non-complex images only. * * ::: tip "Optional arguments" - * * @max_alpha: %gdouble, maximum value for alpha - * * @alpha_band: %gint, band containing alpha data + * * @max_alpha: `gdouble`, maximum value for alpha + * * @alpha_band: `gint`, band containing alpha data * * ::: seealso * [method@Image.premultiply], [method@Image.flatten]. diff --git a/libvips/conversion/wrap.c b/libvips/conversion/wrap.c index a965b12b9c..9d725eddcb 100644 --- a/libvips/conversion/wrap.c +++ b/libvips/conversion/wrap.c @@ -145,7 +145,7 @@ vips_wrap_init(VipsWrap *wrap) * vips_wrap: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Slice an image up and move the segments about so that the pixel that was * at 0, 0 is now at @x, @y. diff --git a/libvips/conversion/zoom.c b/libvips/conversion/zoom.c index c20bcaac1c..3051747099 100644 --- a/libvips/conversion/zoom.c +++ b/libvips/conversion/zoom.c @@ -401,7 +401,7 @@ vips_zoom_init(VipsZoom *zoom) * @out: (out): output image * @xfac: horizontal scale factor * @yfac: vertical scale factor - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Zoom an image by repeating pixels. This is fast nearest-neighbour * zoom. diff --git a/libvips/convolution/canny.c b/libvips/convolution/canny.c index 67fe6395e8..d5afa8f07a 100644 --- a/libvips/convolution/canny.c +++ b/libvips/convolution/canny.c @@ -476,7 +476,7 @@ vips_canny_init(VipsCanny *canny) * vips_canny: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Find edges by Canny's method: The maximum of the derivative of the gradient * in the direction of the gradient. Output is float, except for uchar input, @@ -494,7 +494,7 @@ vips_canny_init(VipsCanny *canny) * edges. * * ::: tip "Optional arguments" - * * @sigma: %gdouble, sigma for gaussian blur + * * @sigma: `gdouble`, sigma for gaussian blur * * @precision: [enum@Precision], calculation accuracy * * ::: seealso diff --git a/libvips/convolution/compass.c b/libvips/convolution/compass.c index 10a60b42c0..877a70b66b 100644 --- a/libvips/convolution/compass.c +++ b/libvips/convolution/compass.c @@ -218,19 +218,19 @@ vips_compass_init(VipsCompass *compass) * @in: input image * @out: (out): output image * @mask: convolve with this mask - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This convolves @in with @mask @times times, rotating @mask by @angle * each time. By default, it comvolves twice, rotating by 90 degrees, taking * the maximum result. * * ::: tip "Optional arguments" - * * @times: %gint, how many times to rotate and convolve + * * @times: `gint`, how many times to rotate and convolve * * @angle: [enum@Angle45], rotate mask by this much between colvolutions - * * @combine: #VipsCombine, combine results like this + * * @combine: [enum@Combine], combine results like this * * @precision: [enum@Precision], precision for blur, default float - * * @layers: %gint, number of layers for approximation - * * @cluster: %gint, cluster lines closer than this distance + * * @layers: `gint`, number of layers for approximation + * * @cluster: `gint`, cluster lines closer than this distance * * ::: seealso * [method@Image.conv]. diff --git a/libvips/convolution/conv.c b/libvips/convolution/conv.c index 9f02b022af..8fd17fb902 100644 --- a/libvips/convolution/conv.c +++ b/libvips/convolution/conv.c @@ -165,7 +165,7 @@ vips_conv_init(VipsConv *conv) * @in: input image * @out: (out): output image * @mask: convolve with this mask - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform a convolution of @in with @mask. * @@ -210,8 +210,8 @@ vips_conv_init(VipsConv *conv) * * ::: tip "Optional arguments" * * @precision: [enum@Precision], calculation accuracy - * * @layers: %gint, number of layers for approximation - * * @cluster: %gint, cluster lines closer than this distance + * * @layers: `gint`, number of layers for approximation + * * @cluster: `gint`, cluster lines closer than this distance * * ::: seealso * [method@Image.convsep]. diff --git a/libvips/convolution/conva.c b/libvips/convolution/conva.c index dd54135141..06f17c5e67 100644 --- a/libvips/convolution/conva.c +++ b/libvips/convolution/conva.c @@ -1346,7 +1346,7 @@ vips_conva_init(VipsConva *conva) * @in: input image * @out: (out): output image * @mask: convolution mask - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform an approximate integer convolution of @in with @mask. * This is a low-level operation, see [method@Image.conv] for something more @@ -1367,8 +1367,8 @@ vips_conva_init(VipsConva *conva) * and use more memory. 10% of the mask radius is a good rule of thumb. * * ::: tip "Optional arguments" - * * @layers: %gint, number of layers for approximation - * * @cluster: %gint, cluster lines closer than this distance + * * @layers: `gint`, number of layers for approximation + * * @cluster: `gint`, cluster lines closer than this distance * * ::: seealso * [method@Image.conv]. diff --git a/libvips/convolution/convasep.c b/libvips/convolution/convasep.c index 50f3bfb893..4db41193a5 100644 --- a/libvips/convolution/convasep.c +++ b/libvips/convolution/convasep.c @@ -934,7 +934,7 @@ vips_convasep_init(VipsConvasep *convasep) * @in: input image * @out: (out): output image * @mask: convolve with this mask - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Approximate separable integer convolution. This is a low-level operation, see * [method@Image.convsep] for something more convenient. @@ -955,7 +955,7 @@ vips_convasep_init(VipsConvasep *convasep) * always has the same [enum@BandFormat] as the input image. * * ::: tip "Optional arguments" - * * @layers: %gint, number of layers for approximation + * * @layers: `gint`, number of layers for approximation * * ::: seealso * [method@Image.convsep]. diff --git a/libvips/convolution/convf.c b/libvips/convolution/convf.c index 0da198bfd8..8bd3b18862 100644 --- a/libvips/convolution/convf.c +++ b/libvips/convolution/convf.c @@ -388,7 +388,7 @@ vips_convf_init(VipsConvf *convf) * @in: input image * @out: (out): output image * @mask: convolve with this mask - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convolution. This is a low-level operation, see [method@Image.conv] for something * more convenient. diff --git a/libvips/convolution/convi.c b/libvips/convolution/convi.c index 4f4a584530..185e01e83e 100644 --- a/libvips/convolution/convi.c +++ b/libvips/convolution/convi.c @@ -1262,7 +1262,7 @@ vips_convi_init(VipsConvi *convi) * @in: input image * @out: (out): output image * @mask: convolve with this mask - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Integer convolution. This is a low-level operation, see [method@Image.conv] for * something more convenient. diff --git a/libvips/convolution/convsep.c b/libvips/convolution/convsep.c index 43968548c7..b34646db44 100644 --- a/libvips/convolution/convsep.c +++ b/libvips/convolution/convsep.c @@ -161,7 +161,7 @@ vips_convsep_init(VipsConvsep *convsep) * @in: input image * @out: (out): output image * @mask: convolution mask - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Perform a separable convolution of @in with @mask. * See [method@Image.conv] for a detailed description. @@ -174,8 +174,8 @@ vips_convsep_init(VipsConvsep *convsep) * * ::: tip "Optional arguments" * * @precision: [enum@Precision], calculation accuracy - * * @layers: %gint, number of layers for approximation - * * @cluster: %gint, cluster lines closer than this distance + * * @layers: `gint`, number of layers for approximation + * * @cluster: `gint`, cluster lines closer than this distance * * ::: seealso * [method@Image.conv], [ctor@Image.gaussmat]. diff --git a/libvips/convolution/edge.c b/libvips/convolution/edge.c index 36b2f2572f..f35f1f7c33 100644 --- a/libvips/convolution/edge.c +++ b/libvips/convolution/edge.c @@ -334,7 +334,7 @@ vips_prewitt_init(VipsPrewitt *prewitt) * vips_sobel: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Sobel edge detector. * @@ -364,7 +364,7 @@ vips_sobel(VipsImage *in, VipsImage **out, ...) * vips_scharr: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Scharr edge detector. * @@ -394,7 +394,7 @@ vips_scharr(VipsImage *in, VipsImage **out, ...) * vips_prewitt: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Prewitt edge detector. * diff --git a/libvips/convolution/fastcor.c b/libvips/convolution/fastcor.c index 8ee047686c..761b05e230 100644 --- a/libvips/convolution/fastcor.c +++ b/libvips/convolution/fastcor.c @@ -231,7 +231,7 @@ vips_fastcor_init(VipsFastcor *fastcor) * @in: input image * @ref: reference image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Calculate a fast correlation surface. * diff --git a/libvips/convolution/gaussblur.c b/libvips/convolution/gaussblur.c index 90e488f350..ffcac665d7 100644 --- a/libvips/convolution/gaussblur.c +++ b/libvips/convolution/gaussblur.c @@ -175,7 +175,7 @@ vips_gaussblur_init(VipsGaussblur *gaussblur) * @in: input image * @out: (out): output image * @sigma: how large a mask to use - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operator runs [ctor@Image.gaussmat] and [method@Image.convsep] for * you on an image. diff --git a/libvips/convolution/sharpen.c b/libvips/convolution/sharpen.c index 618b67daec..cef99414c7 100644 --- a/libvips/convolution/sharpen.c +++ b/libvips/convolution/sharpen.c @@ -397,7 +397,7 @@ vips_sharpen_init(VipsSharpen *sharpen) * vips_sharpen: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Selectively sharpen the L channel of a LAB image. The input image is * transformed to [enum@Vips.Interpretation.LABS]. @@ -450,12 +450,12 @@ vips_sharpen_init(VipsSharpen *sharpen) * resolution. * * ::: tip "Optional arguments" - * * @sigma: %gdouble, sigma of gaussian - * * @x1: %gdouble, flat/jaggy threshold - * * @y2: %gdouble, maximum amount of brightening - * * @y3: %gdouble, maximum amount of darkening - * * @m1: %gdouble, slope for flat areas - * * @m2: %gdouble, slope for jaggy areas + * * @sigma: `gdouble`, sigma of gaussian + * * @x1: `gdouble`, flat/jaggy threshold + * * @y2: `gdouble`, maximum amount of brightening + * * @y3: `gdouble`, maximum amount of darkening + * * @m1: `gdouble`, slope for flat areas + * * @m2: `gdouble`, slope for jaggy areas * * ::: seealso * [method@Image.conv]. diff --git a/libvips/convolution/spcor.c b/libvips/convolution/spcor.c index 992c16921b..73a7b67cea 100644 --- a/libvips/convolution/spcor.c +++ b/libvips/convolution/spcor.c @@ -331,7 +331,7 @@ vips_spcor_init(VipsSpcor *spcor) * @in: input image * @ref: reference image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Calculate a correlation surface. * diff --git a/libvips/create/black.c b/libvips/create/black.c index e8d22b9642..93d252214c 100644 --- a/libvips/create/black.c +++ b/libvips/create/black.c @@ -169,12 +169,12 @@ vips_black_init(VipsBlack *black) * @out: (out): output image * @width: output width * @height: output height - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make a black unsigned char image of a specified size. * * ::: tip "Optional arguments" - * * @bands: %gint, output bands + * * @bands: `gint`, output bands * * ::: seealso * [ctor@Image.xyz], [ctor@Image.text], [ctor@Image.gaussnoise]. diff --git a/libvips/create/buildlut.c b/libvips/create/buildlut.c index 9d2155f3bf..67b846e8e5 100644 --- a/libvips/create/buildlut.c +++ b/libvips/create/buildlut.c @@ -275,7 +275,7 @@ vips_buildlut_init(VipsBuildlut *lut) * vips_buildlut: (method) * @in: input matrix * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation builds a lookup table from a set of points. Intermediate * values are generated by piecewise linear interpolation. The lookup table is diff --git a/libvips/create/eye.c b/libvips/create/eye.c index 8e337b26f8..a872b18bf2 100644 --- a/libvips/create/eye.c +++ b/libvips/create/eye.c @@ -123,7 +123,7 @@ vips_eye_init(VipsEye *eye) * @out: (out): output image * @width: image size * @height: image size - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Create a test pattern with increasing spatial frequency in X and * amplitude in Y. @@ -134,8 +134,8 @@ vips_eye_init(VipsEye *eye) * Set @uchar to output a uchar image. * * ::: tip "Optional arguments" - * * @factor: %gdouble, maximum spatial frequency - * * @uchar: %gboolean, output a uchar image + * * @factor: `gdouble`, maximum spatial frequency + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.zone]. diff --git a/libvips/create/fractsurf.c b/libvips/create/fractsurf.c index d1c09e0945..c9fb88f8d3 100644 --- a/libvips/create/fractsurf.c +++ b/libvips/create/fractsurf.c @@ -136,7 +136,7 @@ vips_fractsurf_init(VipsFractsurf *fractsurf) * @width: output width * @height: output height * @fractal_dimension: fractal dimension - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Generate an image of size @width by @height and fractal dimension * @fractal_dimension. The dimension should be between 2 and 3. diff --git a/libvips/create/gaussmat.c b/libvips/create/gaussmat.c index 2b643072d3..23804290ae 100644 --- a/libvips/create/gaussmat.c +++ b/libvips/create/gaussmat.c @@ -230,7 +230,7 @@ vips_gaussmat_init(VipsGaussmat *gaussmat) * @out: (out): output image * @sigma: standard deviation of mask * @min_ampl: minimum amplitude - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Creates a circularly symmetric Gaussian image of radius * @sigma. @@ -257,7 +257,7 @@ vips_gaussmat_init(VipsGaussmat *gaussmat) * "scale" is set to the sum of all the mask elements. * * ::: tip "Optional arguments" - * * @separable: %gboolean, generate a separable gaussian + * * @separable: `gboolean`, generate a separable gaussian * * @precision: [enum@Precision] for @out * * ::: seealso diff --git a/libvips/create/gaussnoise.c b/libvips/create/gaussnoise.c index 7b1dc887d6..7dcf406f52 100644 --- a/libvips/create/gaussnoise.c +++ b/libvips/create/gaussnoise.c @@ -213,7 +213,7 @@ vips_gaussnoise_init(VipsGaussnoise *gaussnoise) * @out: (out): output image * @width: output width * @height: output height - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make a one band float image of gaussian noise with the specified * distribution. @@ -222,8 +222,8 @@ vips_gaussnoise_init(VipsGaussnoise *gaussnoise) * linear generator, then weighting appropriately with @mean and @sigma. * * ::: tip "Optional arguments" - * * @mean: %gdouble, mean of generated pixels - * * @sigma: %gdouble, standard deviation of generated pixels + * * @mean: `gdouble`, mean of generated pixels + * * @sigma: `gdouble`, standard deviation of generated pixels * * ::: seealso * [ctor@Image.black], [ctor@Image.xyz], [ctor@Image.text]. diff --git a/libvips/create/grey.c b/libvips/create/grey.c index 51f800258f..8c26e30c5f 100644 --- a/libvips/create/grey.c +++ b/libvips/create/grey.c @@ -103,7 +103,7 @@ vips_grey_init(VipsGrey *grey) * @out: (out): output image * @width: image size * @height: image size - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Create a one-band float image with the left-most column zero and the * right-most 1. @@ -114,7 +114,7 @@ vips_grey_init(VipsGrey *grey) * rightmost 255. * * ::: tip "Optional arguments" - * * @uchar: %gboolean, output a uchar image + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.xyz], [ctor@Image.identity]. diff --git a/libvips/create/identity.c b/libvips/create/identity.c index 67073aba07..5152293336 100644 --- a/libvips/create/identity.c +++ b/libvips/create/identity.c @@ -172,7 +172,7 @@ vips_identity_init(VipsIdentity *identity) /** * vips_identity: * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Creates an identity lookup table, ie. one which will leave an image * unchanged when applied with [method@Image.maplut]. Each entry in the table @@ -187,9 +187,9 @@ vips_identity_init(VipsIdentity *identity) * @size. * * ::: tip "Optional arguments" - * * @bands: %gint, number of bands to create - * * @ushort: %gboolean, %TRUE for an unsigned short identity - * * @size: %gint, number of LUT elements for a ushort image + * * @bands: `gint`, number of bands to create + * * @ushort: `gboolean`, `TRUE` for an unsigned short identity + * * @size: `gint`, number of LUT elements for a ushort image * * ::: seealso * [ctor@Image.xyz], [method@Image.maplut]. diff --git a/libvips/create/invertlut.c b/libvips/create/invertlut.c index 208f4ad561..db88c5cf89 100644 --- a/libvips/create/invertlut.c +++ b/libvips/create/invertlut.c @@ -308,7 +308,7 @@ vips_invertlut_init(VipsInvertlut *lut) * vips_invertlut: (method) * @in: input mask * @out: (out): output LUT - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Given a mask of target values and real values, generate a LUT which * will map reals to targets. @@ -337,7 +337,7 @@ vips_invertlut_init(VipsInvertlut *lut) * do something better really. * * ::: tip "Optional arguments" - * * @size: %gint, generate this much + * * @size: `gint`, generate this much * * ::: seealso * [method@Image.buildlut]. diff --git a/libvips/create/logmat.c b/libvips/create/logmat.c index 4b7d186523..49cc773a42 100644 --- a/libvips/create/logmat.c +++ b/libvips/create/logmat.c @@ -246,7 +246,7 @@ vips_logmat_init(VipsLogmat *logmat) * @out: (out): output image * @sigma: standard deviation of mask * @min_ampl: minimum amplitude - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Create a circularly symmetric Laplacian of Gaussian mask of radius * @sigma. @@ -283,7 +283,7 @@ vips_logmat_init(VipsLogmat *logmat) * "scale" is set to the sum of all the mask elements. * * ::: tip "Optional arguments" - * * @separable: %gboolean, generate a separable mask + * * @separable: `gboolean`, generate a separable mask * * @precision: [enum@Precision] for @out * * ::: seealso diff --git a/libvips/create/mask_butterworth.c b/libvips/create/mask_butterworth.c index 71a50e7f17..4982670426 100644 --- a/libvips/create/mask_butterworth.c +++ b/libvips/create/mask_butterworth.c @@ -125,7 +125,7 @@ vips_mask_butterworth_init(VipsMaskButterworth *butterworth) * @order: filter order * @frequency_cutoff: frequency threshold * @amplitude_cutoff: amplitude threshold - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make an butterworth high- or low-pass filter, that is, one with a variable, * smooth transition @@ -137,10 +137,10 @@ vips_mask_butterworth_init(VipsMaskButterworth *butterworth) * Digital Image Processing, 1987. * * ::: tip "Optional arguments" - * * @nodc: %gboolean, don't set the DC pixel - * * @reject: %gboolean, invert the filter sense - * * @optical: %gboolean, coordinates in optical space - * * @uchar: %gboolean, output a uchar image + * * @nodc: `gboolean`, don't set the DC pixel + * * @reject: `gboolean`, invert the filter sense + * * @optical: `gboolean`, coordinates in optical space + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.mask_ideal]. diff --git a/libvips/create/mask_butterworth_band.c b/libvips/create/mask_butterworth_band.c index b2e443544c..7053bcbddd 100644 --- a/libvips/create/mask_butterworth_band.c +++ b/libvips/create/mask_butterworth_band.c @@ -168,7 +168,7 @@ vips_mask_butterworth_band_init( * @frequency_cutoff_y: band position * @radius: band radius * @amplitude_cutoff: amplitude threshold - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make an butterworth band-pass or band-reject filter, that is, one with a * variable, smooth transition positioned at @frequency_cutoff_x, @@ -179,10 +179,10 @@ vips_mask_butterworth_band_init( * Digital Image Processing, 1987. * * ::: tip "Optional arguments" - * * @nodc: %gboolean, don't set the DC pixel - * * @reject: %gboolean, invert the filter sense - * * @optical: %gboolean, coordinates in optical space - * * @uchar: %gboolean, output a uchar image + * * @nodc: `gboolean`, don't set the DC pixel + * * @reject: `gboolean`, invert the filter sense + * * @optical: `gboolean`, coordinates in optical space + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.mask_ideal]. diff --git a/libvips/create/mask_butterworth_ring.c b/libvips/create/mask_butterworth_ring.c index 9372d456b4..bccb2e6fdb 100644 --- a/libvips/create/mask_butterworth_ring.c +++ b/libvips/create/mask_butterworth_ring.c @@ -126,7 +126,7 @@ vips_mask_butterworth_ring_init( * @frequency_cutoff: frequency threshold * @amplitude_cutoff: amplitude threshold * @ringwidth: ringwidth - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make a butterworth ring-pass or ring-reject filter, that is, one with a * variable, @@ -139,10 +139,10 @@ vips_mask_butterworth_ring_init( * Digital Image Processing, 1987. * * ::: tip "Optional arguments" - * * @nodc: %gboolean, don't set the DC pixel - * * @reject: %gboolean, invert the filter sense - * * @optical: %gboolean, coordinates in optical space - * * @uchar: %gboolean, output a uchar image + * * @nodc: `gboolean`, don't set the DC pixel + * * @reject: `gboolean`, invert the filter sense + * * @optical: `gboolean`, coordinates in optical space + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.mask_ideal]. diff --git a/libvips/create/mask_fractal.c b/libvips/create/mask_fractal.c index b0a48a1637..1c0a6711f5 100644 --- a/libvips/create/mask_fractal.c +++ b/libvips/create/mask_fractal.c @@ -109,7 +109,7 @@ vips_mask_fractal_init(VipsMaskFractal *fractal) * @width: image size * @height: image size * @fractal_dimension: fractal dimension - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation should be used to create fractal images by filtering the * power spectrum of Gaussian white noise. @@ -117,10 +117,10 @@ vips_mask_fractal_init(VipsMaskFractal *fractal) * See [ctor@Image.gaussnoise]. * * ::: tip "Optional arguments" - * * @nodc: %gboolean, don't set the DC pixel - * * @reject: %gboolean, invert the filter sense - * * @optical: %gboolean, coordinates in optical space - * * @uchar: %gboolean, output a uchar image + * * @nodc: `gboolean`, don't set the DC pixel + * * @reject: `gboolean`, invert the filter sense + * * @optical: `gboolean`, coordinates in optical space + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.mask_ideal]. diff --git a/libvips/create/mask_gaussian.c b/libvips/create/mask_gaussian.c index d0c74898c3..520f65c42a 100644 --- a/libvips/create/mask_gaussian.c +++ b/libvips/create/mask_gaussian.c @@ -111,16 +111,16 @@ vips_mask_gaussian_init(VipsMaskGaussian *gaussian) * @height: image size * @frequency_cutoff: frequency threshold * @amplitude_cutoff: amplitude threshold - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make a gaussian high- or low-pass filter, that is, one with a variable, * smooth transition positioned at @frequency_cutoff. * * ::: tip "Optional arguments" - * * @nodc: %gboolean, don't set the DC pixel - * * @reject: %gboolean, invert the filter sense - * * @optical: %gboolean, coordinates in optical space - * * @uchar: %gboolean, output a uchar image + * * @nodc: `gboolean`, don't set the DC pixel + * * @reject: `gboolean`, invert the filter sense + * * @optical: `gboolean`, coordinates in optical space + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.mask_ideal]. diff --git a/libvips/create/mask_gaussian_band.c b/libvips/create/mask_gaussian_band.c index 6d3139b287..1aa493c737 100644 --- a/libvips/create/mask_gaussian_band.c +++ b/libvips/create/mask_gaussian_band.c @@ -150,17 +150,17 @@ vips_mask_gaussian_band_init(VipsMaskGaussianBand *gaussian_band) * @frequency_cutoff_y: band position * @radius: band radius * @amplitude_cutoff: amplitude threshold - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make a gaussian band-pass or band-reject filter, that is, one with a * variable, smooth transition positioned at @frequency_cutoff_x, * @frequency_cutoff_y, of radius @radius. * * ::: tip "Optional arguments" - * * @nodc: %gboolean, don't set the DC pixel - * * @reject: %gboolean, invert the filter sense - * * @optical: %gboolean, coordinates in optical space - * * @uchar: %gboolean, output a uchar image + * * @nodc: `gboolean`, don't set the DC pixel + * * @reject: `gboolean`, invert the filter sense + * * @optical: `gboolean`, coordinates in optical space + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.mask_ideal]. diff --git a/libvips/create/mask_gaussian_ring.c b/libvips/create/mask_gaussian_ring.c index c665f620ee..0d55060a11 100644 --- a/libvips/create/mask_gaussian_ring.c +++ b/libvips/create/mask_gaussian_ring.c @@ -119,17 +119,17 @@ vips_mask_gaussian_ring_init(VipsMaskGaussianRing *gaussian_ring) * @frequency_cutoff: frequency threshold * @amplitude_cutoff: amplitude threshold * @ringwidth: ringwidth - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make a gaussian ring-pass or ring-reject filter, that is, one with a * variable, smooth transition positioned at @frequency_cutoff of width * @ringwidth. * * ::: tip "Optional arguments" - * * @nodc: %gboolean, don't set the DC pixel - * * @reject: %gboolean, invert the filter sense - * * @optical: %gboolean, coordinates in optical space - * * @uchar: %gboolean, output a uchar image + * * @nodc: `gboolean`, don't set the DC pixel + * * @reject: `gboolean`, invert the filter sense + * * @optical: `gboolean`, coordinates in optical space + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.mask_ideal]. diff --git a/libvips/create/mask_ideal.c b/libvips/create/mask_ideal.c index 4815d41f97..c5dc5e82ce 100644 --- a/libvips/create/mask_ideal.c +++ b/libvips/create/mask_ideal.c @@ -100,7 +100,7 @@ vips_mask_ideal_init(VipsMaskIdeal *ideal) * @width: image size * @height: image size * @frequency_cutoff: threshold at which filter ends - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make an ideal high- or low-pass filter, that is, one with a sharp cutoff * positioned at @frequency_cutoff, where @frequency_cutoff is in @@ -126,10 +126,10 @@ vips_mask_ideal_init(VipsMaskIdeal *ideal) * float image. In this case, pixels are in the range [0 - 255]. * * ::: tip "Optional arguments" - * * @nodc: %gboolean, don't set the DC pixel - * * @reject: %gboolean, invert the filter sense - * * @optical: %gboolean, coordinates in optical space - * * @uchar: %gboolean, output a uchar image + * * @nodc: `gboolean`, don't set the DC pixel + * * @reject: `gboolean`, invert the filter sense + * * @optical: `gboolean`, coordinates in optical space + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.mask_ideal], [ctor@Image.mask_ideal_ring], diff --git a/libvips/create/mask_ideal_band.c b/libvips/create/mask_ideal_band.c index 1b97a7f706..9cd928837a 100644 --- a/libvips/create/mask_ideal_band.c +++ b/libvips/create/mask_ideal_band.c @@ -132,17 +132,17 @@ vips_mask_ideal_band_init(VipsMaskIdealBand *ideal_band) * @frequency_cutoff_x: position of band * @frequency_cutoff_y: position of band * @radius: size of band - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make an ideal band-pass or band-reject filter, that is, one with a * sharp cutoff around the point @frequency_cutoff_x, @frequency_cutoff_y, * of size @radius. * * ::: tip "Optional arguments" - * * @nodc: %gboolean, don't set the DC pixel - * * @reject: %gboolean, invert the filter sense - * * @optical: %gboolean, coordinates in optical space - * * @uchar: %gboolean, output a uchar image + * * @nodc: `gboolean`, don't set the DC pixel + * * @reject: `gboolean`, invert the filter sense + * * @optical: `gboolean`, coordinates in optical space + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.mask_ideal]. diff --git a/libvips/create/mask_ideal_ring.c b/libvips/create/mask_ideal_ring.c index 3573802238..0e076b8236 100644 --- a/libvips/create/mask_ideal_ring.c +++ b/libvips/create/mask_ideal_ring.c @@ -115,17 +115,17 @@ vips_mask_ideal_ring_init(VipsMaskIdealRing *ideal_ring) * @height: image size * @frequency_cutoff: threshold at which filter ends * @ringwidth: ring width - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make an ideal ring-pass or ring-reject filter, that is, one with a sharp * ring positioned at @frequency_cutoff of width @width, where * @frequency_cutoff and @width are expressed as the range 0 - 1. * * ::: tip "Optional arguments" - * * @nodc: %gboolean, don't set the DC pixel - * * @reject: %gboolean, invert the filter sense - * * @optical: %gboolean, coordinates in optical space - * * @uchar: %gboolean, output a uchar image + * * @nodc: `gboolean`, don't set the DC pixel + * * @reject: `gboolean`, invert the filter sense + * * @optical: `gboolean`, coordinates in optical space + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.mask_ideal]. diff --git a/libvips/create/perlin.c b/libvips/create/perlin.c index 1a24f3eda9..f9e2f4a3e6 100644 --- a/libvips/create/perlin.c +++ b/libvips/create/perlin.c @@ -339,7 +339,7 @@ vips_perlin_init(VipsPerlin *perlin) * @out: (out): output image * @width: horizontal size * @height: vertical size - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Create a one-band float image of Perlin noise. * @@ -356,8 +356,8 @@ vips_perlin_init(VipsPerlin *perlin) * [-1, +1]. Set @uchar to output a uchar image with pixels in [0, 255]. * * ::: tip "Optional arguments" - * * @cell_size: %gint, size of Perlin cells - * * @uchar: %gboolean, output a uchar image + * * @cell_size: `gint`, size of Perlin cells + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.worley], [ctor@Image.fractsurf], [ctor@Image.gaussnoise]. diff --git a/libvips/create/sdf.c b/libvips/create/sdf.c index e3fbbfd74f..bbcf4c7535 100644 --- a/libvips/create/sdf.c +++ b/libvips/create/sdf.c @@ -363,7 +363,7 @@ vips_sdf_init(VipsSdf *sdf) * @width: horizontal size * @height: vertical size * @shape: SDF to create - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Create a signed distance field (SDF) image of the given @shape. * @@ -385,7 +385,7 @@ vips_sdf_init(VipsSdf *sdf) * ::: tip "Optional arguments" * * @a: [struct@ArrayDouble], first point * * @b: [struct@ArrayDouble], second point - * * @r: %gfloat, radius + * * @r: `gdouble`, radius * * @corners: [struct@ArrayDouble], corner radii * * ::: seealso diff --git a/libvips/create/sines.c b/libvips/create/sines.c index f7c3fb9e8e..a16056324e 100644 --- a/libvips/create/sines.c +++ b/libvips/create/sines.c @@ -151,7 +151,7 @@ vips_sines_init(VipsSines *sines) * @out: (out): output image * @width: image size * @height: image size - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Creates a float one band image of the a sine waveform in two * dimensions. @@ -167,9 +167,9 @@ vips_sines_init(VipsSines *sines) * Pixels are normally in [-1, +1], set @uchar to output [0, 255]. * * ::: tip "Optional arguments" - * * @hfreq: %gdouble, horizontal frequency - * * @vreq: %gdouble, vertical frequency - * * @uchar: %gboolean, output a uchar image + * * @hfreq: `gdouble`, horizontal frequency + * * @vreq: `gdouble`, vertical frequency + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.grey], [ctor@Image.xyz]. diff --git a/libvips/create/text.c b/libvips/create/text.c index 51ec614c44..b8d5a3cf74 100644 --- a/libvips/create/text.c +++ b/libvips/create/text.c @@ -654,7 +654,7 @@ vips_text_init(VipsText *text) * vips_text: * @out: (out): output image * @text: utf-8 text string to render - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Draw the string @text to an image. * @@ -704,17 +704,17 @@ vips_text_init(VipsText *text) * several [ctor@Image.text]. * * ::: tip "Optional arguments" - * * @font: %gchararray, font to render with - * * @fontfile: %gchararray, load this font file - * * @width: %gint, image should be no wider than this many pixels - * * @height: %gint, image should be no higher than this many pixels - * * @align: #VipsAlign, set justification alignment - * * @justify: %gboolean, justify lines - * * @dpi: %gint, render at this resolution - * * @autofit_dpi: %gint, read out auto-fitted DPI - * * @rgba: %gboolean, enable RGBA output - * * @spacing: %gint, space lines by this in points - * * @wrap: #VipsTextWrap, wrap lines on characters or words + * * @font: `gchararray`, font to render with + * * @fontfile: `gchararray`, load this font file + * * @width: `gint`, image should be no wider than this many pixels + * * @height: `gint`, image should be no higher than this many pixels + * * @align: [enum@Align], set justification alignment + * * @justify: `gboolean`, justify lines + * * @dpi: `gint`, render at this resolution + * * @autofit_dpi: `gint`, read out auto-fitted DPI + * * @rgba: `gboolean`, enable RGBA output + * * @spacing: `gint`, space lines by this in points + * * @wrap: [enum@TextWrap], wrap lines on characters or words * * ::: seealso * [func@Image.bandjoin], [func@Image.composite]. diff --git a/libvips/create/tonelut.c b/libvips/create/tonelut.c index 281ea225c4..d6d4bb6b8d 100644 --- a/libvips/create/tonelut.c +++ b/libvips/create/tonelut.c @@ -310,7 +310,7 @@ vips_tonelut_init(VipsTonelut *lut) /** * vips_tonelut: * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * [ctor@Image.tonelut] generates a tone curve for the adjustment of image * levels. @@ -326,16 +326,16 @@ vips_tonelut_init(VipsTonelut *lut) * @out_max parameters. * * ::: tip "Optional arguments" - * * @in_max: %gint, input range - * * @out_max: %gint, output range - * * @Lb: %gdouble, black-point [0-100] - * * @Lw: %gdouble, white-point [0-100] - * * @Ps: %gdouble, shadow point (eg. 0.2) - * * @Pm: %gdouble, mid-tone point (eg. 0.5) - * * @Ph: %gdouble, highlight point (eg. 0.8) - * * @S: %gdouble, shadow adjustment (+/- 30) - * * @M: %gdouble, mid-tone adjustment (+/- 30) - * * @H: %gdouble, highlight adjustment (+/- 30) + * * @in_max: `gint`, input range + * * @out_max: `gint`, output range + * * @Lb: `gdouble`, black-point [0-100] + * * @Lw: `gdouble`, white-point [0-100] + * * @Ps: `gdouble`, shadow point (eg. 0.2) + * * @Pm: `gdouble`, mid-tone point (eg. 0.5) + * * @Ph: `gdouble`, highlight point (eg. 0.8) + * * @S: `gdouble`, shadow adjustment (+/- 30) + * * @M: `gdouble`, mid-tone adjustment (+/- 30) + * * @H: `gdouble`, highlight adjustment (+/- 30) * * Returns: 0 on success, -1 on error */ diff --git a/libvips/create/worley.c b/libvips/create/worley.c index 0442b60964..3db7a1e5e1 100644 --- a/libvips/create/worley.c +++ b/libvips/create/worley.c @@ -345,7 +345,7 @@ vips_worley_init(VipsWorley *worley) * @out: (out): output image * @width: horizontal size * @height: vertical size - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Create a one-band float image of Worley noise. * @@ -359,7 +359,7 @@ vips_worley_init(VipsWorley *worley) * If @width and @height are multiples of @cell_size, the image will tessellate. * * ::: tip "Optional arguments" - * * @cell_size: %gint, size of Worley cells + * * @cell_size: `gint`, size of Worley cells * * ::: seealso * [ctor@Image.perlin], [ctor@Image.fractsurf], [ctor@Image.gaussnoise]. diff --git a/libvips/create/xyz.c b/libvips/create/xyz.c index f647fc414b..e5203a50a3 100644 --- a/libvips/create/xyz.c +++ b/libvips/create/xyz.c @@ -239,7 +239,7 @@ vips_xyz_init(VipsXyz *xyz) * @out: (out): output image * @width: horizontal size * @height: vertical size - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Create a two-band uint32 image where the elements in the first band have the * value of their x coordinate and elements in the second band have their y @@ -253,9 +253,9 @@ vips_xyz_init(VipsXyz *xyz) * [method@Image.grid] to change the layout. * * ::: tip "Optional arguments" - * * @csize: %gint, size for third dimension - * * @dsize: %gint, size for fourth dimension - * * @esize: %gint, size for fifth dimension + * * @csize: `gint`, size for third dimension + * * @dsize: `gint`, size for fourth dimension + * * @esize: `gint`, size for fifth dimension * * ::: seealso * [ctor@Image.grey], [method@Image.grid], [ctor@Image.identity]. diff --git a/libvips/create/zone.c b/libvips/create/zone.c index e2aa6653f6..727d1a355c 100644 --- a/libvips/create/zone.c +++ b/libvips/create/zone.c @@ -102,14 +102,14 @@ vips_zone_init(VipsZone *zone) * @out: (out): output image * @width: image size * @height: image size - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Create a one-band image of a zone plate. * * Pixels are normally in [-1, +1], set @uchar to output [0, 255]. * * ::: tip "Optional arguments" - * * @uchar: %gboolean, output a uchar image + * * @uchar: `gboolean`, output a uchar image * * ::: seealso * [ctor@Image.eye], [ctor@Image.xyz]. diff --git a/libvips/draw/draw_circle.c b/libvips/draw/draw_circle.c index da2649c99d..ed3d43cfe9 100644 --- a/libvips/draw/draw_circle.c +++ b/libvips/draw/draw_circle.c @@ -288,17 +288,17 @@ vips_draw_circlev(VipsImage *image, * @cx: centre of draw_circle * @cy: centre of draw_circle * @radius: draw_circle radius - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Draws a circle on @image. * - * If @fill is %TRUE then the circle is filled, + * If @fill is `TRUE` then the circle is filled, * otherwise a 1-pixel-wide perimeter is drawn. * * @ink is an array of double containing values to draw. * * ::: tip "Optional arguments" - * * @fill: %gboolean, fill the draw_circle + * * @fill: `gboolean`, fill the draw_circle * * ::: seealso * [method@Image.draw_circle1], [method@Image.draw_line]. @@ -326,12 +326,12 @@ vips_draw_circle(VipsImage *image, * @cx: centre of draw_circle * @cy: centre of draw_circle * @radius: draw_circle radius - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.draw_circle], but just takes a single double for @ink. * * ::: tip "Optional arguments" - * * @fill: %gboolean, fill the draw_circle + * * @fill: `gboolean`, fill the draw_circle * * ::: seealso * [method@Image.draw_circle]. diff --git a/libvips/draw/draw_flood.c b/libvips/draw/draw_flood.c index da40fee57f..36d762cc08 100644 --- a/libvips/draw/draw_flood.c +++ b/libvips/draw/draw_flood.c @@ -694,7 +694,7 @@ vips_draw_floodv(VipsImage *image, * @n: length of ink array * @x: centre of circle * @y: centre of circle - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Flood-fill @image with @ink, starting at position @x, @y. * @@ -714,11 +714,11 @@ vips_draw_floodv(VipsImage *image, * * ::: tip "Optional arguments" * * @test: [class@Image], test this image - * * @equal: %gboolean, fill while equal to edge - * * @left: %gint, output left edge of bounding box of modified area - * * @top: %gint, output top edge of bounding box of modified area - * * @width: %gint, output width of bounding box of modified area - * * @height: %gint, output height of bounding box of modified area + * * @equal: `gboolean`, fill while equal to edge + * * @left: `gint`, output left edge of bounding box of modified area + * * @top: `gint`, output top edge of bounding box of modified area + * * @width: `gint`, output width of bounding box of modified area + * * @height: `gint`, output height of bounding box of modified area * * @ink is an array of double containing values to draw. * @@ -747,17 +747,17 @@ vips_draw_flood(VipsImage *image, * @ink: value to draw * @x: centre of circle * @y: centre of circle - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.draw_flood], but just takes a single double for @ink. * * ::: tip "Optional arguments" * * @test: [class@Image], test this image - * * @equal: %gboolean, fill while equal to edge - * * @left: %gint, output left edge of bounding box of modified area - * * @top: %gint, output top edge of bounding box of modified area - * * @width: %gint, output width of bounding box of modified area - * * @height: %gint, output height of bounding box of modified area + * * @equal: `gboolean`, fill while equal to edge + * * @left: `gint`, output left edge of bounding box of modified area + * * @top: `gint`, output top edge of bounding box of modified area + * * @width: `gint`, output width of bounding box of modified area + * * @height: `gint`, output height of bounding box of modified area * * ::: seealso * [method@Image.draw_flood]. diff --git a/libvips/draw/draw_image.c b/libvips/draw/draw_image.c index 852cd07714..d76d1c870c 100644 --- a/libvips/draw/draw_image.c +++ b/libvips/draw/draw_image.c @@ -305,7 +305,7 @@ vips_draw_image_init(VipsDrawImage *draw_image) * @sub: image to paint * @x: draw @sub here * @y: draw @sub here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Draw @sub on top of @image at position @x, @y. * diff --git a/libvips/draw/draw_line.c b/libvips/draw/draw_line.c index 673cac6f1f..085f75d08f 100644 --- a/libvips/draw/draw_line.c +++ b/libvips/draw/draw_line.c @@ -338,7 +338,7 @@ vips_draw_linev(VipsImage *image, * @y1: start of draw_line * @x2: end of draw_line * @y2: end of draw_line - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Draws a 1-pixel-wide line on an image. * @@ -371,7 +371,7 @@ vips_draw_line(VipsImage *image, * @y1: start of draw_line * @x2: end of draw_line * @y2: end of draw_line - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.draw_line], but just take a single double for @ink. * diff --git a/libvips/draw/draw_mask.c b/libvips/draw/draw_mask.c index b6401fddd2..b3cceeb226 100644 --- a/libvips/draw/draw_mask.c +++ b/libvips/draw/draw_mask.c @@ -377,7 +377,7 @@ vips_draw_maskv(VipsImage *image, * @mask: mask of 0/255 values showing where to plot * @x: draw mask here * @y: draw mask here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Draw @mask on the image. @mask is a monochrome 8-bit image with 0/255 * for transparent or @ink coloured points. Intermediate values blend the ink @@ -412,7 +412,7 @@ vips_draw_mask(VipsImage *image, * @mask: mask of 0/255 values showing where to plot * @x: draw mask here * @y: draw mask here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.draw_mask], but just takes a single double for @ink. * diff --git a/libvips/draw/draw_rect.c b/libvips/draw/draw_rect.c index 49e8c45def..4dc1114b45 100644 --- a/libvips/draw/draw_rect.c +++ b/libvips/draw/draw_rect.c @@ -235,14 +235,14 @@ vips_draw_rectv(VipsImage *image, * @top: area to paint * @width: area to paint * @height: area to paint - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Paint pixels within @left, @top, @width, @height in @image with @ink. * * If @fill is zero, just paint a 1-pixel-wide outline. * * ::: tip "Optional arguments" - * * @fill: %gboolean, fill the rect + * * @fill: `gboolean`, fill the rect * * ::: seealso * [method@Image.draw_circle]. @@ -272,12 +272,12 @@ vips_draw_rect(VipsImage *image, * @top: area to paint * @width: area to paint * @height: area to paint - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.draw_rect], but just take a single double for @ink. * * ::: tip "Optional arguments" - * * @fill: %gboolean, fill the rect + * * @fill: `gboolean`, fill the rect * * ::: seealso * [method@Image.draw_rect]. @@ -309,7 +309,7 @@ vips_draw_rect1(VipsImage *image, * @n: length of ink array * @x: point to paint * @y: point to paint - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.draw_rect], but draw a single pixel at @x, @y. * @@ -337,7 +337,7 @@ vips_draw_point(VipsImage *image, double *ink, int n, int x, int y, ...) * @ink: value to draw * @x: point to draw * @y: point to draw - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.draw_point], but just take a single double for @ink. * diff --git a/libvips/draw/draw_smudge.c b/libvips/draw/draw_smudge.c index 72a847df6b..3038fe2acd 100644 --- a/libvips/draw/draw_smudge.c +++ b/libvips/draw/draw_smudge.c @@ -252,7 +252,7 @@ vips_draw_smudge_init(VipsDrawSmudge *draw_smudge) * @top: point to paint * @width: area to paint * @height: area to paint - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Smudge a section of @image. Each pixel in the area @left, @top, @width, * @height is replaced by the average of the surrounding 3x3 pixels. diff --git a/libvips/foreign/analyzeload.c b/libvips/foreign/analyzeload.c index e6f4691ad1..1644c70c9a 100644 --- a/libvips/foreign/analyzeload.c +++ b/libvips/foreign/analyzeload.c @@ -156,7 +156,7 @@ vips_foreign_load_analyze_init(VipsForeignLoadAnalyze *analyze) * vips_analyzeload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Load an Analyze 6.0 file. If @filename is "fred.img", this will look for * an image header called "fred.hdr" and pixel data in "fred.img". You can @@ -167,7 +167,7 @@ vips_foreign_load_analyze_init(VipsForeignLoadAnalyze *analyze) * and attached. * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/cgifsave.c b/libvips/foreign/cgifsave.c index 6ad0bf6bc3..8e02266f10 100644 --- a/libvips/foreign/cgifsave.c +++ b/libvips/foreign/cgifsave.c @@ -1132,7 +1132,7 @@ vips_foreign_save_cgif_buffer_init(VipsForeignSaveCgifBuffer *buffer) * vips_gifsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write to a file in GIF format. * @@ -1165,20 +1165,20 @@ vips_foreign_save_cgif_buffer_init(VipsForeignSaveCgifBuffer *buffer) * kept in the output instead of combining them. * * ::: tip "Optional arguments" - * * @dither: %gdouble, quantisation dithering level - * * @effort: %gint, quantisation CPU effort - * * @bitdepth: %gint, number of bits per pixel - * * @interframe_maxerror: %gdouble, maximum inter-frame error for + * * @dither: `gdouble`, quantisation dithering level + * * @effort: `gint`, quantisation CPU effort + * * @bitdepth: `gint`, number of bits per pixel + * * @interframe_maxerror: `gdouble`, maximum inter-frame error for * transparency - * * @reuse: %gboolean, reuse palette from input - * * @interlace: %gboolean, write an interlaced (progressive) GIF - * * @interpalette_maxerror: %gdouble, maximum inter-palette error for - * palette * reusage - * * @keep_duplicate_frames: %boolean, keep duplicate frames in the output + * * @reuse: `gboolean`, reuse palette from input + * * @interlace: `gboolean`, write an interlaced (progressive) GIF + * * @interpalette_maxerror: `gdouble`, maximum inter-palette error for + * palette reusage + * * @keep_duplicate_frames: `gboolean`, keep duplicate frames in the output * instead of combining them * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -1200,7 +1200,7 @@ vips_gifsave(VipsImage *in, const char *filename, ...) * @in: image to save * @buf: (array length=len) (element-type guint8): return output buffer here * @len: (type gsize): return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.gifsave], but save to a memory buffer. * @@ -1209,16 +1209,16 @@ vips_gifsave(VipsImage *in, const char *filename, ...) * are done with it. * * ::: tip "Optional arguments" - * * @dither: %gdouble, quantisation dithering level - * * @effort: %gint, quantisation CPU effort - * * @bitdepth: %gint, number of bits per pixel - * * @interframe_maxerror: %gdouble, maximum inter-frame error for + * * @dither: `gdouble`, quantisation dithering level + * * @effort: `gint`, quantisation CPU effort + * * @bitdepth: `gint`, number of bits per pixel + * * @interframe_maxerror: `gdouble`, maximum inter-frame error for * transparency - * * @reuse: %gboolean, reuse palette from input - * * @interlace: %gboolean, write an interlaced (progressive) GIF - * * @interpalette_maxerror: %gdouble, maximum inter-palette error for - * palette * reusage - * * @keep_duplicate_frames: %boolean, keep duplicate frames in the output + * * @reuse: `gboolean`, reuse palette from input + * * @interlace: `gboolean`, write an interlaced (progressive) GIF + * * @interpalette_maxerror: `gdouble`, maximum inter-palette error for + * palette reusage + * * @keep_duplicate_frames: `gboolean`, keep duplicate frames in the output * instead of combining them * * ::: seealso @@ -1258,21 +1258,21 @@ vips_gifsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * vips_gifsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.gifsave], but save to a target. * * ::: tip "Optional arguments" - * * @dither: %gdouble, quantisation dithering level - * * @effort: %gint, quantisation CPU effort - * * @bitdepth: %gint, number of bits per pixel - * * @interframe_maxerror: %gdouble, maximum inter-frame error for + * * @dither: `gdouble`, quantisation dithering level + * * @effort: `gint`, quantisation CPU effort + * * @bitdepth: `gint`, number of bits per pixel + * * @interframe_maxerror: `gdouble`, maximum inter-frame error for * transparency - * * @reuse: %gboolean, reuse palette from input - * * @interlace: %gboolean, write an interlaced (progressive) GIF - * * @interpalette_maxerror: %gdouble, maximum inter-palette error for - * palette * reusage - * * @keep_duplicate_frames: %boolean, keep duplicate frames in the output + * * @reuse: `gboolean`, reuse palette from input + * * @interlace: `gboolean`, write an interlaced (progressive) GIF + * * @interpalette_maxerror: `gdouble`, maximum inter-palette error for + * palette reusage + * * @keep_duplicate_frames: `gboolean`, keep duplicate frames in the output * instead of combining them * * ::: seealso diff --git a/libvips/foreign/csvload.c b/libvips/foreign/csvload.c index f6f2769409..66acb7abb2 100644 --- a/libvips/foreign/csvload.c +++ b/libvips/foreign/csvload.c @@ -674,7 +674,7 @@ vips_foreign_load_csv_source_init(VipsForeignLoadCsvSource *source) * vips_csvload: * @filename: file to load * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Load a CSV (comma-separated values) file. * @@ -701,17 +701,17 @@ vips_foreign_load_csv_source_init(VipsForeignLoadCsvSource *source) * Default ;,*tab*. Separators are never run together. * * Use @fail_on to set the type of error that will cause load to fail. By - * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. + * default, loaders are permissive, that is, [enum@Vips.FailOn.NONE]. * * ::: tip "Optional arguments" - * * @skip: %gint, skip this many lines at start of file - * * @lines: %gint, read this many lines from file - * * @whitespace: %gchararray, set of whitespace characters - * * @separator: %gchararray, set of separator characters + * * @skip: `gint`, skip this many lines at start of file + * * @lines: `gint`, read this many lines from file + * * @whitespace: `gchararray`, set of whitespace characters + * * @separator: `gchararray`, set of separator characters * * @fail_on: [enum@FailOn], types of read error to fail on * * ::: seealso - * vips_image_new_from_file(), [method@Image.bandfold]. + * [ctor@Image.new_from_file], [method@Image.bandfold]. * * Returns: 0 on success, -1 on error. */ @@ -732,15 +732,15 @@ vips_csvload(const char *filename, VipsImage **out, ...) * vips_csvload_source: * @source: source to load * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.csvload], but read from a source. * * ::: tip "Optional arguments" - * * @skip: %gint, skip this many lines at start of file - * * @lines: %gint, read this many lines from file - * * @whitespace: %gchararray, set of whitespace characters - * * @separator: %gchararray, set of separator characters + * * @skip: `gint`, skip this many lines at start of file + * * @lines: `gint`, read this many lines from file + * * @whitespace: `gchararray`, set of whitespace characters + * * @separator: `gchararray`, set of separator characters * * @fail_on: [enum@FailOn], types of read error to fail on * * ::: seealso diff --git a/libvips/foreign/csvsave.c b/libvips/foreign/csvsave.c index 61e6ea85af..ec62dac5d1 100644 --- a/libvips/foreign/csvsave.c +++ b/libvips/foreign/csvsave.c @@ -338,7 +338,7 @@ vips_foreign_save_csv_target_init(VipsForeignSaveCsvTarget *target) * vips_csvsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Writes the pixels in @in to the @filename as CSV (comma-separated values). * @@ -375,7 +375,7 @@ vips_csvsave(VipsImage *in, const char *filename, ...) * vips_csvsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.csvsave], but save to a target. * diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index 05eafcea27..33b0f61796 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -2678,7 +2678,7 @@ vips_foreign_save_dz_buffer_init(VipsForeignSaveDzBuffer *buffer) * vips_dzsave: (method) * @in: image to save * @name: name to save to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Save an image as a set of tiles at various resolutions. By default dzsave * uses DeepZoom layout -- use @layout to pick other conventions. @@ -2734,25 +2734,25 @@ vips_foreign_save_dz_buffer_init(VipsForeignSaveDzBuffer *buffer) * In IIIF layout, you can set the base of the `id` property in `info.json` * with @id. The default is `https://example.com/iiif`. * - * Use @layout #VIPS_FOREIGN_DZ_LAYOUT_IIIF3 for IIIF v3 layout. + * Use @layout [enum@Vips.ForeignDzLayout.IIIF3] for IIIF v3 layout. * * ::: tip "Optional arguments" - * * @basename: %gchararray, base part of name + * * @basename: `gchararray`, base part of name * * @layout: [enum@ForeignDzLayout], directory layout convention - * * @suffix: %gchararray, suffix for tiles - * * @overlap: %gint, set tile overlap - * * @tile_size: %gint, set tile size + * * @suffix: `gchararray`, suffix for tiles + * * @overlap: `gint`, set tile overlap + * * @tile_size: `gint`, set tile size * * @background: [struct@ArrayDouble], background colour * * @depth: [enum@ForeignDzDepth], how deep to make the pyramid - * * @centre: %gboolean, centre the tiles + * * @centre: `gboolean`, centre the tiles * * @angle: [enum@Angle], rotate the image by this much * * @container: [enum@ForeignDzContainer], set container type - * * @compression: %gint, zip deflate compression level + * * @compression: `gint`, zip deflate compression level * * @region_shrink: [enum@RegionShrink], how to shrink each 2x2 region - * * @skip_blanks: %gint, skip tiles which are nearly equal to the + * * @skip_blanks: `gint`, skip tiles which are nearly equal to the * background - * * @id: %gchararray, id for IIIF properties - * * @Q: %gint, quality factor + * * @id: `gchararray`, id for IIIF properties + * * @Q: `gint`, quality factor * * ::: seealso * [method@Image.tiffsave]. @@ -2777,7 +2777,7 @@ vips_dzsave(VipsImage *in, const char *name, ...) * @in: image to save * @buf: (array length=len) (element-type guint8): return output buffer here * @len: (type gsize): return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.dzsave], but save to a memory buffer. * @@ -2789,22 +2789,22 @@ vips_dzsave(VipsImage *in, const char *name, ...) * are done with it. * * ::: tip "Optional arguments" - * * @basename: %gchararray, base part of name + * * @basename: `gchararray`, base part of name * * @layout: [enum@ForeignDzLayout], directory layout convention - * * @suffix: %gchararray, suffix for tiles - * * @overlap: %gint, set tile overlap - * * @tile_size: %gint, set tile size + * * @suffix: `gchararray`, suffix for tiles + * * @overlap: `gint`, set tile overlap + * * @tile_size: `gint`, set tile size * * @background: [struct@ArrayDouble], background colour * * @depth: [enum@ForeignDzDepth], how deep to make the pyramid - * * @centre: %gboolean, centre the tiles + * * @centre: `gboolean`, centre the tiles * * @angle: [enum@Angle], rotate the image by this much * * @container: [enum@ForeignDzContainer], set container type - * * @compression: %gint, zip deflate compression level + * * @compression: `gint`, zip deflate compression level * * @region_shrink: [enum@RegionShrink], how to shrink each 2x2 region - * * @skip_blanks: %gint, skip tiles which are nearly equal to the + * * @skip_blanks: `gint`, skip tiles which are nearly equal to the * background - * * @id: %gchararray, id for IIIF properties - * * @Q: %gint, quality factor + * * @id: `gchararray`, id for IIIF properties + * * @Q: `gint`, quality factor * * ::: seealso * [method@Image.dzsave], [method@Image.write_to_file]. @@ -2843,27 +2843,27 @@ vips_dzsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * vips_dzsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.dzsave], but save to a target. * * ::: tip "Optional arguments" - * * @basename: %gchararray, base part of name + * * @basename: `gchararray`, base part of name * * @layout: [enum@ForeignDzLayout], directory layout convention - * * @suffix: %gchararray, suffix for tiles - * * @overlap: %gint, set tile overlap - * * @tile_size: %gint, set tile size + * * @suffix: `gchararray`, suffix for tiles + * * @overlap: `gint`, set tile overlap + * * @tile_size: `gint`, set tile size * * @background: [struct@ArrayDouble], background colour * * @depth: [enum@ForeignDzDepth], how deep to make the pyramid - * * @centre: %gboolean, centre the tiles + * * @centre: `gboolean`, centre the tiles * * @angle: [enum@Angle], rotate the image by this much * * @container: [enum@ForeignDzContainer], set container type - * * @compression: %gint, zip deflate compression level + * * @compression: `gint`, zip deflate compression level * * @region_shrink: [enum@RegionShrink], how to shrink each 2x2 region - * * @skip_blanks: %gint, skip tiles which are nearly equal to the + * * @skip_blanks: `gint`, skip tiles which are nearly equal to the * background - * * @id: %gchararray, id for IIIF properties - * * @Q: %gint, quality factor + * * @id: `gchararray`, id for IIIF properties + * * @Q: `gint`, quality factor * * ::: seealso * [method@Image.dzsave], [method@Image.write_to_target]. diff --git a/libvips/foreign/fitsload.c b/libvips/foreign/fitsload.c index 44314b0872..db7d39c12e 100644 --- a/libvips/foreign/fitsload.c +++ b/libvips/foreign/fitsload.c @@ -353,7 +353,7 @@ vips_foreign_load_fits_source_init(VipsForeignLoadFitsSource *fits) * vips_fitsload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a FITS image file into a VIPS image. * @@ -366,7 +366,7 @@ vips_foreign_load_fits_source_init(VipsForeignLoadFitsSource *fits) * FITS metadata is attached with the "fits-" prefix. * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -387,7 +387,7 @@ vips_fitsload(const char *filename, VipsImage **out, ...) * vips_fitsload_source: * @source: source to load from * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.fitsload], but read from a source. * diff --git a/libvips/foreign/fitssave.c b/libvips/foreign/fitssave.c index 51dce1e140..1a039485de 100644 --- a/libvips/foreign/fitssave.c +++ b/libvips/foreign/fitssave.c @@ -158,7 +158,7 @@ vips_foreign_save_fits_init(VipsForeignSaveFits *fits) * vips_fitssave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write a VIPS image to a file in FITS format. * diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 88807976df..a8576f14f4 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -357,17 +357,17 @@ static GQuark vips__foreign_load_operation = 0; * * Some hints about the image loader. * - * #VIPS_FOREIGN_PARTIAL means that the image can be read directly from the + * [flags@Vips.ForeignFlags.PARTIAL] means that the image can be read directly from the * file without needing to be unpacked to a temporary image first. * - * #VIPS_FOREIGN_SEQUENTIAL means that the loader supports lazy reading, but + * [flags@Vips.ForeignFlags.SEQUENTIAL] means that the loader supports lazy reading, but * only top-to-bottom (sequential) access. Formats like PNG can read sets of * scanlines, for example, but only in order. * * If neither PARTIAL or SEQUENTIAL is set, the loader only supports whole * image read. Setting both PARTIAL and SEQUENTIAL is an error. * - * #VIPS_FOREIGN_BIGENDIAN means that image pixels are most-significant byte + * [flags@Vips.ForeignFlags.BIGENDIAN] means that image pixels are most-significant byte * first. Depending on the native byte order of the host machine, you may * need to swap bytes. See [method@Image.copy]. */ @@ -464,9 +464,9 @@ file_compare(VipsForeignClass *a, VipsForeignClass *b, void *user_data) * Apply a function to every [class@Foreign]Class that VIPS knows about. Foreigns * are presented to the function in priority order. * - * Like all VIPS map functions, if @fn returns %NULL, iteration continues. If - * it returns non-%NULL, iteration terminates and that value is returned. The - * map function returns %NULL if all calls return %NULL. + * Like all VIPS map functions, if @fn returns `NULL`, iteration continues. If + * it returns non-`NULL`, iteration terminates and that value is returned. The + * map function returns `NULL` if all calls return `NULL`. * * ::: seealso * [func@slist_map2]. @@ -598,9 +598,9 @@ vips_foreign_find_load_sub(VipsForeignLoadClass *load_class, * options on @filename are stripped and ignored. * * ::: seealso - * [func@Foreign.find_load_buffer], vips_image_new_from_file(). + * [func@Foreign.find_load_buffer], [ctor@Image.new_from_file]. * - * Returns: the name of an operation on success, %NULL on error + * Returns: the name of an operation on success, `NULL` on error */ const char * vips_foreign_find_load(const char *name) @@ -704,7 +704,7 @@ vips_foreign_find_load_buffer_sub(VipsForeignLoadClass *load_class, * ::: seealso * vips_image_new_from_buffer(). * - * Returns: (transfer none): the name of an operation on success, %NULL on + * Returns: (transfer none): the name of an operation on success, `NULL` on * error. */ const char * @@ -766,7 +766,7 @@ vips_foreign_find_load_source_sub(void *item, void *a, void *b) * ::: seealso * vips_image_new_from_source(). * - * Returns: (transfer none): the name of an operation on success, %NULL on + * Returns: (transfer none): the name of an operation on success, `NULL` on * error. */ const char * @@ -791,10 +791,10 @@ vips_foreign_find_load_source(VipsSource *source) * @loader: name of loader to use for test * @filename: file to test * - * Return %TRUE if @filename can be loaded by @loader. @loader is something + * Return `TRUE` if @filename can be loaded by @loader. @loader is something * like "tiffload" or "VipsForeignLoadTiff". * - * Returns: %TRUE if @filename can be loaded by @loader. + * Returns: `TRUE` if @filename can be loaded by @loader. */ gboolean vips_foreign_is_a(const char *loader, const char *filename) @@ -818,10 +818,10 @@ vips_foreign_is_a(const char *loader, const char *filename) * @data: (array length=size) (element-type guint8): pointer to the buffer to test * @size: (type gsize): size of the buffer to test * - * Return %TRUE if @data can be loaded by @loader. @loader is something + * Return `TRUE` if @data can be loaded by @loader. @loader is something * like "tiffload_buffer" or "VipsForeignLoadTiffBuffer". * - * Returns: %TRUE if @data can be loaded by @loader. + * Returns: `TRUE` if @data can be loaded by @loader. */ gboolean vips_foreign_is_a_buffer(const char *loader, const void *data, size_t size) @@ -844,10 +844,10 @@ vips_foreign_is_a_buffer(const char *loader, const void *data, size_t size) * @loader: name of loader to use for test * @source: source to test * - * Return %TRUE if @source can be loaded by @loader. @loader is something + * Return `TRUE` if @source can be loaded by @loader. @loader is something * like "tiffload_source" or "VipsForeignLoadTiffSource". * - * Returns: %TRUE if @data can be loaded by @source. + * Returns: `TRUE` if @data can be loaded by @source. */ gboolean vips_foreign_is_a_source(const char *loader, VipsSource *source) @@ -1958,7 +1958,7 @@ vips_foreign_find_save_sub(VipsForeignSaveClass *save_class, * ::: seealso * [func@Foreign.find_save_buffer], [method@Image.write_to_file]. * - * Returns: (nullable): the name of an operation on success, %NULL on error + * Returns: (nullable): the name of an operation on success, `NULL` on error */ const char * vips_foreign_find_save(const char *name) @@ -2019,7 +2019,7 @@ vips_foreign_get_suffixes_add_cb(VipsForeignSaveClass *save_class, /** * vips_foreign_get_suffixes: * - * Get a %NULL-terminated array listing all the supported suffixes. + * Get a `NULL`-terminated array listing all the supported suffixes. * * This is not the same as all the supported file types, since libvips * detects image format for load by testing the first few bytes. @@ -2029,7 +2029,7 @@ vips_foreign_get_suffixes_add_cb(VipsForeignSaveClass *save_class, * Free the return result with [func@GLib.strfreev]. * * Returns: (transfer full) (array): all supported file extensions, as a - * %NULL-terminated array. + * `NULL`-terminated array. */ gchar ** vips_foreign_get_suffixes(void) @@ -2114,7 +2114,7 @@ vips_foreign_find_save_target_sub(VipsForeignSaveClass *save_class, * ::: seealso * [method@Image.write_to_buffer]. * - * Returns: (nullable): the name of an operation on success, %NULL on error + * Returns: (nullable): the name of an operation on success, `NULL` on error */ const char * vips_foreign_find_save_target(const char *name) @@ -2173,7 +2173,7 @@ vips_foreign_find_save_buffer_sub(VipsForeignSaveClass *save_class, * ::: seealso * [method@Image.write_to_buffer]. * - * Returns: (nullable): the name of an operation on success, %NULL on error + * Returns: (nullable): the name of an operation on success, `NULL` on error */ const char * vips_foreign_find_save_buffer(const char *name) @@ -2204,7 +2204,7 @@ vips_foreign_find_save_buffer(const char *name) * vips_heifload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a HEIF image file into a VIPS image. * @@ -2218,23 +2218,23 @@ vips_foreign_find_save_buffer(const char *name) * HEIF images have a primary image. The metadata item `heif-primary` gives * the page number of the primary. * - * If @thumbnail is %TRUE, then fetch a stored thumbnail rather than the + * If @thumbnail is `TRUE`, then fetch a stored thumbnail rather than the * image. * * By default, input image dimensions are limited to 16384x16384. - * If @unlimited is %TRUE, this increases to the maximum of 65535x65535. + * If @unlimited is `TRUE`, this increases to the maximum of 65535x65535. * * The bitdepth of the heic image is recorded in the metadata item * `heif-bitdepth`. * * ::: tip "Optional arguments" - * * @page: %gint, page (top-level image number) to read - * * @n: %gint, load this many pages - * * @thumbnail: %gboolean, fetch thumbnail instead of image - * * @unlimited: %gboolean, remove all denial of service limits + * * @page: `gint`, page (top-level image number) to read + * * @n: `gint`, load this many pages + * * @thumbnail: `gboolean`, fetch thumbnail instead of image + * * @unlimited: `gboolean`, remove all denial of service limits * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -2256,7 +2256,7 @@ vips_heifload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: (type gsize): size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a HEIF image file into a VIPS image. * Exactly as [ctor@Image.heifload], but read from a memory buffer. @@ -2265,10 +2265,10 @@ vips_heifload(const char *filename, VipsImage **out, ...) * [signal@Object::postclose] signal on @out is a good place to free. * * ::: tip "Optional arguments" - * * @page: %gint, page (top-level image number) to read - * * @n: %gint, load this many pages - * * @thumbnail: %gboolean, fetch thumbnail instead of image - * * @unlimited: %gboolean, remove all denial of service limits + * * @page: `gint`, page (top-level image number) to read + * * @n: `gint`, load this many pages + * * @thumbnail: `gboolean`, fetch thumbnail instead of image + * * @unlimited: `gboolean`, remove all denial of service limits * * ::: seealso * [ctor@Image.heifload]. @@ -2299,15 +2299,15 @@ vips_heifload_buffer(void *buf, size_t len, VipsImage **out, ...) * vips_heifload_source: * @source: source to load from * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.heifload], but read from a source. * * ::: tip "Optional arguments" - * * @page: %gint, page (top-level image number) to read - * * @n: %gint, load this many pages - * * @thumbnail: %gboolean, fetch thumbnail instead of image - * * @unlimited: %gboolean, remove all denial of service limits + * * @page: `gint`, page (top-level image number) to read + * * @n: `gint`, load this many pages + * * @thumbnail: `gboolean`, fetch thumbnail instead of image + * * @unlimited: `gboolean`, remove all denial of service limits * * ::: seealso * [ctor@Image.heifload]. @@ -2331,14 +2331,14 @@ vips_heifload_source(VipsSource *source, VipsImage **out, ...) * vips_heifsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write a VIPS image to a file in HEIF format. * * Use @Q to set the compression factor. Default 50, which seems to be roughly * what the iphone uses. Q 30 gives about the same quality as JPEG Q 75. * - * Set @lossless %TRUE to switch to lossless compression. + * Set @lossless `TRUE` to switch to lossless compression. * * Use @compression to set the compression format e.g. HEVC, AVC, AV1 to use. It defaults to AV1 * if the target filename ends with ".avif", otherwise HEVC. @@ -2356,12 +2356,12 @@ vips_heifload_source(VipsSource *source, VipsImage **out, ...) * Use @encoder to set the encode library to use, e.g. aom, SVT-AV1, rav1e etc. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @bitdepth: %gint, set write bit depth to 8, 10, or 12 bits - * * @lossless: %gboolean, enable lossless encoding + * * @Q: `gint`, quality factor + * * @bitdepth: `gint`, set write bit depth to 8, 10, or 12 bits + * * @lossless: `gboolean`, enable lossless encoding * * @compression: [enum@ForeignHeifCompression], write with this * compression - * * @effort: %gint, encoding effort + * * @effort: `gint`, encoding effort * * @subsample_mode: [class@Foreign]Subsample, chroma subsampling mode * * @encoder: [class@Foreign]HeifEncoder, select encoder to use * @@ -2388,7 +2388,7 @@ vips_heifsave(VipsImage *in, const char *filename, ...) * @in: image to save * @buf: (array length=len) (element-type guint8): return output buffer here * @len: (type gsize): return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.heifsave], but save to a memory buffer. * @@ -2397,12 +2397,12 @@ vips_heifsave(VipsImage *in, const char *filename, ...) * when you are done with it. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @bitdepth: %gint, set write bit depth to 8, 10, or 12 bits - * * @lossless: %gboolean, enable lossless encoding + * * @Q: `gint`, quality factor + * * @bitdepth: `gint`, set write bit depth to 8, 10, or 12 bits + * * @lossless: `gboolean`, enable lossless encoding * * @compression: [enum@ForeignHeifCompression], write with this * compression - * * @effort: %gint, encoding effort + * * @effort: `gint`, encoding effort * * @subsample_mode: [class@Foreign]Subsample, chroma subsampling mode * * @encoder: [class@Foreign]HeifEncoder, select encoder to use * @@ -2443,17 +2443,17 @@ vips_heifsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * vips_heifsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.heifsave], but save to a target. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @bitdepth: %gint, set write bit depth to 8, 10, or 12 bits - * * @lossless: %gboolean, enable lossless encoding + * * @Q: `gint`, quality factor + * * @bitdepth: `gint`, set write bit depth to 8, 10, or 12 bits + * * @lossless: `gboolean`, enable lossless encoding * * @compression: [enum@ForeignHeifCompression], write with this * compression - * * @effort: %gint, encoding effort + * * @effort: `gint`, encoding effort * * @subsample_mode: [class@Foreign]Subsample, chroma subsampling mode * * @encoder: [class@Foreign]HeifEncoder, select encoder to use * @@ -2479,7 +2479,7 @@ vips_heifsave_target(VipsImage *in, VipsTarget *target, ...) * vips_jxlload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a JPEG-XL image. * @@ -2487,7 +2487,7 @@ vips_heifsave_target(VipsImage *in, VipsTarget *target, ...) * in future libvips versions. * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -2509,7 +2509,7 @@ vips_jxlload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: (type gsize): size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.jxlload], but read from a buffer. * @@ -2539,7 +2539,7 @@ vips_jxlload_buffer(void *buf, size_t len, VipsImage **out, ...) * vips_jxlload_source: * @source: source to load from * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.jxlload], but read from a source. * @@ -2562,7 +2562,7 @@ vips_jxlload_source(VipsSource *source, VipsImage **out, ...) * vips_jxlsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write a VIPS image to a file in JPEG-XL format. * @@ -2582,11 +2582,11 @@ vips_jxlload_source(VipsSource *source, VipsImage **out, ...) * Set @lossless to enable lossless compression. * * ::: tip "Optional arguments" - * * @tier: %gint, decode speed tier - * * @distance: %gdouble, maximum encoding error - * * @effort: %gint, encoding effort - * * @lossless: %gboolean, enables lossless compression - * * @Q: %gint, quality setting + * * @tier: `gint`, decode speed tier + * * @distance: `gdouble`, maximum encoding error + * * @effort: `gint`, encoding effort + * * @lossless: `gboolean`, enables lossless compression + * * @Q: `gint`, quality setting * * Returns: 0 on success, -1 on error. */ @@ -2608,16 +2608,16 @@ vips_jxlsave(VipsImage *in, const char *filename, ...) * @in: image to save * @buf: (array length=len) (element-type guint8): return output buffer here * @len: (type gsize): return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.jxlsave], but save to a memory buffer. * * ::: tip "Optional arguments" - * * @tier: %gint, decode speed tier - * * @distance: %gdouble, maximum encoding error - * * @effort: %gint, encoding effort - * * @lossless: %gboolean, enables lossless compression - * * @Q: %gint, quality setting + * * @tier: `gint`, decode speed tier + * * @distance: `gdouble`, maximum encoding error + * * @effort: `gint`, encoding effort + * * @lossless: `gboolean`, enables lossless compression + * * @Q: `gint`, quality setting * * ::: seealso * [method@Image.jxlsave], [method@Image.write_to_target]. @@ -2656,16 +2656,16 @@ vips_jxlsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * vips_jxlsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.jxlsave], but save to a target. * * ::: tip "Optional arguments" - * * @tier: %gint, decode speed tier - * * @distance: %gdouble, maximum encoding error - * * @effort: %gint, encoding effort - * * @lossless: %gboolean, enables lossless compression - * * @Q: %gint, quality setting + * * @tier: `gint`, decode speed tier + * * @distance: `gdouble`, maximum encoding error + * * @effort: `gint`, encoding effort + * * @lossless: `gboolean`, enables lossless compression + * * @Q: `gint`, quality setting * * ::: seealso * [method@Image.jxlsave], [method@Image.write_to_target]. @@ -2689,7 +2689,7 @@ vips_jxlsave_target(VipsImage *in, VipsTarget *target, ...) * vips_pdfload: * @filename: file to load * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Render a PDF file into a VIPS image. * @@ -2719,14 +2719,14 @@ vips_jxlsave_target(VipsImage *in, VipsTarget *target, ...) * data. Rendering occurs when pixels are accessed. * * ::: tip "Optional arguments" - * * @page: %gint, load this page, numbered from zero - * * @n: %gint, load this many pages - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor + * * @page: `gint`, load this page, numbered from zero + * * @n: `gint`, load this many pages + * * @dpi: `gdouble`, render at this DPI + * * @scale: `gdouble`, scale render by this factor * * @background: [struct@ArrayDouble], background colour * * ::: seealso - * vips_image_new_from_file(), [ctor@Image.magickload]. + * [ctor@Image.new_from_file], [ctor@Image.magickload]. * * Returns: 0 on success, -1 on error. */ @@ -2748,7 +2748,7 @@ vips_pdfload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: (type gsize): size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a PDF-formatted memory buffer into a VIPS image. Exactly as * [ctor@Image.pdfload], but read from memory. @@ -2757,10 +2757,10 @@ vips_pdfload(const char *filename, VipsImage **out, ...) * [signal@Object::postclose] signal on @out is a good place to free. * * ::: tip "Optional arguments" - * * @page: %gint, load this page, numbered from zero - * * @n: %gint, load this many pages - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor + * * @page: `gint`, load this page, numbered from zero + * * @n: `gint`, load this many pages + * * @dpi: `gdouble`, render at this DPI + * * @scale: `gdouble`, scale render by this factor * * @background: [struct@ArrayDouble], background colour * * ::: seealso @@ -2792,15 +2792,15 @@ vips_pdfload_buffer(void *buf, size_t len, VipsImage **out, ...) * vips_pdfload_source: * @source: source to load from * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.pdfload], but read from a source. * * ::: tip "Optional arguments" - * * @page: %gint, load this page, numbered from zero - * * @n: %gint, load this many pages - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor + * * @page: `gint`, load this page, numbered from zero + * * @n: `gint`, load this many pages + * * @dpi: `gdouble`, render at this DPI + * * @scale: `gdouble`, scale render by this factor * * @background: [struct@ArrayDouble], background colour * * ::: seealso @@ -2825,7 +2825,7 @@ vips_pdfload_source(VipsSource *source, VipsImage **out, ...) * vips_openslideload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a virtual slide supported by the OpenSlide library into a VIPS image. * OpenSlide supports images in Aperio, Hamamatsu, MIRAX, Sakura, Trestle, @@ -2852,14 +2852,14 @@ vips_pdfload_source(VipsSource *source, VipsImage **out, ...) * output. * * ::: tip "Optional arguments" - * * @level: %gint, load this level - * * @associated: %gchararray, load this associated image - * * @attach_associated: %gboolean, attach all associated images as metadata - * * @autocrop: %gboolean, crop to image bounds - * * @rgb: %gboolean, output RGB (not RGBA) pixels + * * @level: `gint`, load this level + * * @associated: `gchararray`, load this associated image + * * @attach_associated: `gboolean`, attach all associated images as metadata + * * @autocrop: `gboolean`, crop to image bounds + * * @rgb: `gboolean`, output RGB (not RGBA) pixels * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -2880,16 +2880,16 @@ vips_openslideload(const char *filename, VipsImage **out, ...) * vips_openslideload_source: * @source: source to load from * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.openslideload], but read from a source. * * ::: tip "Optional arguments" - * * @level: %gint, load this level - * * @associated: %gchararray, load this associated image - * * @attach_associated: %gboolean, attach all associated images as metadata - * * @autocrop: %gboolean, crop to image bounds - * * @rgb: %gboolean, output RGB (not RGBA) pixels + * * @level: `gint`, load this level + * * @associated: `gchararray`, load this associated image + * * @attach_associated: `gboolean`, attach all associated images as metadata + * * @autocrop: `gboolean`, crop to image bounds + * * @rgb: `gboolean`, output RGB (not RGBA) pixels * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/jp2kload.c b/libvips/foreign/jp2kload.c index 1313eb671e..54a84ad0c3 100644 --- a/libvips/foreign/jp2kload.c +++ b/libvips/foreign/jp2kload.c @@ -1622,7 +1622,7 @@ vips__foreign_load_jp2k_decompress(VipsImage *out, * vips_jp2kload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a JPEG2000 image. * @@ -1641,15 +1641,15 @@ vips__foreign_load_jp2k_decompress(VipsImage *out, * operation and can improve compatibility. * * Use @fail_on to set the type of error that will cause load to fail. By - * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. + * default, loaders are permissive, that is, [enum@Vips.FailOn.NONE]. * * ::: tip "Optional arguments" - * * @page: %gint, load this page - * * @oneshot: %gboolean, load pages in one-shot mode + * * @page: `gint`, load this page + * * @oneshot: `gboolean`, load pages in one-shot mode * * @fail_on: #VipsFailOn, types of read error to fail on * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -1671,7 +1671,7 @@ vips_jp2kload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: (type gsize): size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.jp2kload], but read from a buffer. * @@ -1679,8 +1679,8 @@ vips_jp2kload(const char *filename, VipsImage **out, ...) * [signal@Object::postclose] signal on @out is a good place to free. * * ::: tip "Optional arguments" - * * @page: %gint, load this page - * * @oneshot: %gboolean, load pages in one-shot mode + * * @page: `gint`, load this page + * * @oneshot: `gboolean`, load pages in one-shot mode * * @fail_on: #VipsFailOn, types of read error to fail on * * Returns: 0 on success, -1 on error. @@ -1709,13 +1709,13 @@ vips_jp2kload_buffer(void *buf, size_t len, VipsImage **out, ...) * vips_jp2kload_source: * @source: source to load from * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.jp2kload], but read from a source. * * ::: tip "Optional arguments" - * * @page: %gint, load this page - * * @oneshot: %gboolean, load pages in one-shot mode + * * @page: `gint`, load this page + * * @oneshot: `gboolean`, load pages in one-shot mode * * @fail_on: #VipsFailOn, types of read error to fail on * * Returns: 0 on success, -1 on error. diff --git a/libvips/foreign/jp2ksave.c b/libvips/foreign/jp2ksave.c index 6f2229c2c2..b92b4b58c8 100644 --- a/libvips/foreign/jp2ksave.c +++ b/libvips/foreign/jp2ksave.c @@ -1441,7 +1441,7 @@ vips__foreign_save_jp2k_compress(VipsRegion *region, * vips_jp2ksave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write a VIPS image to a file in JPEG2000 format. * @@ -1464,10 +1464,10 @@ vips__foreign_save_jp2k_compress(VipsRegion *region, * This operation always writes a pyramid. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression - * * @tile_width: %gint, tile width - * * @tile_height: %gint, tile width + * * @Q: `gint`, quality factor + * * @lossless: `gboolean`, enables lossless compression + * * @tile_width: `gint`, tile width + * * @tile_height: `gint`, tile width * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode * * ::: seealso @@ -1493,15 +1493,15 @@ vips_jp2ksave(VipsImage *in, const char *filename, ...) * @in: image to save * @buf: (array length=len) (element-type guint8): return output buffer here * @len: (type gsize): return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.jp2ksave], but save to a target. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression - * * @tile_width: %gint, tile width - * * @tile_height: %gint, tile width + * * @Q: `gint`, quality factor + * * @lossless: `gboolean`, enables lossless compression + * * @tile_width: `gint`, tile width + * * @tile_height: `gint`, tile width * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode * * ::: seealso @@ -1541,15 +1541,15 @@ vips_jp2ksave_buffer(VipsImage *in, void **buf, size_t *len, ...) * vips_jp2ksave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.jp2ksave], but save to a target. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression - * * @tile_width: %gint, tile width - * * @tile_height: %gint, tile width + * * @Q: `gint`, quality factor + * * @lossless: `gboolean`, enables lossless compression + * * @tile_width: `gint`, tile width + * * @tile_height: `gint`, tile width * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode * * ::: seealso diff --git a/libvips/foreign/jpegload.c b/libvips/foreign/jpegload.c index 6847ab152c..6a73aa5282 100644 --- a/libvips/foreign/jpegload.c +++ b/libvips/foreign/jpegload.c @@ -445,7 +445,7 @@ vips_foreign_load_jpeg_buffer_init(VipsForeignLoadJpegBuffer *buffer) * vips_jpegload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a JPEG file into a VIPS image. It can read most 8-bit JPEG images, * including CMYK and YCbCr. @@ -455,17 +455,17 @@ vips_foreign_load_jpeg_buffer_init(VipsForeignLoadJpegBuffer *buffer) * decompressing the whole image and then shrinking later. * * Use @fail_on to set the type of error that will cause load to fail. By - * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. + * default, loaders are permissive, that is, [enum@Vips.FailOn.NONE]. * - * Setting @autorotate to %TRUE will make the loader interpret the + * Setting @autorotate to `TRUE` will make the loader interpret the * orientation tag and automatically rotate the image appropriately during * load. * - * If @autorotate is %FALSE, the metadata field #VIPS_META_ORIENTATION is set + * If @autorotate is `FALSE`, the metadata field [const@META_ORIENTATION] is set * to the value of the orientation tag. Applications may read and interpret * this field * as they wish later in processing. See [method@Image.autorot]. Save - * operations will use #VIPS_META_ORIENTATION, if present, to set the + * operations will use [const@META_ORIENTATION], if present, to set the * orientation of output images. * * Example: @@ -479,14 +479,14 @@ vips_foreign_load_jpeg_buffer_init(VipsForeignLoadJpegBuffer *buffer) * * Any embedded ICC profiles are ignored: you always just get the RGB from * the file. Instead, the embedded profile will be attached to the image as - * #VIPS_META_ICC_NAME. You need to use something like + * [const@META_ICC_NAME]. You need to use something like * [method@Image.icc_import] to get CIE values from the file. * - * EXIF metadata is attached as #VIPS_META_EXIF_NAME, IPTC as - * #VIPS_META_IPTC_NAME, and XMP as #VIPS_META_XMP_NAME. + * EXIF metadata is attached as [const@META_EXIF_NAME], IPTC as + * [const@META_IPTC_NAME], and XMP as [const@META_XMP_NAME]. * * The int metadata item "jpeg-multiscan" is set to the result of - * jpeg_has_multiple_scans(). Interlaced jpeg images need a large amount of + * `jpeg_has_multiple_scans()`. Interlaced jpeg images need a large amount of * memory to load, so this field gives callers a chance to handle these * images differently. * @@ -499,9 +499,9 @@ vips_foreign_load_jpeg_buffer_init(VipsForeignLoadJpegBuffer *buffer) * "jpeg-thumbnail-data". See [method@Image.get_blob]. * * ::: tip "Optional arguments" - * * @shrink: %gint, shrink by this much on load + * * @shrink: `gint`, shrink by this much on load * * @fail_on: [enum@FailOn], types of read error to fail on - * * @autorotate: %gboolean, use exif Orientation tag to rotate the image + * * @autorotate: `gboolean`, use exif Orientation tag to rotate the image * during load * * ::: seealso @@ -527,7 +527,7 @@ vips_jpegload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: (type gsize): size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a JPEG-formatted memory block into a VIPS image. Exactly as * [ctor@Image.jpegload], but read from a memory buffer. @@ -536,9 +536,9 @@ vips_jpegload(const char *filename, VipsImage **out, ...) * [signal@Object::postclose] signal on @out is a good place to free. * * ::: tip "Optional arguments" - * * @shrink: %gint, shrink by this much on load + * * @shrink: `gint`, shrink by this much on load * * @fail_on: [enum@FailOn], types of read error to fail on - * * @autorotate: %gboolean, use exif Orientation tag to rotate the image + * * @autorotate: `gboolean`, use exif Orientation tag to rotate the image * during load * * ::: seealso @@ -570,15 +570,15 @@ vips_jpegload_buffer(void *buf, size_t len, VipsImage **out, ...) * vips_jpegload_source: * @source: source to load * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a JPEG-formatted memory block into a VIPS image. Exactly as * [ctor@Image.jpegload], but read from a source. * * ::: tip "Optional arguments" - * * @shrink: %gint, shrink by this much on load + * * @shrink: `gint`, shrink by this much on load * * @fail_on: [enum@FailOn], types of read error to fail on - * * @autorotate: %gboolean, use exif Orientation tag to rotate the image + * * @autorotate: `gboolean`, use exif Orientation tag to rotate the image * during load * * ::: seealso diff --git a/libvips/foreign/jpegsave.c b/libvips/foreign/jpegsave.c index ed331bec7f..8349cdafee 100644 --- a/libvips/foreign/jpegsave.c +++ b/libvips/foreign/jpegsave.c @@ -526,7 +526,7 @@ vips_foreign_save_jpeg_mime_init(VipsForeignSaveJpegMime *mime) * vips_jpegsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write a VIPS image to a file as JPEG. * @@ -595,24 +595,24 @@ vips_foreign_save_jpeg_mime_init(VipsForeignSaveJpegMime *mime) * The image is automatically converted to RGB, Monochrome or CMYK before * saving. * - * EXIF data is constructed from #VIPS_META_EXIF_NAME, then + * EXIF data is constructed from [const@META_EXIF_NAME], then * modified with any other related tags on the image before being written to - * the file. #VIPS_META_RESOLUTION_UNIT is used to set the EXIF resolution - * unit. #VIPS_META_ORIENTATION is used to set the EXIF orientation tag. + * the file. [const@META_RESOLUTION_UNIT] is used to set the EXIF resolution + * unit. [const@META_ORIENTATION] is used to set the EXIF orientation tag. * - * IPTC as #VIPS_META_IPTC_NAME and XMP as #VIPS_META_XMP_NAME + * IPTC as [const@META_IPTC_NAME] and XMP as [const@META_XMP_NAME] * are coded and attached. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @optimize_coding: %gboolean, compute optimal Huffman coding tables - * * @interlace: %gboolean, write an interlaced (progressive) jpeg + * * @Q: `gint`, quality factor + * * @optimize_coding: `gboolean`, compute optimal Huffman coding tables + * * @interlace: `gboolean`, write an interlaced (progressive) jpeg * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode - * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block - * * @overshoot_deringing: %gboolean, overshoot samples with extreme values - * * @optimize_scans: %gboolean, split DCT coefficients into separate scans - * * @quant_table: %gint, quantization table index - * * @restart_interval: %gint, restart interval in mcu + * * @trellis_quant: `gboolean`, apply trellis quantisation to each 8x8 block + * * @overshoot_deringing: `gboolean`, overshoot samples with extreme values + * * @optimize_scans: `gboolean`, split DCT coefficients into separate scans + * * @quant_table: `gint`, quantization table index + * * @restart_interval: `gint`, restart interval in mcu * * ::: seealso * [method@Image.jpegsave_buffer], [method@Image.write_to_file]. @@ -636,20 +636,20 @@ vips_jpegsave(VipsImage *in, const char *filename, ...) * vips_jpegsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.jpegsave], but save to a target. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @optimize_coding: %gboolean, compute optimal Huffman coding tables - * * @interlace: %gboolean, write an interlaced (progressive) jpeg + * * @Q: `gint`, quality factor + * * @optimize_coding: `gboolean`, compute optimal Huffman coding tables + * * @interlace: `gboolean`, write an interlaced (progressive) jpeg * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode - * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block - * * @overshoot_deringing: %gboolean, overshoot samples with extreme values - * * @optimize_scans: %gboolean, split DCT coefficients into separate scans - * * @quant_table: %gint, quantization table index - * * @restart_interval: %gint, restart interval in mcu + * * @trellis_quant: `gboolean`, apply trellis quantisation to each 8x8 block + * * @overshoot_deringing: `gboolean`, overshoot samples with extreme values + * * @optimize_scans: `gboolean`, split DCT coefficients into separate scans + * * @quant_table: `gint`, quantization table index + * * @restart_interval: `gint`, restart interval in mcu * * ::: seealso * [method@Image.jpegsave], [method@Image.write_to_target]. @@ -674,7 +674,7 @@ vips_jpegsave_target(VipsImage *in, VipsTarget *target, ...) * @in: image to save * @buf: (array length=len) (element-type guint8): return output buffer here * @len: (type gsize): return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.jpegsave], but save to a memory buffer. * @@ -683,15 +683,15 @@ vips_jpegsave_target(VipsImage *in, VipsTarget *target, ...) * when you are done with it. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @optimize_coding: %gboolean, compute optimal Huffman coding tables - * * @interlace: %gboolean, write an interlaced (progressive) jpeg + * * @Q: `gint`, quality factor + * * @optimize_coding: `gboolean`, compute optimal Huffman coding tables + * * @interlace: `gboolean`, write an interlaced (progressive) jpeg * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode - * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block - * * @overshoot_deringing: %gboolean, overshoot samples with extreme values - * * @optimize_scans: %gboolean, split DCT coefficients into separate scans - * * @quant_table: %gint, quantization table index - * * @restart_interval: %gint, restart interval in mcu + * * @trellis_quant: `gboolean`, apply trellis quantisation to each 8x8 block + * * @overshoot_deringing: `gboolean`, overshoot samples with extreme values + * * @optimize_scans: `gboolean`, split DCT coefficients into separate scans + * * @quant_table: `gint`, quantization table index + * * @restart_interval: `gint`, restart interval in mcu * * ::: seealso * [method@Image.jpegsave], [method@Image.write_to_file]. @@ -729,20 +729,20 @@ vips_jpegsave_buffer(VipsImage *in, void **buf, size_t *len, ...) /** * vips_jpegsave_mime: (method) * @in: image to save - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.jpegsave], but save as a mime jpeg on stdout. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @optimize_coding: %gboolean, compute optimal Huffman coding tables - * * @interlace: %gboolean, write an interlaced (progressive) jpeg + * * @Q: `gint`, quality factor + * * @optimize_coding: `gboolean`, compute optimal Huffman coding tables + * * @interlace: `gboolean`, write an interlaced (progressive) jpeg * * @subsample_mode: [enum@ForeignSubsample], chroma subsampling mode - * * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block - * * @overshoot_deringing: %gboolean, overshoot samples with extreme values - * * @optimize_scans: %gboolean, split DCT coefficients into separate scans - * * @quant_table: %gint, quantization table index - * * @restart_interval: %gint, restart interval in mcu + * * @trellis_quant: `gboolean`, apply trellis quantisation to each 8x8 block + * * @overshoot_deringing: `gboolean`, overshoot samples with extreme values + * * @optimize_scans: `gboolean`, split DCT coefficients into separate scans + * * @quant_table: `gint`, quantization table index + * * @restart_interval: `gint`, restart interval in mcu * * ::: seealso * [method@Image.jpegsave], [method@Image.write_to_file]. diff --git a/libvips/foreign/magickload.c b/libvips/foreign/magickload.c index 27920634c9..f3bf49e852 100644 --- a/libvips/foreign/magickload.c +++ b/libvips/foreign/magickload.c @@ -64,7 +64,7 @@ * vips_magickload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read in an image using libMagick, the ImageMagick library. * @@ -90,13 +90,13 @@ * on the imagemagick website. * * ::: tip "Optional arguments" - * * @page: %gint, load from this page - * * @n: %gint, load this many pages + * * @page: `gint`, load from this page + * * @n: `gint`, load this many pages * * @density: string, canvas resolution for rendering vector formats * like SVG * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -118,7 +118,7 @@ vips_magickload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read an image memory block using libMagick into a VIPS image. Exactly as * [ctor@Image.magickload], but read from a memory source. @@ -127,8 +127,8 @@ vips_magickload(const char *filename, VipsImage **out, ...) * [signal@Object::postclose] signal on @out is a good place to free. * * ::: tip "Optional arguments" - * * @page: %gint, load from this page - * * @n: %gint, load this many pages + * * @page: `gint`, load from this page + * * @n: `gint`, load this many pages * * @density: string, canvas resolution for rendering vector formats * like SVG * diff --git a/libvips/foreign/magicksave.c b/libvips/foreign/magicksave.c index b740467bd0..b32a4cc04f 100644 --- a/libvips/foreign/magicksave.c +++ b/libvips/foreign/magicksave.c @@ -58,7 +58,7 @@ * vips_magicksave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write an image using libMagick. * @@ -80,12 +80,12 @@ * and dithered if the value is within the valid range (1 to 8). * * ::: tip "Optional arguments" - * * @quality: %gint, quality factor - * * @format: %gchararray, format to save as - * * @optimize_gif_frames: %gboolean, apply GIF frames optimization - * * @optimize_gif_transparency: %gboolean, apply GIF transparency + * * @quality: `gint`, quality factor + * * @format: `gchararray`, format to save as + * * @optimize_gif_frames: `gboolean`, apply GIF frames optimization + * * @optimize_gif_transparency: `gboolean`, apply GIF transparency * optimization - * * @bitdepth: %gint, number of bits per pixel + * * @bitdepth: `gint`, number of bits per pixel * * ::: seealso * [method@Image.magicksave_buffer], [ctor@Image.magickload]. @@ -110,7 +110,7 @@ vips_magicksave(VipsImage *in, const char *filename, ...) * @in: image to save * @buf: (array length=len) (element-type guint8): return output buffer here * @len: (type gsize): return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.magicksave], but save to a memory buffer. * @@ -119,12 +119,12 @@ vips_magicksave(VipsImage *in, const char *filename, ...) * when you are done with it. * * ::: tip "Optional arguments" - * * @quality: %gint, quality factor - * * @format: %gchararray, format to save as - * * @optimize_gif_frames: %gboolean, apply GIF frames optimization - * * @optimize_gif_transparency: %gboolean, apply GIF transparency + * * @quality: `gint`, quality factor + * * @format: `gchararray`, format to save as + * * @optimize_gif_frames: `gboolean`, apply GIF frames optimization + * * @optimize_gif_transparency: `gboolean`, apply GIF transparency * optimization - * * @bitdepth: %gint, number of bits per pixel + * * @bitdepth: `gint`, number of bits per pixel * * ::: seealso * [method@Image.magicksave], [method@Image.write_to_file]. diff --git a/libvips/foreign/matload.c b/libvips/foreign/matload.c index 248433fc93..c4f971dbce 100644 --- a/libvips/foreign/matload.c +++ b/libvips/foreign/matload.c @@ -153,7 +153,7 @@ vips_foreign_load_mat_init(VipsForeignLoadMat *mat) * vips_matload: * @filename: file to load * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a Matlab save file into a VIPS image. * @@ -163,7 +163,7 @@ vips_foreign_load_mat_init(VipsForeignLoadMat *mat) * sparse matrices. * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/matrixload.c b/libvips/foreign/matrixload.c index 99db8dc2ca..7ef9c92543 100644 --- a/libvips/foreign/matrixload.c +++ b/libvips/foreign/matrixload.c @@ -474,7 +474,7 @@ vips_foreign_load_matrix_source_init(VipsForeignLoadMatrixSource *source) * vips_matrixload: * @filename: file to load * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Reads a matrix from a file. * @@ -520,7 +520,7 @@ vips_matrixload(const char *filename, VipsImage **out, ...) * vips_matrixload_source: * @source: source to load * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.matrixload], but read from a source. * diff --git a/libvips/foreign/matrixsave.c b/libvips/foreign/matrixsave.c index 2907898e3c..4a76092941 100644 --- a/libvips/foreign/matrixsave.c +++ b/libvips/foreign/matrixsave.c @@ -333,7 +333,7 @@ vips_foreign_print_matrix_init(VipsForeignPrintMatrix *matrix) * vips_matrixsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write @in to @filename in matrix format. See [ctor@Image.matrixload] for a * description of the format. @@ -360,7 +360,7 @@ vips_matrixsave(VipsImage *in, const char *filename, ...) * vips_matrixsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.matrixsave], but save to a target. * @@ -385,7 +385,7 @@ vips_matrixsave_target(VipsImage *in, VipsTarget *target, ...) /** * vips_matrixprint: (method) * @in: image to print - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Print @in to %stdout in matrix format. See [ctor@Image.matrixload] for a * description of the format. diff --git a/libvips/foreign/niftiload.c b/libvips/foreign/niftiload.c index 2412ae68f9..614d74ed6a 100644 --- a/libvips/foreign/niftiload.c +++ b/libvips/foreign/niftiload.c @@ -808,14 +808,14 @@ vips_foreign_load_nifti_source_init( * vips_niftiload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a NIFTI image file into a VIPS image. * * NIFTI metadata is attached with the "nifti-" prefix. * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -836,7 +836,7 @@ vips_niftiload(const char *filename, VipsImage **out, ...) * vips_niftiload_source: * @source: source to load from * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.niftiload], but read from a source. * diff --git a/libvips/foreign/niftisave.c b/libvips/foreign/niftisave.c index 68643e8238..15982d74e2 100644 --- a/libvips/foreign/niftisave.c +++ b/libvips/foreign/niftisave.c @@ -456,7 +456,7 @@ vips_foreign_save_nifti_init(VipsForeignSaveNifti *nifti) * vips_niftisave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write a VIPS image to a file in NIFTI format. * diff --git a/libvips/foreign/nsgifload.c b/libvips/foreign/nsgifload.c index 46a79d059a..b794afb4c7 100644 --- a/libvips/foreign/nsgifload.c +++ b/libvips/foreign/nsgifload.c @@ -924,7 +924,7 @@ vips_foreign_load_nsgif_source_init(VipsForeignLoadNsgifSource *source) * vips_gifload: * @filename: file to load * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a GIF file into a libvips image. * @@ -935,18 +935,18 @@ vips_foreign_load_nsgif_source_init(VipsForeignLoadNsgifSource *source) * document". Use [method@Image.grid] to change page layout. * * Use @fail_on to set the type of error that will cause load to fail. By - * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. + * default, loaders are permissive, that is, [enum@Vips.FailOn.NONE]. * * The output image is RGBA for GIFs containing transparent elements, RGB * otherwise. * * ::: tip "Optional arguments" - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages + * * @page: `gint`, page (frame) to read + * * @n: `gint`, load this many pages * * @fail_on: [enum@FailOn], types of read error to fail on * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -968,7 +968,7 @@ vips_gifload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: (type gsize): size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.gifload], but read from a memory buffer. * @@ -976,8 +976,8 @@ vips_gifload(const char *filename, VipsImage **out, ...) * [signal@Object::postclose] signal on @out is a good place to free. * * ::: tip "Optional arguments" - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages + * * @page: `gint`, page (frame) to read + * * @n: `gint`, load this many pages * * @fail_on: [enum@FailOn], types of read error to fail on * * ::: seealso @@ -1009,13 +1009,13 @@ vips_gifload_buffer(void *buf, size_t len, VipsImage **out, ...) * vips_gifload_source: * @source: source to load * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.gifload], but read from a source. * * ::: tip "Optional arguments" - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages + * * @page: `gint`, page (frame) to read + * * @n: `gint`, load this many pages * * @fail_on: [enum@FailOn], types of read error to fail on * * ::: seealso diff --git a/libvips/foreign/openexrload.c b/libvips/foreign/openexrload.c index 00f5fbf259..dc3c3a7aaf 100644 --- a/libvips/foreign/openexrload.c +++ b/libvips/foreign/openexrload.c @@ -164,7 +164,7 @@ vips_foreign_load_openexr_init(VipsForeignLoadOpenexr *openexr) * vips_openexrload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a OpenEXR file into a VIPS image. * @@ -176,7 +176,7 @@ vips_foreign_load_openexr_init(VipsForeignLoadOpenexr *openexr) * redone in C++. * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/pngload.c b/libvips/foreign/pngload.c index 9124505dd6..2cb943168c 100644 --- a/libvips/foreign/pngload.c +++ b/libvips/foreign/pngload.c @@ -409,7 +409,7 @@ vips_foreign_load_png_buffer_init(VipsForeignLoadPngBuffer *buffer) * vips_pngload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a PNG file into a VIPS image. It can read all png images, including 8- * and 16-bit images, 1 and 3 channel, with and without an alpha channel. @@ -418,7 +418,7 @@ vips_foreign_load_png_buffer_init(VipsForeignLoadPngBuffer *buffer) * XMP metadata. * * Use @fail_on to set the type of error that will cause load to fail. By - * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. + * default, loaders are permissive, that is, [enum@Vips.FailOn.NONE]. * * By default, the PNG loader limits the number of text and data chunks to * block some denial of service attacks. Set @unlimited to disable these @@ -426,10 +426,10 @@ vips_foreign_load_png_buffer_init(VipsForeignLoadPngBuffer *buffer) * * ::: tip "Optional arguments" * * @fail_on: [enum@FailOn], types of read error to fail on - * * @unlimited: %gboolean, Remove all denial of service limits + * * @unlimited: `gboolean`, Remove all denial of service limits * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -451,7 +451,7 @@ vips_pngload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: (type gsize): size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.pngload], but read from a PNG-formatted memory block. * @@ -460,7 +460,7 @@ vips_pngload(const char *filename, VipsImage **out, ...) * * ::: tip "Optional arguments" * * @fail_on: [enum@FailOn], types of read error to fail on - * * @unlimited: %gboolean, Remove all denial of service limits + * * @unlimited: `gboolean`, Remove all denial of service limits * * ::: seealso * [ctor@Image.pngload]. @@ -491,13 +491,13 @@ vips_pngload_buffer(void *buf, size_t len, VipsImage **out, ...) * vips_pngload_source: * @source: source to load from * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.pngload], but read from a source. * * ::: tip "Optional arguments" * * @fail_on: [enum@FailOn], types of read error to fail on - * * @unlimited: %gboolean, Remove all denial of service limits + * * @unlimited: `gboolean`, Remove all denial of service limits * * ::: seealso * [ctor@Image.pngload]. diff --git a/libvips/foreign/pngsave.c b/libvips/foreign/pngsave.c index b9cab4e86c..9d384e4806 100644 --- a/libvips/foreign/pngsave.c +++ b/libvips/foreign/pngsave.c @@ -455,13 +455,13 @@ vips_foreign_save_png_buffer_init(VipsForeignSavePngBuffer *buffer) * vips_pngsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write a VIPS image to a file as PNG. * * @compression means compress with this much effort (0 - 9). Default 6. * - * Set @interlace to %TRUE to interlace the image with ADAM7 + * Set @interlace to `TRUE` to interlace the image with ADAM7 * interlacing. Beware * than an interlaced PNG can be up to 7 times slower to write than a * non-interlaced image. @@ -473,7 +473,7 @@ vips_foreign_save_png_buffer_init(VipsForeignSavePngBuffer *buffer) * alpha before saving. Images with more than one byte per band element are * saved as 16-bit PNG, others are saved as 8-bit PNG. * - * Set @palette to %TRUE to enable palette mode for RGB or RGBA images. A + * Set @palette to `TRUE` to enable palette mode for RGB or RGBA images. A * palette will be computed with enough space for @bitdepth (1, 2, 4 or 8) * bits. Use @Q to set the optimisation effort, @dither to set the degree of * Floyd-Steinberg dithering and @effort to control the CPU effort @@ -488,17 +488,17 @@ vips_foreign_save_png_buffer_init(VipsForeignSavePngBuffer *buffer) * separate text chunks. * * ::: tip "Optional arguments" - * * @compression: %gint, compression level - * * @interlace: %gboolean, interlace image + * * @compression: `gint`, compression level + * * @interlace: `gboolean`, interlace image * * @filter: [flags@ForeignPngFilter], row filter flag(s) - * * @palette: %gboolean, enable quantisation to 8bpp palette - * * @Q: %gint, quality for 8bpp quantisation - * * @dither: %gdouble, amount of dithering for 8bpp quantization - * * @bitdepth: %gint, set write bit depth to 1, 2, 4, 8 or 16 - * * @effort: %gint, quantisation CPU effort + * * @palette: `gboolean`, enable quantisation to 8bpp palette + * * @Q: `gint`, quality for 8bpp quantisation + * * @dither: `gdouble`, amount of dithering for 8bpp quantization + * * @bitdepth: `gint`, set write bit depth to 1, 2, 4, 8 or 16 + * * @effort: `gint`, quantisation CPU effort * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -520,7 +520,7 @@ vips_pngsave(VipsImage *in, const char *filename, ...) * @in: image to save * @buf: (array length=len) (element-type guint8): return output buffer here * @len: (type gsize): return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.pngsave], but save to a memory buffer. * @@ -529,14 +529,14 @@ vips_pngsave(VipsImage *in, const char *filename, ...) * are done with it. * * ::: tip "Optional arguments" - * * @compression: %gint, compression level - * * @interlace: %gboolean, interlace image + * * @compression: `gint`, compression level + * * @interlace: `gboolean`, interlace image * * @filter: [flags@ForeignPngFilter], row filter flag(s) - * * @palette: %gboolean, enable quantisation to 8bpp palette - * * @Q: %gint, quality for 8bpp quantisation - * * @dither: %gdouble, amount of dithering for 8bpp quantization - * * @bitdepth: %gint, set write bit depth to 1, 2, 4, 8 or 16 - * * @effort: %gint, quantisation CPU effort + * * @palette: `gboolean`, enable quantisation to 8bpp palette + * * @Q: `gint`, quality for 8bpp quantisation + * * @dither: `gdouble`, amount of dithering for 8bpp quantization + * * @bitdepth: `gint`, set write bit depth to 1, 2, 4, 8 or 16 + * * @effort: `gint`, quantisation CPU effort * * ::: seealso * [method@Image.pngsave], [method@Image.write_to_file]. @@ -575,19 +575,19 @@ vips_pngsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * vips_pngsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.pngsave], but save to a target. * * ::: tip "Optional arguments" - * * @compression: %gint, compression level - * * @interlace: %gboolean, interlace image + * * @compression: `gint`, compression level + * * @interlace: `gboolean`, interlace image * * @filter: [flags@ForeignPngFilter], row filter flag(s) - * * @palette: %gboolean, enable quantisation to 8bpp palette - * * @Q: %gint, quality for 8bpp quantisation - * * @dither: %gdouble, amount of dithering for 8bpp quantization - * * @bitdepth: %gint, set write bit depth to 1, 2, 4, 8 or 16 - * * @effort: %gint, quantisation CPU effort + * * @palette: `gboolean`, enable quantisation to 8bpp palette + * * @Q: `gint`, quality for 8bpp quantisation + * * @dither: `gdouble`, amount of dithering for 8bpp quantization + * * @bitdepth: `gint`, set write bit depth to 1, 2, 4, 8 or 16 + * * @effort: `gint`, quantisation CPU effort * * ::: seealso * [method@Image.pngsave], [method@Image.write_to_target]. diff --git a/libvips/foreign/ppmload.c b/libvips/foreign/ppmload.c index 2aa01e0dbb..c239c1c9d7 100644 --- a/libvips/foreign/ppmload.c +++ b/libvips/foreign/ppmload.c @@ -905,7 +905,7 @@ vips_foreign_load_ppm_source_init(VipsForeignLoadPpmSource *source) * vips_ppmload: * @filename: file to load * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a PPM/PBM/PGM/PFM file into a VIPS image. * @@ -914,7 +914,7 @@ vips_foreign_load_ppm_source_init(VipsForeignLoadPpmSource *source) * with 0 and 255 for 0 and 1. * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -935,7 +935,7 @@ vips_ppmload(const char *filename, VipsImage **out, ...) * vips_ppmload_source: * @source: source to load * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.ppmload], but read from a source. * diff --git a/libvips/foreign/ppmsave.c b/libvips/foreign/ppmsave.c index 5ea885d418..5e0da236dd 100644 --- a/libvips/foreign/ppmsave.c +++ b/libvips/foreign/ppmsave.c @@ -791,7 +791,7 @@ vips_foreign_save_pnm_target_init(VipsForeignSavePfmTarget *target) * vips_ppmsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write a VIPS image to a file as PPM. * @@ -803,7 +803,7 @@ vips_foreign_save_pnm_target_init(VipsForeignSavePfmTarget *target) * When writing float (PFM) images the scale factor is set from the * "pfm-scale" metadata. * - * Set @ascii to %TRUE to write as human-readable ASCII. Normally data is + * Set @ascii to `TRUE` to write as human-readable ASCII. Normally data is * written in binary. * * Set @bitdepth to 1 to write a one-bit image. @@ -812,8 +812,8 @@ vips_foreign_save_pnm_target_init(VipsForeignSavePfmTarget *target) * * ::: tip "Optional arguments" * * @format: [enum@ForeignPpmFormat], format to save in - * * @ascii: %gboolean, save as ASCII rather than binary - * * @bitdepth: %gint, bitdepth to save at + * * @ascii: `gboolean`, save as ASCII rather than binary + * * @bitdepth: `gint`, bitdepth to save at * * ::: seealso * [method@Image.write_to_file]. @@ -837,14 +837,14 @@ vips_ppmsave(VipsImage *in, const char *filename, ...) * vips_ppmsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.ppmsave], but save to a target. * * ::: tip "Optional arguments" * * @format: [enum@ForeignPpmFormat], format to save in - * * @ascii: %gboolean, save as ASCII rather than binary - * * @bitdepth: %gint, bitdepth to save at + * * @ascii: `gboolean`, save as ASCII rather than binary + * * @bitdepth: `gint`, bitdepth to save at * * ::: seealso * [method@Image.ppmsave]. diff --git a/libvips/foreign/radload.c b/libvips/foreign/radload.c index 10c08d5856..6728681b20 100644 --- a/libvips/foreign/radload.c +++ b/libvips/foreign/radload.c @@ -371,7 +371,7 @@ vips_foreign_load_rad_buffer_init(VipsForeignLoadRadBuffer *buffer) * vips_radload: * @filename: file to load * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a Radiance (HDR) file into a VIPS image. * @@ -388,7 +388,7 @@ vips_foreign_load_rad_buffer_init(VipsForeignLoadRadBuffer *buffer) * Sections of this reader from Greg Ward and Radiance with kind permission. * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -410,7 +410,7 @@ vips_radload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: (type gsize): size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.radload], but read from a HDR-formatted memory block. * @@ -446,7 +446,7 @@ vips_radload_buffer(void *buf, size_t len, VipsImage **out, ...) * vips_radload_source: * @source: source to load from * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.radload], but read from a source. * diff --git a/libvips/foreign/radsave.c b/libvips/foreign/radsave.c index 0ed3ac6083..13e405cb83 100644 --- a/libvips/foreign/radsave.c +++ b/libvips/foreign/radsave.c @@ -290,7 +290,7 @@ vips_foreign_save_rad_buffer_init(VipsForeignSaveRadBuffer *buffer) * vips_radsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write a VIPS image in Radiance (HDR) format. * @@ -319,7 +319,7 @@ vips_radsave(VipsImage *in, const char *filename, ...) * @in: image to save * @buf: (array length=len) (element-type guint8): return output buffer here * @len: (type gsize): return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.radsave], but save to a memory buffer. * @@ -364,7 +364,7 @@ vips_radsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * vips_radsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.radsave], but save to a target. * diff --git a/libvips/foreign/rawload.c b/libvips/foreign/rawload.c index 3da27c2d62..491077eaed 100644 --- a/libvips/foreign/rawload.c +++ b/libvips/foreign/rawload.c @@ -199,7 +199,7 @@ vips_foreign_load_raw_init(VipsForeignLoadRaw *raw) * @width: width of image in pixels * @height: height of image in pixels * @bands: number of image bands - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation mmaps the file, setting up @out so that access to that * image will read from the file. @@ -212,12 +212,12 @@ vips_foreign_load_raw_init(VipsForeignLoadRaw *raw) * Use [method@Image.byteswap] to reverse the byte ordering if necessary. * * ::: tip "Optional arguments" - * * @offset: %guint64, offset in bytes from start of file + * * @offset: `guint64`, offset in bytes from start of file * * @format: [enum@BandFormat], set image format * * @interpretation: [enum@Interpretation], set image interpretation * * ::: seealso - * vips_image_new_from_file(), [method@Image.copy], [method@Image.byteswap]. + * [ctor@Image.new_from_file], [method@Image.copy], [method@Image.byteswap]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/rawsave.c b/libvips/foreign/rawsave.c index 18abf45cfb..bff1a6139b 100644 --- a/libvips/foreign/rawsave.c +++ b/libvips/foreign/rawsave.c @@ -327,7 +327,7 @@ vips_foreign_save_raw_buffer_init(VipsForeignSaveRawBuffer *buffer) * vips_rawsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Writes the pixels in @in to the file @filename with no header or other * metadata. @@ -355,7 +355,7 @@ vips_rawsave(VipsImage *in, const char *filename, ...) * @in: image to save * @buf: (array length=len) (element-type guint8): return output buffer here * @len: (type gsize): return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.rawsave], but save to a memory buffer. * @@ -400,7 +400,7 @@ vips_rawsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * vips_rawsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.rawsave], but save to a target. * diff --git a/libvips/foreign/svgload.c b/libvips/foreign/svgload.c index d839225802..6596aefabf 100644 --- a/libvips/foreign/svgload.c +++ b/libvips/foreign/svgload.c @@ -1038,7 +1038,7 @@ vips_foreign_load_svg_buffer_init(VipsForeignLoadSvgBuffer *buffer) * vips_svgload: * @filename: file to load * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Render a SVG file into a VIPS image. * @@ -1058,13 +1058,13 @@ vips_foreign_load_svg_buffer_init(VipsForeignLoadSvgBuffer *buffer) * User Origin. This feature requires librsvg 2.48.0 or later. * * ::: tip "Optional arguments" - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor - * * @unlimited: %gboolean, allow SVGs of any size - * * @stylesheet: %gchararray, custom CSS + * * @dpi: `gdouble`, render at this DPI + * * @scale: `gdouble`, scale render by this factor + * * @unlimited: `gboolean`, allow SVGs of any size + * * @stylesheet: `gchararray`, custom CSS * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -1086,7 +1086,7 @@ vips_svgload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: (type gsize): size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a SVG-formatted memory block into a VIPS image. Exactly as * [ctor@Image.svgload], but read from a memory buffer. @@ -1095,10 +1095,10 @@ vips_svgload(const char *filename, VipsImage **out, ...) * [signal@Object::postclose] signal on @out is a good place to free. * * ::: tip "Optional arguments" - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor - * * @unlimited: %gboolean, allow SVGs of any size - * * @stylesheet: %gchararray, custom CSS + * * @dpi: `gdouble`, render at this DPI + * * @scale: `gdouble`, scale render by this factor + * * @unlimited: `gboolean`, allow SVGs of any size + * * @stylesheet: `gchararray`, custom CSS * * ::: seealso * [ctor@Image.svgload]. @@ -1129,16 +1129,16 @@ vips_svgload_buffer(void *buf, size_t len, VipsImage **out, ...) * vips_svgload_string: * @str: string to load * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.svgload], but read from a string. This function * takes a copy of the string. * * ::: tip "Optional arguments" - * * @dpi: %gdouble, render at this DPI - * * @scale: %gdouble, scale render by this factor - * * @unlimited: %gboolean, allow SVGs of any size - * * @stylesheet: %gchararray, custom CSS + * * @dpi: `gdouble`, render at this DPI + * * @scale: `gdouble`, scale render by this factor + * * @unlimited: `gboolean`, allow SVGs of any size + * * @stylesheet: `gchararray`, custom CSS * * ::: seealso * [ctor@Image.svgload]. @@ -1169,7 +1169,7 @@ vips_svgload_string(const char *str, VipsImage **out, ...) * vips_svgload_source: * @source: source to load from * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.svgload], but read from a source. * diff --git a/libvips/foreign/tiffload.c b/libvips/foreign/tiffload.c index b7bdbe5cb4..31f774f90f 100644 --- a/libvips/foreign/tiffload.c +++ b/libvips/foreign/tiffload.c @@ -475,7 +475,7 @@ vips_foreign_load_tiff_buffer_init(VipsForeignLoadTiffBuffer *buffer) * vips_tiffload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a TIFF file into a VIPS image. * @@ -488,18 +488,18 @@ vips_foreign_load_tiff_buffer_init(VipsForeignLoadTiffBuffer *buffer) * * @n means load this many pages. By default a single page is read. All the * pages must have the same dimensions, and they are loaded as a tall, thin - * "toilet roll" image. The #VIPS_META_PAGE_HEIGHT metadata + * "toilet roll" image. The [const@META_PAGE_HEIGHT] metadata * tag gives the height in pixels of each page. Use -1 to load all pages. * - * Setting @autorotate to %TRUE will make the loader interpret the + * Setting @autorotate to `TRUE` will make the loader interpret the * orientation tag and automatically rotate the image appropriately during * load. * - * If @autorotate is %FALSE, the metadata field #VIPS_META_ORIENTATION is set + * If @autorotate is `FALSE`, the metadata field [const@META_ORIENTATION] is set * to the value of the orientation tag. Applications may read and interpret * this field * as they wish later in processing. See [method@Image.autorot]. Save - * operations will use #VIPS_META_ORIENTATION, if present, to set the + * operations will use [const@META_ORIENTATION], if present, to set the * orientation of output images. * * If @autorotate is TRUE, the image will be rotated upright during load and @@ -511,30 +511,30 @@ vips_foreign_load_tiff_buffer_init(VipsForeignLoadTiffBuffer *buffer) * bioformats-style image pyramids. * * Use @fail_on to set the type of error that will cause load to fail. By - * default, loaders are permissive, that is, #VIPS_FAIL_ON_NONE. + * default, loaders are permissive, that is, [enum@Vips.FailOn.NONE]. * * When using libtiff 4.7.0+, the TIFF loader will limit memory allocation * for tag processing to 20MB to prevent denial of service attacks. * Set @unlimited to remove this limit. * * Any ICC profile is read and attached to the VIPS image as - * #VIPS_META_ICC_NAME. Any XMP metadata is read and attached to the image - * as #VIPS_META_XMP_NAME. Any IPTC is attached as #VIPS_META_IPTC_NAME. The + * [const@META_ICC_NAME]. Any XMP metadata is read and attached to the image + * as [const@META_XMP_NAME]. Any IPTC is attached as [const@META_IPTC_NAME]. The * image description is - * attached as #VIPS_META_IMAGEDESCRIPTION. Data in the photoshop tag is - * attached as #VIPS_META_PHOTOSHOP_NAME. + * attached as [const@META_IMAGEDESCRIPTION]. Data in the photoshop tag is + * attached as [const@META_PHOTOSHOP_NAME]. * * ::: tip "Optional arguments" - * * @page: %gint, load this page - * * @n: %gint, load this many pages - * * @autorotate: %gboolean, use orientation tag to rotate the image + * * @page: `gint`, load this page + * * @n: `gint`, load this many pages + * * @autorotate: `gboolean`, use orientation tag to rotate the image * during load - * * @subifd: %gint, select this subifd index + * * @subifd: `gint`, select this subifd index * * @fail_on: [enum@FailOn], types of read error to fail on - * * @unlimited: %gboolean, remove all denial of service limits + * * @unlimited: `gboolean`, remove all denial of service limits * * ::: seealso - * vips_image_new_from_file(), [method@Image.autorot]. + * [ctor@Image.new_from_file], [method@Image.autorot]. * * Returns: 0 on success, -1 on error. */ @@ -556,7 +556,7 @@ vips_tiffload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: (type gsize): size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a TIFF-formatted memory block into a VIPS image. Exactly as * [ctor@Image.tiffload], but read from a memory source. @@ -565,13 +565,13 @@ vips_tiffload(const char *filename, VipsImage **out, ...) * [signal@Object::postclose] signal on @out is a good place to free. * * ::: tip "Optional arguments" - * * @page: %gint, load this page - * * @n: %gint, load this many pages - * * @autorotate: %gboolean, use orientation tag to rotate the image + * * @page: `gint`, load this page + * * @n: `gint`, load this many pages + * * @autorotate: `gboolean`, use orientation tag to rotate the image * during load - * * @subifd: %gint, select this subifd index + * * @subifd: `gint`, select this subifd index * * @fail_on: [enum@FailOn], types of read error to fail on - * * @unlimited: %gboolean, remove all denial of service limits + * * @unlimited: `gboolean`, remove all denial of service limits * * ::: seealso * [ctor@Image.tiffload]. @@ -602,18 +602,18 @@ vips_tiffload_buffer(void *buf, size_t len, VipsImage **out, ...) * vips_tiffload_source: * @source: source to load * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.tiffload], but read from a source. * * ::: tip "Optional arguments" - * * @page: %gint, load this page - * * @n: %gint, load this many pages - * * @autorotate: %gboolean, use orientation tag to rotate the image + * * @page: `gint`, load this page + * * @n: `gint`, load this many pages + * * @autorotate: `gboolean`, use orientation tag to rotate the image * during load - * * @subifd: %gint, select this subifd index + * * @subifd: `gint`, select this subifd index * * @fail_on: [enum@FailOn], types of read error to fail on - * * @unlimited: %gboolean, remove all denial of service limits + * * @unlimited: `gboolean`, remove all denial of service limits * * ::: seealso * [ctor@Image.tiffload]. diff --git a/libvips/foreign/tiffsave.c b/libvips/foreign/tiffsave.c index 89ea48b538..4cb66e919d 100644 --- a/libvips/foreign/tiffsave.c +++ b/libvips/foreign/tiffsave.c @@ -606,13 +606,13 @@ vips_foreign_save_tiff_buffer_init(VipsForeignSaveTiffBuffer *buffer) * vips_tiffsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write a VIPS image to a file as TIFF. * - * If @in has the #VIPS_META_PAGE_HEIGHT metadata item, this is assumed to be a + * If @in has the [const@META_PAGE_HEIGHT] metadata item, this is assumed to be a * "toilet roll" image. It will be - * written as series of pages, each #VIPS_META_PAGE_HEIGHT pixels high. + * written as series of pages, each [const@META_PAGE_HEIGHT] pixels high. * * Use @compression to set the tiff compression. Currently jpeg, packbits, * fax4, lzw, none, deflate, webp and zstd are supported. The default is no @@ -631,7 +631,7 @@ vips_foreign_save_tiff_buffer_init(VipsForeignSaveTiffBuffer *buffer) * set WEBP lossless mode on. Use @Q to set the WEBP compression level. * * Use @predictor to set the predictor for lzw, deflate and zstd compression. - * It defaults to #VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL, meaning horizontal + * It defaults to [enum@Vips.ForeignTiffPredictor.HORIZONTAL], meaning horizontal * differencing. Please refer to the libtiff * specifications for further discussion of various predictors. * @@ -664,7 +664,7 @@ vips_foreign_save_tiff_buffer_init(VipsForeignSaveTiffBuffer *buffer) * Use @resunit to override the default resolution unit. * The default * resolution unit is taken from the header field - * #VIPS_META_RESOLUTION_UNIT. If this field is not set, then + * [const@META_RESOLUTION_UNIT]. If this field is not set, then * VIPS defaults to cm. * * Use @xres and @yres to override the default horizontal and vertical @@ -675,14 +675,14 @@ vips_foreign_save_tiff_buffer_init(VipsForeignSaveTiffBuffer *buffer) * format that allows more than 4GB in a file. * * Set @properties to write all vips metadata to the IMAGEDESCRIPTION tag as - * xml. If @properties is not set, the value of #VIPS_META_IMAGEDESCRIPTION is + * xml. If @properties is not set, the value of [const@META_IMAGEDESCRIPTION] is * used instead. * - * The value of #VIPS_META_XMP_NAME is written to - * the XMP tag. #VIPS_META_ORIENTATION (if set) is used to set the value of + * The value of [const@META_XMP_NAME] is written to + * the XMP tag. [const@META_ORIENTATION] (if set) is used to set the value of * the orientation - * tag. #VIPS_META_IPTC (if set) is used to set the value of the IPTC tag. - * #VIPS_META_PHOTOSHOP_NAME (if set) is used to set the value of the PHOTOSHOP + * tag. [const@META_IPTC_NAME] (if set) is used to set the value of the IPTC tag. + * [const@META_PHOTOSHOP_NAME] (if set) is used to set the value of the PHOTOSHOP * tag. * * By default, pyramid layers are saved as consecutive pages. @@ -694,25 +694,25 @@ vips_foreign_save_tiff_buffer_init(VipsForeignSaveTiffBuffer *buffer) * * ::: tip "Optional arguments" * * @compression: use this [enum@ForeignTiffCompression] - * * @Q: %gint quality factor + * * @Q: `gint`, quality factor * * @predictor: use this [enum@ForeignTiffPredictor] - * * @tile: %gboolean, set %TRUE to write a tiled tiff - * * @tile_width: %gint for tile size - * * @tile_height: %gint for tile size - * * @pyramid: %gboolean, write an image pyramid - * * @bitdepth: %int, change bit depth to 1,2, or 4 bit - * * @miniswhite: %gboolean, write 1-bit images as MINISWHITE + * * @tile: `gboolean`, set `TRUE` to write a tiled tiff + * * @tile_width: `gint`, for tile size + * * @tile_height: `gint`, for tile size + * * @pyramid: `gboolean`, write an image pyramid + * * @bitdepth: `gint`, change bit depth to 1,2, or 4 bit + * * @miniswhite: `gboolean`, write 1-bit images as MINISWHITE * * @resunit: [enum@ForeignTiffResunit] for resolution unit - * * @xres: %gdouble horizontal resolution in pixels/mm - * * @yres: %gdouble vertical resolution in pixels/mm - * * @bigtiff: %gboolean, write a BigTiff file - * * @properties: %gboolean, set %TRUE to write an IMAGEDESCRIPTION tag + * * @xres: `gdouble` horizontal resolution in pixels/mm + * * @yres: `gdouble` vertical resolution in pixels/mm + * * @bigtiff: `gboolean`, write a BigTiff file + * * @properties: `gboolean`, set `TRUE` to write an IMAGEDESCRIPTION tag * * @region_shrink: [enum@RegionShrink] How to shrink each 2x2 region. - * * @level: %gint, Zstd or Deflate (zlib) compression level - * * @lossless: %gboolean, WebP lossless mode + * * @level: `gint`, Zstd or Deflate (zlib) compression level + * * @lossless: `gboolean`, WebP lossless mode * * @depth: [enum@ForeignDzDepth] how deep to make the pyramid - * * @subifd: %gboolean write pyr layers as sub-ifds - * * @premultiply: %gboolean write premultiplied alpha + * * @subifd: `gboolean` write pyr layers as sub-ifds + * * @premultiply: `gboolean` write premultiplied alpha * * ::: seealso * [ctor@Image.tiffload], [method@Image.write_to_file]. @@ -737,7 +737,7 @@ vips_tiffsave(VipsImage *in, const char *filename, ...) * @in: image to save * @buf: (array length=len) (element-type guint8): return output buffer here * @len: (type gsize): return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.tiffsave], but save to a memory buffer. * @@ -747,25 +747,25 @@ vips_tiffsave(VipsImage *in, const char *filename, ...) * * ::: tip "Optional arguments" * * @compression: use this [enum@ForeignTiffCompression] - * * @Q: %gint quality factor + * * @Q: `gint`, quality factor * * @predictor: use this [enum@ForeignTiffPredictor] - * * @tile: %gboolean, set %TRUE to write a tiled tiff - * * @tile_width: %gint for tile size - * * @tile_height: %gint for tile size - * * @pyramid: %gboolean, write an image pyramid - * * @bitdepth: %int, change bit depth to 1,2, or 4 bit - * * @miniswhite: %gboolean, write 1-bit images as MINISWHITE + * * @tile: `gboolean`, set `TRUE` to write a tiled tiff + * * @tile_width: `gint`, for tile size + * * @tile_height: `gint`, for tile size + * * @pyramid: `gboolean`, write an image pyramid + * * @bitdepth: `gint`, change bit depth to 1,2, or 4 bit + * * @miniswhite: `gboolean`, write 1-bit images as MINISWHITE * * @resunit: [enum@ForeignTiffResunit] for resolution unit - * * @xres: %gdouble horizontal resolution in pixels/mm - * * @yres: %gdouble vertical resolution in pixels/mm - * * @bigtiff: %gboolean, write a BigTiff file - * * @properties: %gboolean, set %TRUE to write an IMAGEDESCRIPTION tag + * * @xres: `gdouble` horizontal resolution in pixels/mm + * * @yres: `gdouble` vertical resolution in pixels/mm + * * @bigtiff: `gboolean`, write a BigTiff file + * * @properties: `gboolean`, set `TRUE` to write an IMAGEDESCRIPTION tag * * @region_shrink: [enum@RegionShrink] How to shrink each 2x2 region. - * * @level: %gint, Zstd or Deflate (zlib) compression level - * * @lossless: %gboolean, WebP lossless mode + * * @level: `gint`, Zstd or Deflate (zlib) compression level + * * @lossless: `gboolean`, WebP lossless mode * * @depth: [enum@ForeignDzDepth] how deep to make the pyramid - * * @subifd: %gboolean write pyr layers as sub-ifds - * * @premultiply: %gboolean write premultiplied alpha + * * @subifd: `gboolean` write pyr layers as sub-ifds + * * @premultiply: `gboolean` write premultiplied alpha * * ::: seealso * [method@Image.tiffsave], [method@Image.write_to_file]. @@ -804,31 +804,31 @@ vips_tiffsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * vips_tiffsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.tiffsave], but save to a target. * * ::: tip "Optional arguments" * * @compression: use this [enum@ForeignTiffCompression] - * * @Q: %gint quality factor + * * @Q: `gint`, quality factor * * @predictor: use this [enum@ForeignTiffPredictor] - * * @tile: %gboolean, set %TRUE to write a tiled tiff - * * @tile_width: %gint for tile size - * * @tile_height: %gint for tile size - * * @pyramid: %gboolean, write an image pyramid - * * @bitdepth: %int, change bit depth to 1,2, or 4 bit - * * @miniswhite: %gboolean, write 1-bit images as MINISWHITE + * * @tile: `gboolean`, set `TRUE` to write a tiled tiff + * * @tile_width: `gint`, for tile size + * * @tile_height: `gint`, for tile size + * * @pyramid: `gboolean`, write an image pyramid + * * @bitdepth: `gint`, change bit depth to 1,2, or 4 bit + * * @miniswhite: `gboolean`, write 1-bit images as MINISWHITE * * @resunit: [enum@ForeignTiffResunit] for resolution unit - * * @xres: %gdouble horizontal resolution in pixels/mm - * * @yres: %gdouble vertical resolution in pixels/mm - * * @bigtiff: %gboolean, write a BigTiff file - * * @properties: %gboolean, set %TRUE to write an IMAGEDESCRIPTION tag + * * @xres: `gdouble` horizontal resolution in pixels/mm + * * @yres: `gdouble` vertical resolution in pixels/mm + * * @bigtiff: `gboolean`, write a BigTiff file + * * @properties: `gboolean`, set `TRUE` to write an IMAGEDESCRIPTION tag * * @region_shrink: [enum@RegionShrink] How to shrink each 2x2 region. - * * @level: %gint, Zstd or Deflate (zlib) compression level - * * @lossless: %gboolean, WebP lossless mode + * * @level: `gint`, Zstd or Deflate (zlib) compression level + * * @lossless: `gboolean`, WebP lossless mode * * @depth: [enum@ForeignDzDepth] how deep to make the pyramid - * * @subifd: %gboolean write pyr layers as sub-ifds - * * @premultiply: %gboolean write premultiplied alpha + * * @subifd: `gboolean` write pyr layers as sub-ifds + * * @premultiply: `gboolean` write premultiplied alpha * * ::: seealso * [method@Image.tiffsave], [method@Image.write_to_target]. diff --git a/libvips/foreign/vipsload.c b/libvips/foreign/vipsload.c index 35d1c170a3..7c04c20f65 100644 --- a/libvips/foreign/vipsload.c +++ b/libvips/foreign/vipsload.c @@ -325,7 +325,7 @@ vips_foreign_load_vips_source_init(VipsForeignLoadVipsSource *source) * vips_vipsload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read in a vips image. * @@ -351,7 +351,7 @@ vips_vipsload(const char *filename, VipsImage **out, ...) * vips_vipsload_source: * @source: source to load from * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.vipsload], but read from a source. * diff --git a/libvips/foreign/vipssave.c b/libvips/foreign/vipssave.c index 0c4cc5bc6b..6c496b8d0b 100644 --- a/libvips/foreign/vipssave.c +++ b/libvips/foreign/vipssave.c @@ -266,7 +266,7 @@ vips_foreign_save_vips_target_init(VipsForeignSaveVipsTarget *target) * vips_vipssave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write @in to @filename in VIPS format. * @@ -292,7 +292,7 @@ vips_vipssave(VipsImage *in, const char *filename, ...) * vips_vipssave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.vipssave], but save to a target. * diff --git a/libvips/foreign/webpload.c b/libvips/foreign/webpload.c index b8a1791f51..8ddda46250 100644 --- a/libvips/foreign/webpload.c +++ b/libvips/foreign/webpload.c @@ -439,7 +439,7 @@ vips_foreign_load_webp_buffer_init(VipsForeignLoadWebpBuffer *buffer) * vips_webpload: * @filename: file to load * @out: (out): decompressed image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a WebP file into a VIPS image. * @@ -457,12 +457,12 @@ vips_foreign_load_webp_buffer_init(VipsForeignLoadWebpBuffer *buffer) * The loader supports ICC, EXIF and XMP metadata. * * ::: tip "Optional arguments" - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages - * * @scale: %gdouble, scale by this much on load + * * @page: `gint`, page (frame) to read + * * @n: `gint`, load this many pages + * * @scale: `gdouble`, scale by this much on load * * ::: seealso - * vips_image_new_from_file(). + * [ctor@Image.new_from_file]. * * Returns: 0 on success, -1 on error. */ @@ -484,7 +484,7 @@ vips_webpload(const char *filename, VipsImage **out, ...) * @buf: (array length=len) (element-type guint8): memory area to load * @len: (type gsize): size of memory area * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Read a WebP-formatted memory block into a VIPS image. Exactly as * [ctor@Image.webpload], but read from a memory buffer. @@ -493,9 +493,9 @@ vips_webpload(const char *filename, VipsImage **out, ...) * [signal@Object::postclose] signal on @out is a good place to free. * * ::: tip "Optional arguments" - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages - * * @scale: %gdouble, scale by this much on load + * * @page: `gint`, page (frame) to read + * * @n: `gint`, load this many pages + * * @scale: `gdouble`, scale by this much on load * * ::: seealso * [ctor@Image.webpload] @@ -526,14 +526,14 @@ vips_webpload_buffer(void *buf, size_t len, VipsImage **out, ...) * vips_webpload_source: * @source: source to load from * @out: (out): image to write - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.webpload], but read from a source. * * ::: tip "Optional arguments" - * * @page: %gint, page (frame) to read - * * @n: %gint, load this many pages - * * @scale: %gdouble, scale by this much on load + * * @page: `gint`, page (frame) to read + * * @n: `gint`, load this many pages + * * @scale: `gdouble`, scale by this much on load * * ::: seealso * [ctor@Image.webpload] diff --git a/libvips/foreign/webpsave.c b/libvips/foreign/webpsave.c index a7667bec8e..7284b64c16 100644 --- a/libvips/foreign/webpsave.c +++ b/libvips/foreign/webpsave.c @@ -1171,7 +1171,7 @@ vips_foreign_save_webp_mime_init(VipsForeignSaveWebpMime *mime) * vips_webpsave: (method) * @in: image to save * @filename: file to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Write an image to a file in WebP format. * @@ -1180,7 +1180,7 @@ vips_foreign_save_webp_mime_init(VipsForeignSaveWebpMime *mime) * default 75. * * Use @preset to hint the image type to the lossy compressor. The default is - * #VIPS_FOREIGN_WEBP_PRESET_DEFAULT. + * [enum@Vips.ForeignWebpPreset.DEFAULT]. * * Set @smart_subsample to enable high quality chroma subsampling. * @@ -1220,22 +1220,22 @@ vips_foreign_save_webp_mime_init(VipsForeignSaveWebpMime *mime) * loops for the animation and the frame delays. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression + * * @Q: `gint`, quality factor + * * @lossless: `gboolean`, enables lossless compression * * @preset: [enum@ForeignWebpPreset], choose lossy compression preset - * * @smart_subsample: %gboolean, enables high quality chroma subsampling - * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking + * * @smart_subsample: `gboolean`, enables high quality chroma subsampling + * * @smart_deblock: `gboolean`, enables auto-adjusting of the deblocking * filter - * * @near_lossless: %gboolean, preprocess in lossless mode (controlled + * * @near_lossless: `gboolean`, preprocess in lossless mode (controlled * by Q) - * * @alpha_q: %gint, set alpha quality in lossless mode - * * @effort: %gint, level of CPU effort to reduce file size - * * @target_size: %gint, desired target size in bytes - * * @passes: %gint, number of entropy-analysis passes - * * @min_size: %gboolean, minimise size - * * @mixed: %gboolean, allow both lossy and lossless encoding - * * @kmin: %gint, minimum number of frames between keyframes - * * @kmax: %gint, maximum number of frames between keyframes + * * @alpha_q: `gint`, set alpha quality in lossless mode + * * @effort: `gint`, level of CPU effort to reduce file size + * * @target_size: `gint`, desired target size in bytes + * * @passes: `gint`, number of entropy-analysis passes + * * @min_size: `gboolean`, minimise size + * * @mixed: `gboolean`, allow both lossy and lossless encoding + * * @kmin: `gint`, minimum number of frames between keyframes + * * @kmax: `gint`, maximum number of frames between keyframes * * ::: seealso * [ctor@Image.webpload], [method@Image.write_to_file]. @@ -1260,7 +1260,7 @@ vips_webpsave(VipsImage *in, const char *filename, ...) * @in: image to save * @buf: (out) (array length=len) (element-type guint8): return output buffer here * @len: return output length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.webpsave], but save to a memory buffer. * @@ -1269,22 +1269,22 @@ vips_webpsave(VipsImage *in, const char *filename, ...) * are done with it. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression + * * @Q: `gint`, quality factor + * * @lossless: `gboolean`, enables lossless compression * * @preset: [enum@ForeignWebpPreset], choose lossy compression preset - * * @smart_subsample: %gboolean, enables high quality chroma subsampling - * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking + * * @smart_subsample: `gboolean`, enables high quality chroma subsampling + * * @smart_deblock: `gboolean`, enables auto-adjusting of the deblocking * filter - * * @near_lossless: %gboolean, preprocess in lossless mode (controlled + * * @near_lossless: `gboolean`, preprocess in lossless mode (controlled * by Q) - * * @alpha_q: %gint, set alpha quality in lossless mode - * * @effort: %gint, level of CPU effort to reduce file size - * * @target_size: %gint, desired target size in bytes - * * @passes: %gint, number of entropy-analysis passes - * * @min_size: %gboolean, minimise size - * * @mixed: %gboolean, allow both lossy and lossless encoding - * * @kmin: %gint, minimum number of frames between keyframes - * * @kmax: %gint, maximum number of frames between keyframes + * * @alpha_q: `gint`, set alpha quality in lossless mode + * * @effort: `gint`, level of CPU effort to reduce file size + * * @target_size: `gint`, desired target size in bytes + * * @passes: `gint`, number of entropy-analysis passes + * * @min_size: `gboolean`, minimise size + * * @mixed: `gboolean`, allow both lossy and lossless encoding + * * @kmin: `gint`, minimum number of frames between keyframes + * * @kmax: `gint`, maximum number of frames between keyframes * * ::: seealso * [method@Image.webpsave]. @@ -1322,27 +1322,27 @@ vips_webpsave_buffer(VipsImage *in, void **buf, size_t *len, ...) /** * vips_webpsave_mime: (method) * @in: image to save - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.webpsave], but save as a mime webp on stdout. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression + * * @Q: `gint`, quality factor + * * @lossless: `gboolean`, enables lossless compression * * @preset: [enum@ForeignWebpPreset], choose lossy compression preset - * * @smart_subsample: %gboolean, enables high quality chroma subsampling - * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking + * * @smart_subsample: `gboolean`, enables high quality chroma subsampling + * * @smart_deblock: `gboolean`, enables auto-adjusting of the deblocking * filter - * * @near_lossless: %gboolean, preprocess in lossless mode (controlled + * * @near_lossless: `gboolean`, preprocess in lossless mode (controlled * by Q) - * * @alpha_q: %gint, set alpha quality in lossless mode - * * @effort: %gint, level of CPU effort to reduce file size - * * @target_size: %gint, desired target size in bytes - * * @passes: %gint, number of entropy-analysis passes - * * @min_size: %gboolean, minimise size - * * @mixed: %gboolean, allow both lossy and lossless encoding - * * @kmin: %gint, minimum number of frames between keyframes - * * @kmax: %gint, maximum number of frames between keyframes + * * @alpha_q: `gint`, set alpha quality in lossless mode + * * @effort: `gint`, level of CPU effort to reduce file size + * * @target_size: `gint`, desired target size in bytes + * * @passes: `gint`, number of entropy-analysis passes + * * @min_size: `gboolean`, minimise size + * * @mixed: `gboolean`, allow both lossy and lossless encoding + * * @kmin: `gint`, minimum number of frames between keyframes + * * @kmax: `gint`, maximum number of frames between keyframes * * ::: seealso * [method@Image.webpsave], [method@Image.write_to_file]. @@ -1366,27 +1366,27 @@ vips_webpsave_mime(VipsImage *in, ...) * vips_webpsave_target: (method) * @in: image to save * @target: save image to this target - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * As [method@Image.webpsave], but save to a target. * * ::: tip "Optional arguments" - * * @Q: %gint, quality factor - * * @lossless: %gboolean, enables lossless compression + * * @Q: `gint`, quality factor + * * @lossless: `gboolean`, enables lossless compression * * @preset: [enum@ForeignWebpPreset], choose lossy compression preset - * * @smart_subsample: %gboolean, enables high quality chroma subsampling - * * @smart_deblock: %gboolean, enables auto-adjusting of the deblocking + * * @smart_subsample: `gboolean`, enables high quality chroma subsampling + * * @smart_deblock: `gboolean`, enables auto-adjusting of the deblocking * filter - * * @near_lossless: %gboolean, preprocess in lossless mode (controlled + * * @near_lossless: `gboolean`, preprocess in lossless mode (controlled * by Q) - * * @alpha_q: %gint, set alpha quality in lossless mode - * * @effort: %gint, level of CPU effort to reduce file size - * * @target_size: %gint, desired target size in bytes - * * @passes: %gint, number of entropy-analysis passes - * * @min_size: %gboolean, minimise size - * * @mixed: %gboolean, allow both lossy and lossless encoding - * * @kmin: %gint, minimum number of frames between keyframes - * * @kmax: %gint, maximum number of frames between keyframes + * * @alpha_q: `gint`, set alpha quality in lossless mode + * * @effort: `gint`, level of CPU effort to reduce file size + * * @target_size: `gint`, desired target size in bytes + * * @passes: `gint`, number of entropy-analysis passes + * * @min_size: `gboolean`, minimise size + * * @mixed: `gboolean`, allow both lossy and lossless encoding + * * @kmin: `gint`, minimum number of frames between keyframes + * * @kmax: `gint`, maximum number of frames between keyframes * * ::: seealso * [method@Image.webpsave]. diff --git a/libvips/freqfilt/freqmult.c b/libvips/freqfilt/freqmult.c index 9e28cb0444..5d5df8bb81 100644 --- a/libvips/freqfilt/freqmult.c +++ b/libvips/freqfilt/freqmult.c @@ -143,7 +143,7 @@ vips_freqmult_init(VipsFreqmult *freqmult) * @in: input image * @mask: mask image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Multiply @in by @mask in Fourier space. * diff --git a/libvips/freqfilt/fwfft.c b/libvips/freqfilt/fwfft.c index 342368ea2f..dfab2b728b 100644 --- a/libvips/freqfilt/fwfft.c +++ b/libvips/freqfilt/fwfft.c @@ -363,7 +363,7 @@ vips_fwfft_init(VipsFwfft *fwfft) * vips_fwfft: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Transform an image to Fourier space. * diff --git a/libvips/freqfilt/invfft.c b/libvips/freqfilt/invfft.c index 16347e563e..79052c57c0 100644 --- a/libvips/freqfilt/invfft.c +++ b/libvips/freqfilt/invfft.c @@ -282,7 +282,7 @@ vips_invfft_init(VipsInvfft *invfft) * vips_invfft: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Transform an image from Fourier space to real space. * @@ -293,7 +293,7 @@ vips_invfft_init(VipsInvfft *invfft) * available when VIPS was configured, these functions will fail. * * ::: tip "Optional arguments" - * * @real: %gboolean, only output the real part + * * @real: `gboolean`, only output the real part * * ::: seealso * [method@Image.fwfft]. diff --git a/libvips/freqfilt/phasecor.c b/libvips/freqfilt/phasecor.c index c2be7afcf5..39d2a1bf30 100644 --- a/libvips/freqfilt/phasecor.c +++ b/libvips/freqfilt/phasecor.c @@ -124,7 +124,7 @@ vips_phasecor_init(VipsPhasecor *phasecor) * @in1: first input image * @in2: second input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Convert the two input images to Fourier space, calculate phase-correlation, * back to real space. diff --git a/libvips/freqfilt/spectrum.c b/libvips/freqfilt/spectrum.c index 500f0f4796..31ac6792e0 100644 --- a/libvips/freqfilt/spectrum.c +++ b/libvips/freqfilt/spectrum.c @@ -110,7 +110,7 @@ vips_spectrum_init(VipsSpectrum *spectrum) * vips_spectrum: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make a displayable (ie. 8-bit unsigned int) power spectrum. * diff --git a/libvips/histogram/case.c b/libvips/histogram/case.c index 42df9fb16f..d27e21d2ab 100644 --- a/libvips/histogram/case.c +++ b/libvips/histogram/case.c @@ -280,7 +280,7 @@ vips_casev(VipsImage *index, VipsImage **cases, VipsImage **out, int n, * @cases: (array length=n): array of case images * @out: (out): output image * @n: number of case images - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Use values in @index to select pixels from @cases. * diff --git a/libvips/histogram/hist_cum.c b/libvips/histogram/hist_cum.c index 6d71f9a0b3..e7d648f1a8 100644 --- a/libvips/histogram/hist_cum.c +++ b/libvips/histogram/hist_cum.c @@ -170,7 +170,7 @@ vips_hist_cum_init(VipsHistCum *hist_cum) * vips_hist_cum: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Form cumulative histogram. * diff --git a/libvips/histogram/hist_entropy.c b/libvips/histogram/hist_entropy.c index 794366edc5..bf0126aa5c 100644 --- a/libvips/histogram/hist_entropy.c +++ b/libvips/histogram/hist_entropy.c @@ -130,7 +130,7 @@ vips_hist_entropy_init(VipsHistEntropy *entropy) * vips_hist_entropy: (method) * @in: input histogram * @out: (out): image entropy - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Estimate image entropy from a histogram. Entropy is calculated as: * diff --git a/libvips/histogram/hist_equal.c b/libvips/histogram/hist_equal.c index 7b2c5207fa..f54f7606f4 100644 --- a/libvips/histogram/hist_equal.c +++ b/libvips/histogram/hist_equal.c @@ -140,7 +140,7 @@ vips_hist_equal_init(VipsHistEqual *equal) * vips_hist_equal: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Histogram-equalise @in. * @@ -149,7 +149,7 @@ vips_hist_equal_init(VipsHistEqual *equal) * input format. * * ::: tip "Optional arguments" - * * @band: %gint, band to equalise + * * @band: `gint`, band to equalise * * Returns: 0 on success, -1 on error */ diff --git a/libvips/histogram/hist_ismonotonic.c b/libvips/histogram/hist_ismonotonic.c index 52c091a03e..ca632b5455 100644 --- a/libvips/histogram/hist_ismonotonic.c +++ b/libvips/histogram/hist_ismonotonic.c @@ -137,7 +137,7 @@ vips_hist_ismonotonic_init(VipsHistIsmonotonic *ismonotonic) * vips_hist_ismonotonic: (method) * @in: lookup-table to test * @out: (out): set non-zero if @in is monotonic - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Test @in for monotonicity. @out is set non-zero if @in is monotonic. * diff --git a/libvips/histogram/hist_local.c b/libvips/histogram/hist_local.c index 8956cabd70..bb5786bd87 100644 --- a/libvips/histogram/hist_local.c +++ b/libvips/histogram/hist_local.c @@ -402,7 +402,7 @@ vips_hist_local_init(VipsHistLocal *local) * @out: (out): output image * @width: width of region * @height: height of region - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Performs local histogram equalisation on @in using a * window of size @width by @height centered on the input pixel. @@ -416,7 +416,7 @@ vips_hist_local_init(VipsHistLocal *local) * contrast limiting is usually called CLAHE. * * ::: tip "Optional arguments" - * * @max_slope: %gint, maximum brightening + * * @max_slope: `gint`, maximum brightening * * ::: seealso * [method@Image.hist_equal]. diff --git a/libvips/histogram/hist_match.c b/libvips/histogram/hist_match.c index 978cd8b8bb..780fab68b3 100644 --- a/libvips/histogram/hist_match.c +++ b/libvips/histogram/hist_match.c @@ -180,7 +180,7 @@ vips_hist_match_init(VipsHistMatch *match) * @in: input histogram * @ref: reference histogram * @out: (out): output histogram - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Adjust @in to match @ref. If @in and @ref are normalised * cumulative histograms, @out will be a LUT that adjusts the PDF of the image diff --git a/libvips/histogram/hist_norm.c b/libvips/histogram/hist_norm.c index bf1a36b178..1d2ac279b8 100644 --- a/libvips/histogram/hist_norm.c +++ b/libvips/histogram/hist_norm.c @@ -159,7 +159,7 @@ vips_hist_norm_init(VipsHistNorm *hist_norm) * vips_hist_norm: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Normalise histogram. The maximum of each band becomes equal to the maximum * index, so for example the max for a uchar image becomes 255. diff --git a/libvips/histogram/hist_plot.c b/libvips/histogram/hist_plot.c index e6243f0856..fb1b8b54ee 100644 --- a/libvips/histogram/hist_plot.c +++ b/libvips/histogram/hist_plot.c @@ -351,7 +351,7 @@ vips_hist_plot_init(VipsHistPlot *hist_plot) * vips_hist_plot: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Plot a 1 by any or any by 1 image file as a max by any or * any by max image using these rules: diff --git a/libvips/histogram/maplut.c b/libvips/histogram/maplut.c index 86f86e2791..d2de901908 100644 --- a/libvips/histogram/maplut.c +++ b/libvips/histogram/maplut.c @@ -777,7 +777,7 @@ vips_maplut_init(VipsMaplut *maplut) * @in: input image * @out: (out): output image * @lut: look-up table - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Map an image through another image acting as a LUT (Look Up Table). * The lut may have any type and the output image will be that type. @@ -801,7 +801,7 @@ vips_maplut_init(VipsMaplut *maplut) * the output will have the same number of bands as @lut. * * ::: tip "Optional arguments" - * * @band: %gint, apply one-band @lut to this band of @in + * * @band: `gint`, apply one-band @lut to this band of @in * * ::: seealso * [method@Image.hist_find], [ctor@Image.identity]. diff --git a/libvips/histogram/percent.c b/libvips/histogram/percent.c index 4199bd9b41..e214ae1fda 100644 --- a/libvips/histogram/percent.c +++ b/libvips/histogram/percent.c @@ -136,7 +136,7 @@ vips_percent_init(VipsPercent *percent) * @in: input image * @percent: threshold percentage * @threshold: (out): output threshold value - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * [method@Image.percent] returns (through the @threshold parameter) the threshold * below which there are @percent values of @in. For example: diff --git a/libvips/histogram/stdif.c b/libvips/histogram/stdif.c index 5e637df867..e442008d02 100644 --- a/libvips/histogram/stdif.c +++ b/libvips/histogram/stdif.c @@ -364,7 +364,7 @@ vips_stdif_init(VipsStdif *stdif) * @out: (out): output image * @width: width of region * @height: height of region - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * [method@Image.stdif] performs statistical differencing according to the * formula given in page 45 of the book "An Introduction to Digital Image @@ -397,10 +397,10 @@ vips_stdif_init(VipsStdif *stdif) * input. * * ::: tip "Optional arguments" - * * @a: %gdouble, weight of new mean - * * @m0: %gdouble, target mean - * * @b: %gdouble, weight of new deviation - * * @s0: %gdouble, target deviation + * * @a: `gdouble`, weight of new mean + * * @m0: `gdouble`, target mean + * * @b: `gdouble`, weight of new deviation + * * @s0: `gdouble`, target deviation * * ::: seealso * [method@Image.hist_local]. diff --git a/libvips/include/vips/almostdeprecated.h b/libvips/include/vips/almostdeprecated.h index d62de53fa2..fe25e7d4e2 100644 --- a/libvips/include/vips/almostdeprecated.h +++ b/libvips/include/vips/almostdeprecated.h @@ -364,7 +364,7 @@ int im_rank_raw(IMAGE *in, IMAGE *out, int xsize, int ysize, int order); * * Set jpeg subsampling mode. * - * DEPRECATED: use #VipsForeignSubsample + * DEPRECATED: use [enum@ForeignSubsample] */ typedef enum { VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO, diff --git a/libvips/include/vips/arithmetic.h b/libvips/include/vips/arithmetic.h index 239abba227..7a039e9726 100644 --- a/libvips/include/vips/arithmetic.h +++ b/libvips/include/vips/arithmetic.h @@ -43,24 +43,24 @@ extern "C" { /** * VipsOperationMath: - * @VIPS_OPERATION_MATH_SIN: sin(), angles in degrees - * @VIPS_OPERATION_MATH_COS: cos(), angles in degrees - * @VIPS_OPERATION_MATH_TAN: tan(), angles in degrees - * @VIPS_OPERATION_MATH_ASIN: asin(), angles in degrees - * @VIPS_OPERATION_MATH_ACOS: acos(), angles in degrees - * @VIPS_OPERATION_MATH_ATAN: atan(), angles in degrees + * @VIPS_OPERATION_MATH_SIN: `sin()`, angles in degrees + * @VIPS_OPERATION_MATH_COS: `cos()`, angles in degrees + * @VIPS_OPERATION_MATH_TAN: `tan()`, angles in degrees + * @VIPS_OPERATION_MATH_ASIN: `asin()`, angles in degrees + * @VIPS_OPERATION_MATH_ACOS: `acos()`, angles in degrees + * @VIPS_OPERATION_MATH_ATAN: `atan()`, angles in degrees * @VIPS_OPERATION_MATH_LOG: log base e * @VIPS_OPERATION_MATH_LOG10: log base 10 * @VIPS_OPERATION_MATH_EXP: e to the something * @VIPS_OPERATION_MATH_EXP10: 10 to the something - * @VIPS_OPERATION_MATH_SINH: sinh(), angles in radians - * @VIPS_OPERATION_MATH_COSH: cosh(), angles in radians - * @VIPS_OPERATION_MATH_TANH: tanh(), angles in radians - * @VIPS_OPERATION_MATH_ASINH: asinh(), angles in radians - * @VIPS_OPERATION_MATH_ACOSH: acosh(), angles in radians - * @VIPS_OPERATION_MATH_ATANH: atanh(), angles in radians + * @VIPS_OPERATION_MATH_SINH: `sinh()`, angles in radians + * @VIPS_OPERATION_MATH_COSH: `cosh()`, angles in radians + * @VIPS_OPERATION_MATH_TANH: `tanh()`, angles in radians + * @VIPS_OPERATION_MATH_ASINH: `asinh()`, angles in radians + * @VIPS_OPERATION_MATH_ACOSH: `acosh()`, angles in radians + * @VIPS_OPERATION_MATH_ATANH: `atanh()`, angles in radians * - * See also: vips_math(). + * See also: [method@Image.math]. */ typedef enum { VIPS_OPERATION_MATH_SIN, @@ -84,11 +84,11 @@ typedef enum { /** * VipsOperationMath2: - * @VIPS_OPERATION_MATH2_POW: pow(left, right) - * @VIPS_OPERATION_MATH2_WOP: pow(right, left) - * @VIPS_OPERATION_MATH2_ATAN2: atan2(left, right) + * @VIPS_OPERATION_MATH2_POW: `pow(left, right)` + * @VIPS_OPERATION_MATH2_WOP: `pow(right, left)` + * @VIPS_OPERATION_MATH2_ATAN2: `atan2(left, right)` * - * See also: vips_math(). + * See also: [method@Image.math]. */ typedef enum { VIPS_OPERATION_MATH2_POW, @@ -103,7 +103,7 @@ typedef enum { * @VIPS_OPERATION_ROUND_FLOOR: largest integral value not greater than * @VIPS_OPERATION_ROUND_CEIL: the smallest integral value not less than * - * See also: vips_round(). + * See also: [method@Image.round]. */ typedef enum { VIPS_OPERATION_ROUND_RINT, @@ -114,14 +114,14 @@ typedef enum { /** * VipsOperationRelational: - * @VIPS_OPERATION_RELATIONAL_EQUAL: == - * @VIPS_OPERATION_RELATIONAL_NOTEQ: != - * @VIPS_OPERATION_RELATIONAL_LESS: < - * @VIPS_OPERATION_RELATIONAL_LESSEQ: <= - * @VIPS_OPERATION_RELATIONAL_MORE: > - * @VIPS_OPERATION_RELATIONAL_MOREEQ: >= + * @VIPS_OPERATION_RELATIONAL_EQUAL: `==` + * @VIPS_OPERATION_RELATIONAL_NOTEQ: `!=` + * @VIPS_OPERATION_RELATIONAL_LESS: `<` + * @VIPS_OPERATION_RELATIONAL_LESSEQ: `<=` + * @VIPS_OPERATION_RELATIONAL_MORE: `>` + * @VIPS_OPERATION_RELATIONAL_MOREEQ: `>=` * - * See also: vips_relational(). + * See also: [method@Image.relational]. */ typedef enum { VIPS_OPERATION_RELATIONAL_EQUAL, @@ -135,13 +135,13 @@ typedef enum { /** * VipsOperationBoolean: - * @VIPS_OPERATION_BOOLEAN_AND: & - * @VIPS_OPERATION_BOOLEAN_OR: | - * @VIPS_OPERATION_BOOLEAN_EOR: ^ - * @VIPS_OPERATION_BOOLEAN_LSHIFT: >> - * @VIPS_OPERATION_BOOLEAN_RSHIFT: << + * @VIPS_OPERATION_BOOLEAN_AND: `&` + * @VIPS_OPERATION_BOOLEAN_OR: `|` + * @VIPS_OPERATION_BOOLEAN_EOR: `^` + * @VIPS_OPERATION_BOOLEAN_LSHIFT: `>>` + * @VIPS_OPERATION_BOOLEAN_RSHIFT: `<<` * - * See also: vips_boolean(). + * See also: [method@Image.boolean]. */ typedef enum { VIPS_OPERATION_BOOLEAN_AND, @@ -158,7 +158,7 @@ typedef enum { * @VIPS_OPERATION_COMPLEX_RECT: convert to rectangular coordinates * @VIPS_OPERATION_COMPLEX_CONJ: complex conjugate * - * See also: vips_complex(). + * See also: [method@Image.complex]. */ typedef enum { VIPS_OPERATION_COMPLEX_POLAR, @@ -171,7 +171,7 @@ typedef enum { * VipsOperationComplex2: * @VIPS_OPERATION_COMPLEX2_CROSS_PHASE: convert to polar coordinates * - * See also: vips_complex2(). + * See also: [method@Image.complex2]. */ typedef enum { VIPS_OPERATION_COMPLEX2_CROSS_PHASE, @@ -183,7 +183,7 @@ typedef enum { * @VIPS_OPERATION_COMPLEXGET_REAL: get real component * @VIPS_OPERATION_COMPLEXGET_IMAG: get imaginary component * - * See also: vips_complexget(). + * See also: [method@Image.complexget]. */ typedef enum { VIPS_OPERATION_COMPLEXGET_REAL, diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index c09093874e..ab6f3ebfa2 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -115,8 +115,8 @@ typedef enum /*< flags >*/ { * How sensitive loaders are to errors, from never stop (very insensitive), to * stop on the smallest warning (very sensitive). * - * Each one implies the ones before it, so #VIPS_FAIL_ON_ERROR implies - * #VIPS_FAIL_ON_TRUNCATED. + * Each one implies the ones before it, so [enum@Vips.FailOn.ERROR] implies + * [enum@Vips.FailOn.TRUNCATED]. */ typedef enum { VIPS_FAIL_ON_NONE, @@ -205,7 +205,7 @@ typedef struct _VipsForeignLoadClass { /* Is a file in this format. * - * This function should return %TRUE if the file contains an image of + * This function should return `TRUE` if the file contains an image of * this type. If you don't define this function, #VipsForeignLoad * will use @suffs instead. */ @@ -213,14 +213,14 @@ typedef struct _VipsForeignLoadClass { /* Is a buffer in this format. * - * This function should return %TRUE if the buffer contains an image of + * This function should return `TRUE` if the buffer contains an image of * this type. */ gboolean (*is_a_buffer)(const void *data, size_t size); /* Is a stream in this format. * - * This function should return %TRUE if the stream contains an image of + * This function should return `TRUE` if the stream contains an image of * this type. */ gboolean (*is_a_source)(VipsSource *source); @@ -317,7 +317,7 @@ void vips_foreign_load_invalidate(VipsImage *image); * * The set of image types supported by a saver. * - * See also: #VipsForeignSave. + * See also: [class@ForeignSave]. */ typedef enum /*< flags >*/ { VIPS_FOREIGN_SAVEABLE_MONO = 1, @@ -744,15 +744,15 @@ int vips_pngsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * * The netpbm file format to save as. * - * #VIPS_FOREIGN_PPM_FORMAT_PBM images are single bit. + * [enum@Vips.ForeignPpmFormat.PBM] images are single bit. * - * #VIPS_FOREIGN_PPM_FORMAT_PGM images are 8, 16, or 32-bits, one band. + * [enum@Vips.ForeignPpmFormat.PGM] images are 8, 16, or 32-bits, one band. * - * #VIPS_FOREIGN_PPM_FORMAT_PPM images are 8, 16, or 32-bits, three bands. + * [enum@Vips.ForeignPpmFormat.PPM] images are 8, 16, or 32-bits, three bands. * - * #VIPS_FOREIGN_PPM_FORMAT_PFM images are 32-bit float pixels. + * [enum@Vips.ForeignPpmFormat.PFM] images are 32-bit float pixels. * - * #VIPS_FOREIGN_PPM_FORMAT_PNM images are anymap images -- the image format + * [enum@Vips.ForeignPpmFormat.PNM] images are anymap images -- the image format * is used to pick the saver. * */ @@ -979,7 +979,7 @@ int vips_dzsave_target(VipsImage *in, VipsTarget *target, ...) * * The compression format to use inside a HEIF container. * - * This is assumed to use the same numbering as %heif_compression_format. + * This is assumed to use the same numbering as `heif_compression_format`. */ typedef enum { VIPS_FOREIGN_HEIF_COMPRESSION_HEVC = 1, diff --git a/libvips/include/vips/type.h b/libvips/include/vips/type.h index 8e5968c7d0..8514aab023 100644 --- a/libvips/include/vips/type.h +++ b/libvips/include/vips/type.h @@ -49,7 +49,7 @@ typedef struct _VipsThing { /** * VIPS_TYPE_THING: * - * The #GType for a #VipsThing. + * The [alias@GObject.Type] for a #VipsThing. */ #define VIPS_TYPE_THING (vips_thing_get_type()) VIPS_API @@ -135,7 +135,7 @@ void *vips_area_get_data(VipsArea *area, /** * VIPS_TYPE_AREA: * - * The #GType for a #VipsArea. + * The [alias@GObject.Type] for a [struct@Area]. */ #define VIPS_TYPE_AREA (vips_area_get_type()) #define VIPS_AREA(X) ((VipsArea *) (X)) @@ -145,7 +145,7 @@ GType vips_area_get_type(void); /** * VIPS_TYPE_SAVE_STRING: * - * The #GType for a #VipsSaveString. + * The [alias@GObject.Type] for a [struct@SaveString]. */ #define VIPS_TYPE_SAVE_STRING (vips_save_string_get_type()) VIPS_API @@ -158,7 +158,7 @@ typedef struct _VipsSaveString { /** * VIPS_TYPE_REF_STRING: * - * The #GType for a #VipsRefString. + * The [alias@GObject.Type] for a [struct@RefString]. */ #define VIPS_TYPE_REF_STRING (vips_ref_string_get_type()) @@ -176,7 +176,7 @@ GType vips_ref_string_get_type(void); /** * VIPS_TYPE_BLOB: * - * The %GType for a #VipsBlob. + * The [alias@GObject.Type] for a [struct@Blob]. */ #define VIPS_TYPE_BLOB (vips_blob_get_type()) @@ -200,7 +200,7 @@ GType vips_blob_get_type(void); /** * VIPS_TYPE_ARRAY_DOUBLE: * - * The #GType for a #VipsArrayDouble. + * The [alias@GObject.Type] for a [struct@ArrayDouble]. */ #define VIPS_TYPE_ARRAY_DOUBLE (vips_array_double_get_type()) @@ -220,7 +220,7 @@ GType vips_array_double_get_type(void); /** * VIPS_TYPE_ARRAY_INT: * - * The #GType for a #VipsArrayInt. + * The [alias@GObject.Type] for a [struct@ArrayInt]. */ #define VIPS_TYPE_ARRAY_INT (vips_array_int_get_type()) @@ -240,7 +240,7 @@ GType vips_array_int_get_type(void); /** * VIPS_TYPE_ARRAY_IMAGE: * - * The #GType for a #VipsArrayImage. + * The [alias@GObject.Type] for a [struct@ArrayImage]. */ #define VIPS_TYPE_ARRAY_IMAGE (vips_array_image_get_type()) diff --git a/libvips/iofuncs/buf.c b/libvips/iofuncs/buf.c index 70d0a81d6b..2c064cbd22 100644 --- a/libvips/iofuncs/buf.c +++ b/libvips/iofuncs/buf.c @@ -246,7 +246,7 @@ vips_buf_init_dynamic(VipsBuf *buf, int mx) * is the low-level append operation: functions like [method@Buf.appendf] build * on top of this. * - * Returns: %FALSE on overflow, %TRUE otherwise. + * Returns: `FALSE` on overflow, `TRUE` otherwise. */ gboolean vips_buf_appendns(VipsBuf *buf, const char *str, int sz) @@ -300,7 +300,7 @@ vips_buf_appendns(VipsBuf *buf, const char *str, int sz) * * Append the whole of @str to @buf. * - * Returns: %FALSE on overflow, %TRUE otherwise. + * Returns: `FALSE` on overflow, `TRUE` otherwise. */ gboolean vips_buf_appends(VipsBuf *buf, const char *str) @@ -315,7 +315,7 @@ vips_buf_appends(VipsBuf *buf, const char *str) * * Append a single character @ch to @buf. * - * Returns: %FALSE on overflow, %TRUE otherwise. + * Returns: `FALSE` on overflow, `TRUE` otherwise. */ gboolean vips_buf_appendc(VipsBuf *buf, char ch) @@ -336,7 +336,7 @@ vips_buf_appendc(VipsBuf *buf, char ch) * * Swap the rightmost occurrence of @o for @n. * - * Returns: %FALSE on overflow, %TRUE otherwise. + * Returns: `FALSE` on overflow, `TRUE` otherwise. */ gboolean vips_buf_change(VipsBuf *buf, const char *old, const char *new) @@ -378,7 +378,7 @@ vips_buf_change(VipsBuf *buf, const char *old, const char *new) * * Remove the last character, if it's @ch. * - * Returns: %FALSE on failure, %TRUE otherwise. + * Returns: `FALSE` on failure, `TRUE` otherwise. */ gboolean vips_buf_removec(VipsBuf *buf, char ch) @@ -401,7 +401,7 @@ vips_buf_removec(VipsBuf *buf, char ch) * * Append to @buf, args as [`vprintf()`](man:vprintf(3)). * - * Returns: %FALSE on overflow, %TRUE otherwise. + * Returns: `FALSE` on overflow, `TRUE` otherwise. */ gboolean vips_buf_vappendf(VipsBuf *buf, const char *fmt, va_list ap) @@ -438,7 +438,7 @@ vips_buf_vappendf(VipsBuf *buf, const char *fmt, va_list ap) * * Format the string and append to @buf. * - * Returns: %FALSE on overflow, %TRUE otherwise. + * Returns: `FALSE` on overflow, `TRUE` otherwise. */ gboolean vips_buf_appendf(VipsBuf *buf, const char *fmt, ...) @@ -460,7 +460,7 @@ vips_buf_appendf(VipsBuf *buf, const char *fmt, ...) * * Append a double, non-localised. Useful for config files etc. * - * Returns: %FALSE on overflow, %TRUE otherwise. + * Returns: `FALSE` on overflow, `TRUE` otherwise. */ gboolean vips_buf_appendg(VipsBuf *buf, double g) @@ -480,7 +480,7 @@ vips_buf_appendg(VipsBuf *buf, double g) * Append a number. If the number is -ve, add brackets. Needed for * building function arguments. * - * Returns: %FALSE on overflow, %TRUE otherwise. + * Returns: `FALSE` on overflow, `TRUE` otherwise. */ gboolean vips_buf_appendd(VipsBuf *buf, int d) @@ -502,7 +502,7 @@ vips_buf_appendd(VipsBuf *buf, int d) * Use [method@Image.get_as_string] to make a text representation of a field. * That will base64-encode blobs, for example. * - * Returns: %FALSE on overflow, %TRUE otherwise. + * Returns: `FALSE` on overflow, `TRUE` otherwise. */ gboolean vips_buf_appendgv(VipsBuf *buf, GValue *value) @@ -662,7 +662,7 @@ vips_buf_appendgv(VipsBuf *buf, GValue *value) * Turn a number of bytes into a sensible string ... eg "12", "12KB", "12MB", * "12GB" etc. * - * Returns: %FALSE on overflow, %TRUE otherwise. + * Returns: `FALSE` on overflow, `TRUE` otherwise. */ gboolean vips_buf_append_size(VipsBuf *buf, size_t n) @@ -711,7 +711,7 @@ vips_buf_append_size(VipsBuf *buf, size_t n) * * Return the contents of the buffer as a C string. * - * Returns: the %NULL-terminated contents of the buffer. This is a pointer to + * Returns: the `NULL`-terminated contents of the buffer. This is a pointer to * the memory managed by the buffer and must not be freed. */ const char * @@ -728,7 +728,7 @@ vips_buf_all(VipsBuf *buf) * * Trim to just the first line (excluding "\n"). * - * Returns: the %NULL-terminated contents of the buffer. This is a pointer to + * Returns: the `NULL`-terminated contents of the buffer. This is a pointer to * the memory managed by the buffer and must not be freed. */ const char * @@ -746,7 +746,7 @@ vips_buf_firstline(VipsBuf *buf) * vips_buf_is_empty: * @buf: the buffer * - * Returns: %TRUE if the buffer is empty. + * Returns: `TRUE` if the buffer is empty. */ gboolean vips_buf_is_empty(VipsBuf *buf) @@ -758,7 +758,7 @@ vips_buf_is_empty(VipsBuf *buf) * vips_buf_is_full: * @buf: the buffer * - * Returns: %TRUE if the buffer is full. + * Returns: `TRUE` if the buffer is full. */ gboolean vips_buf_is_full(VipsBuf *buf) diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index c2ce36ec5a..bb3a9fa00d 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -1166,7 +1166,7 @@ vips_cache_set_max_files(int max_files) /** * vips_cache_set_dump: - * @dump: if %TRUE, dump the operation cache on exit + * @dump: if `TRUE`, dump the operation cache on exit * * Handy for debugging. Print the operation cache to stdout just before exit. * @@ -1181,7 +1181,7 @@ vips_cache_set_dump(gboolean dump) /** * vips_cache_set_trace: - * @trace: if %TRUE, trace the operation cache + * @trace: if `TRUE`, trace the operation cache * * Handy for debugging. Print operation cache actions to stdout as we run. * diff --git a/libvips/iofuncs/dbuf.c b/libvips/iofuncs/dbuf.c index 6d3d3556e7..bc87b500e3 100644 --- a/libvips/iofuncs/dbuf.c +++ b/libvips/iofuncs/dbuf.c @@ -66,7 +66,7 @@ vips_dbuf_init(VipsDbuf *dbuf) * * Make sure @dbuf is at least @size bytes. * - * Returns: %FALSE on out of memory, %TRUE otherwise. + * Returns: `FALSE` on out of memory, `TRUE` otherwise. */ gboolean vips_dbuf_minimum_size(VipsDbuf *dbuf, size_t size) @@ -96,7 +96,7 @@ vips_dbuf_minimum_size(VipsDbuf *dbuf, size_t size) * * Make sure @dbuf has at least @size bytes available after the write point. * - * Returns: %FALSE on out of memory, %TRUE otherwise. + * Returns: `FALSE` on out of memory, `TRUE` otherwise. */ gboolean vips_dbuf_allocate(VipsDbuf *dbuf, size_t size) @@ -165,7 +165,7 @@ vips_dbuf_get_write(VipsDbuf *dbuf, size_t *size) * * Append @size bytes from @data. @dbuf expands if necessary. * - * Returns: %FALSE on out of memory, %TRUE otherwise. + * Returns: `FALSE` on out of memory, `TRUE` otherwise. */ gboolean vips_dbuf_write(VipsDbuf *dbuf, const unsigned char *data, size_t size) @@ -188,7 +188,7 @@ vips_dbuf_write(VipsDbuf *dbuf, const unsigned char *data, size_t size) * * Format the string and write to @dbuf. * - * Returns: %FALSE on out of memory, %TRUE otherwise. + * Returns: `FALSE` on out of memory, `TRUE` otherwise. */ gboolean vips_dbuf_writef(VipsDbuf *dbuf, const char *fmt, ...) @@ -222,7 +222,7 @@ vips_dbuf_writef(VipsDbuf *dbuf, const char *fmt, ...) * - Don't escape \n, \t, \r * - Do escape the other ASCII codes. * - * Returns: %FALSE on out of memory, %TRUE otherwise. + * Returns: `FALSE` on out of memory, `TRUE` otherwise. */ gboolean vips_dbuf_write_amp(VipsDbuf *dbuf, const char *str) @@ -301,7 +301,7 @@ vips_dbuf_destroy(VipsDbuf *dbuf) * @offset: how to move the write point * @whence: from start, from end, from current * - * Move the write point. @whence can be %SEEK_SET, %SEEK_CUR, %SEEK_END, with + * Move the write point. @whence can be `SEEK_SET`, `SEEK_CUR`, `SEEK_END`, with * the usual meaning. */ gboolean @@ -380,7 +380,7 @@ vips_dbuf_tell(VipsDbuf *dbuf) * * This makes it safe to treat the dbuf contents as a C string. * - * Returns: %FALSE on out of memory, %TRUE otherwise. + * Returns: `FALSE` on out of memory, `TRUE` otherwise. */ static gboolean vips_dbuf_null_terminate(VipsDbuf *dbuf) diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index 17e972e702..fd1e8d5932 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -160,7 +160,7 @@ vips_error_buffer_copy(void) /** * vips_verror: * @domain: the source of the error - * @fmt: printf()-style format string for the error + * @fmt: `printf()`-style format string for the error * @ap: arguments to the format string * * Append a message to the error buffer. @@ -202,10 +202,10 @@ vips_verror(const char *domain, const char *fmt, va_list ap) /** * vips_error: * @domain: the source of the error - * @fmt: printf()-style format string for the error + * @fmt: `printf()`-style format string for the error * @...: arguments to the format string * - * Format the string in the style of printf() and append to the error buffer. + * Format the string in the style of [`printf()`](man:printf(3)) and append to the error buffer. * * ::: seealso * [func@error_system], [func@verror]. @@ -224,10 +224,10 @@ vips_error(const char *domain, const char *fmt, ...) * vips_verror_system: * @err: the system error code * @domain: the source of the error - * @fmt: printf()-style format string for the error + * @fmt: `printf()`-style format string for the error * @ap: arguments to the format string * - * Format the string in the style of printf() and append to the error buffer. + * Format the string in the style of [`printf()`](man:printf(3)) and append to the error buffer. * Then create and append a localised message based on the system error code, * usually the value of errno. * @@ -245,7 +245,7 @@ vips_verror_system(int err, const char *domain, const char *fmt, va_list ap) * vips_error_system: * @err: the system error code * @domain: the source of the error - * @fmt: printf()-style format string for the error + * @fmt: `printf()`-style format string for the error * @...: arguments to the format string * * Format the string in the style of printf() and append to the error buffer. @@ -299,7 +299,7 @@ vips_error_g(GError **error) * vips_g_error: * @error: glib error pointer * - * This function adds the %GError to the vips error buffer and clears it. It's + * This function adds the [struct@GLib.Error] to the vips error buffer and clears it. It's * the opposite of [func@error_g]. * * ::: seealso @@ -335,14 +335,14 @@ vips_error_clear(void) /** * vips_error_exit: - * @fmt: printf()-style format string for the message + * @fmt: `printf()`-style format string for the message * @...: arguments to the format string * * Sends a formatted error message to stderr, then sends the contents of the * error buffer, if any, then shuts down vips and terminates the program with * an error code. * - * @fmt may be %NULL, in which case only the error buffer is printed before + * @fmt may be `NULL`, in which case only the error buffer is printed before * exiting. * * ::: seealso diff --git a/libvips/iofuncs/gate.c b/libvips/iofuncs/gate.c index 06958e06c4..d8db5985fe 100644 --- a/libvips/iofuncs/gate.c +++ b/libvips/iofuncs/gate.c @@ -86,7 +86,7 @@ static FILE *vips__thread_fp = NULL; /** * vips_profile_set: - * @profile: %TRUE to enable profile recording + * @profile: `TRUE` to enable profile recording * * If set, vips will record profiling information, and dump it on program * exit. These profiles can be analysed with the `vipsprofile` program. diff --git a/libvips/iofuncs/generate.c b/libvips/iofuncs/generate.c index 5fd702e92b..f568957179 100644 --- a/libvips/iofuncs/generate.c +++ b/libvips/iofuncs/generate.c @@ -332,7 +332,7 @@ vips__demand_hint_array(VipsImage *image, * vips_image_pipeline_array: * @image: (out): output image * @hint: demand hint for @image - * @in: (array zero-terminated=1): %NULL-terminated array of input images + * @in: (array zero-terminated=1): `NULL`-terminated array of input images * * Add an image to a pipeline. @image depends on all of the images in @in, * @image prefers to supply pixels according to @hint. @@ -340,8 +340,8 @@ vips__demand_hint_array(VipsImage *image, * Operations can set demand hints, that is, hints to the VIPS IO system about * the type of region geometry they work best with. For example, * operations which transform coordinates will usually work best with - * %VIPS_DEMAND_STYLE_SMALLTILE, operations which work on local windows of - * pixels will like %VIPS_DEMAND_STYLE_FATSTRIP. + * [enum@Vips.DemandStyle.SMALLTILE], operations which work on local windows of + * pixels will like [enum@Vips.DemandStyle.FATSTRIP]. * * Header fields in @image are set from the fields in @in, with lower-numbered * images in @in taking priority. @@ -389,7 +389,7 @@ vips_image_pipeline_array(VipsImage *image, * vips_image_pipelinev: * @image: output image of pipeline * @hint: hint for this image - * @...: %NULL-terminated list of input images + * @...: `NULL`-terminated list of input images * * Build an array and call [func@Image.pipeline_array]. * @@ -467,7 +467,7 @@ vips_stop_one(void *seq, void *a, void *b) * @b: user data * * Stop function for many images in. @a is a pointer to - * a %NULL-terminated array of input images. + * a `NULL`-terminated array of input images. * * ::: seealso * [method@Image.generate]. @@ -495,7 +495,7 @@ vips_stop_many(void *seq, void *a, void *b) * @b: user data * * Start function for many images in. @a is a pointer to - * a %NULL-terminated array of input images. + * a `NULL`-terminated array of input images. * * ::: seealso * [method@Image.generate], [func@allocate_input_array] @@ -533,15 +533,15 @@ vips_start_many(VipsImage *out, void *a, void *b) /** * vips_allocate_input_array: * @out: free array when this image closes - * @...: %NULL-terminated list of input images + * @...: `NULL`-terminated list of input images * - * Convenience function --- make a %NULL-terminated array of input images. + * Convenience function --- make a `NULL`-terminated array of input images. * Use with [func@start_many]. * * ::: seealso * [method@Image.generate], [func@start_many]. * - * Returns: (transfer none) (nullable): %NULL-terminated array of images. + * Returns: (transfer none) (nullable): `NULL`-terminated array of images. * Do not free the result. */ VipsImage ** @@ -598,7 +598,7 @@ vips_allocate_input_array(VipsImage *out, ...) * @stop: set this to stop processing * * Fill @out->valid with pixels. @seq contains per-thread state, such as the - * input regions. Set @stop to %TRUE to stop processing. + * input regions. Set @stop to `TRUE` to stop processing. * * ::: seealso * [method@Image.generate], [func@stop_many]. diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index c5cc5fbe33..9cbc517036 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -283,21 +283,21 @@ * VIPS_IMAGE_SIZEOF_ELEMENT: * @I: a [class@Image] * - * Returns: sizeof() a band element. + * Returns: `sizeof()` a band element. */ /** * VIPS_IMAGE_SIZEOF_PEL: * @I: a [class@Image] * - * Returns: sizeof() a pixel. + * Returns: `sizeof()` a pixel. */ /** * VIPS_IMAGE_SIZEOF_LINE: * @I: a [class@Image] * - * Returns: sizeof() a scanline of pixels. + * Returns: `sizeof()` a scanline of pixels. */ /** @@ -383,7 +383,7 @@ G_DEFINE_TYPE(VipsImage, vips_image, VIPS_TYPE_OBJECT); /** * vips_progress_set: - * @progress: %TRUE to enable progress messages + * @progress: `TRUE` to enable progress messages * * If set, vips will print messages about the progress of computation to * stdout. This can also be enabled with the --vips-progress option, or by @@ -1446,7 +1446,7 @@ vips_image_minimise_all(VipsImage *image) * mode. Some operations change behaviour slightly in sequential mode to * optimize memory behaviour. * - * Returns: %TRUE if @image is in sequential mode. + * Returns: `TRUE` if @image is in sequential mode. */ gboolean vips_image_is_sequential(VipsImage *image) @@ -1618,14 +1618,14 @@ vips_image_set_progress(VipsImage *image, gboolean progress) * @image: image to test * * If @image has been killed (see [method@Image.set_kill]), set an error message, - * clear the [class@Image].kill flag and return %TRUE. Otherwise return %FALSE. + * clear the [class@Image].kill flag and return `TRUE`. Otherwise return `FALSE`. * * Handy for loops which need to run sets of threads which can fail. * * ::: seealso * [method@Image.set_kill]. * - * Returns: %TRUE if @image has been killed. + * Returns: `TRUE` if @image has been killed. */ gboolean vips_image_iskilled(VipsImage *image) @@ -1704,7 +1704,7 @@ vips_image_temp_name(char *name, int size) * [method@Image.write_line]. Write a whole image to another image with * [method@Image.write]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new(void) @@ -1761,7 +1761,7 @@ vips_image_new_mode(const char *filename, const char *mode) * ::: seealso * [ctor@Image.new]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_memory(void) @@ -1781,7 +1781,7 @@ vips_image_new_memory(void) * ::: seealso * [ctor@Image.new_memory]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_memory(void) @@ -1842,7 +1842,7 @@ vips_filename_get_options(const char *vips_filename) /** * vips_image_new_from_file: (constructor) * @name: file to open - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * ::: note "Optional arguments" * * @access: hint [enum@Access] mode to loader @@ -1873,7 +1873,7 @@ vips_filename_get_options(const char *vips_filename) * and then processed from there. Large images are decompressed to temporary * random-access files on disc and then processed from there. * - * Set @memory to %TRUE to force loading via memory. The default is to load + * Set @memory to `TRUE` to force loading via memory. The default is to load * large random access images via temporary disc files. See * [ctor@Image.new_temp_file] for an * explanation of how VIPS selects a location for the temporary file. @@ -1910,7 +1910,7 @@ vips_filename_get_options(const char *vips_filename) * [func@Foreign.find_load], [func@Foreign.is_a], * [method@Image.write_to_file]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_from_file(const char *name, ...) @@ -1951,7 +1951,7 @@ vips_image_new_from_file(const char *name, ...) * ::: seealso * [method@Image.draw_circle]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_from_file_RW(const char *filename) @@ -1976,7 +1976,7 @@ vips_image_new_from_file_RW(const char *filename) * ::: seealso * [method@Image.copy], [ctor@Image.rawload], [ctor@Image.new_from_file]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_from_file_raw(const char *filename, @@ -2032,7 +2032,7 @@ vips_image_new_from_file_raw(const char *filename, * [ctor@Image.new], [method@Image.write_to_memory], * [ctor@Image.new_from_memory_copy]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_from_memory(const void *data, size_t size, @@ -2093,7 +2093,7 @@ vips_image_new_from_memory_copy_cb(VipsImage *image, void *data_copy) * ::: seealso * [ctor@Image.new_from_memory]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_from_memory_copy(const void *data, size_t size, @@ -2124,7 +2124,7 @@ vips_image_new_from_memory_copy(const void *data, size_t size, * @buf: (array length=len) (element-type guint8) (transfer none): image data * @len: (type gsize): length of memory buffer * @option_string: set of extra options as a string - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Loads an image from the formatted area of memory @buf, @len using the * loader recommended by [func@Foreign.find_load_buffer]. @@ -2142,7 +2142,7 @@ vips_image_new_from_memory_copy(const void *data, size_t size, * ::: seealso * [method@Image.write_to_buffer]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_from_buffer(const void *buf, size_t len, @@ -2180,7 +2180,7 @@ vips_image_new_from_buffer(const void *buf, size_t len, * vips_image_new_from_source: (constructor) * @source: (transfer none): source to fetch image from * @option_string: set of extra options as a string - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Loads an image from the formatted source @input, * loader recommended by [func@Foreign.find_load_source]. @@ -2192,7 +2192,7 @@ vips_image_new_from_buffer(const void *buf, size_t len, * ::: seealso * [method@Image.write_to_target]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_from_source(VipsSource *source, @@ -2278,7 +2278,7 @@ vips_image_new_from_source(VipsSource *source, * ::: seealso * [ctor@Image.new_matrixv] * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_matrix(int width, int height) @@ -2323,7 +2323,7 @@ vips_image_new_matrix(int width, int height) * ::: seealso * [ctor@Image.new_matrix] * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_matrixv(int width, int height, ...) @@ -2354,7 +2354,7 @@ vips_image_new_matrixv(int width, int height, ...) * * A binding-friendly version of [ctor@Image.new_matrixv]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_matrix_from_array(int width, int height, @@ -2393,7 +2393,7 @@ vips_image_new_matrix_from_array(int width, int height, * A renamed [ctor@Image.new_matrix_from_array]. Some gobject bindings do not * like more than one _new method. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_matrix_from_array(int width, int height, @@ -2416,7 +2416,7 @@ vips_image_matrix_from_array(int width, int height, * ::: seealso * [ctor@Image.new_from_image1] * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_from_image(VipsImage *image, const double *c, int n) @@ -2471,7 +2471,7 @@ vips_image_new_from_image(VipsImage *image, const double *c, int n) * ::: seealso * [ctor@Image.new_from_image] * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_from_image1(VipsImage *image, double c) @@ -2564,7 +2564,7 @@ vips_get_disc_threshold(void) * ::: seealso * [ctor@Image.new]. * - * Returns: the new [class@Image], or %NULL on error. + * Returns: the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_new_temp_file(const char *format) @@ -2670,7 +2670,7 @@ vips_image_write(VipsImage *image, VipsImage *out) * vips_image_write_to_file: * @image: image to write * @name: write to this file - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Writes @in to @name using the saver recommended by * [func@Foreign.find_save]. @@ -2735,7 +2735,7 @@ vips_image_write_to_file(VipsImage *image, const char *name, ...) * @suffix: format to write * @buf: (array length=size) (element-type guint8) (transfer full): return buffer start here * @size: (type gsize): return buffer length here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Writes @in to a memory buffer in a format specified by @suffix. * @@ -2825,7 +2825,7 @@ vips_image_write_to_buffer(VipsImage *in, * @in: image to write * @suffix: format to write * @target: target to write to - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Writes @in to @output in format @suffix. * @@ -3026,7 +3026,7 @@ vips_image_encode(VipsImage *in, VipsImage **out, VipsCoding coding) * vips_image_isMSBfirst: * @image: image to test * - * Return %TRUE if @image is in most-significant- + * Return `TRUE` if @image is in most-significant- * byte first form. This is the byte order used on the SPARC * architecture and others. */ @@ -3043,7 +3043,7 @@ vips_image_isMSBfirst(VipsImage *image) * vips_image_isfile: * @image: image to test * - * Return %TRUE if @image represents a file on disc in some way. + * Return `TRUE` if @image represents a file on disc in some way. */ gboolean vips_image_isfile(VipsImage *image) @@ -3071,7 +3071,7 @@ vips_image_isfile(VipsImage *image) * vips_image_ispartial: * @image: image to test * - * Return %TRUE if @im represents a partial image (a delayed calculation). + * Return `TRUE` if @im represents a partial image (a delayed calculation). */ gboolean vips_image_ispartial(VipsImage *image) @@ -3090,7 +3090,7 @@ vips_image_ispartial(VipsImage *image) * example, a 4-band [enum@Vips.Interpretation.sRGB] would, but a six-band * [enum@Vips.Interpretation.MULTIBAND] would not. * - * Return %TRUE if @image has an alpha channel. + * Return `TRUE` if @image has an alpha channel. */ gboolean vips_image_hasalpha(VipsImage *image) @@ -3351,7 +3351,7 @@ vips_image_rewind_output(VipsImage *image) * ::: seealso * [method@Image.wio_input]. * - * Returns: (transfer full): the new [class@Image], or %NULL on error. + * Returns: (transfer full): the new [class@Image], or `NULL` on error. */ VipsImage * vips_image_copy_memory(VipsImage *image) @@ -3754,7 +3754,7 @@ vips_image_pio_output(VipsImage *image) * vips_band_format_isint: * @format: format to test * - * Return %TRUE if @format is one of the integer types. + * Return `TRUE` if @format is one of the integer types. */ gboolean vips_band_format_isint(VipsBandFormat format) @@ -3784,7 +3784,7 @@ vips_band_format_isint(VipsBandFormat format) * vips_band_format_isuint: * @format: format to test * - * Return %TRUE if @format is one of the unsigned integer types. + * Return `TRUE` if @format is one of the unsigned integer types. */ gboolean vips_band_format_isuint(VipsBandFormat format) @@ -3814,7 +3814,7 @@ vips_band_format_isuint(VipsBandFormat format) * vips_band_format_is8bit: * @format: format to test * - * Return %TRUE if @format is uchar or schar. + * Return `TRUE` if @format is uchar or schar. */ gboolean vips_band_format_is8bit(VipsBandFormat format) @@ -3844,7 +3844,7 @@ vips_band_format_is8bit(VipsBandFormat format) * vips_band_format_isfloat: * @format: format to test * - * Return %TRUE if @format is one of the float types. + * Return `TRUE` if @format is one of the float types. */ gboolean vips_band_format_isfloat(VipsBandFormat format) @@ -3874,7 +3874,7 @@ vips_band_format_isfloat(VipsBandFormat format) * vips_band_format_iscomplex: * @format: format to test * - * Return %TRUE if @fmt is one of the complex types. + * Return `TRUE` if @fmt is one of the complex types. */ gboolean vips_band_format_iscomplex(VipsBandFormat format) diff --git a/libvips/iofuncs/memory.c b/libvips/iofuncs/memory.c index efd70c59e0..dcd814055a 100644 --- a/libvips/iofuncs/memory.c +++ b/libvips/iofuncs/memory.c @@ -96,7 +96,7 @@ static GMutex vips_tracked_mutex; /** * VIPS_NEW: - * @OBJ: allocate memory local to @OBJ, or %NULL for no auto-free + * @OBJ: allocate memory local to @OBJ, or `NULL` for no auto-free * @T: type of thing to allocate * * Allocate memory for a thing of type @T. The memory is not @@ -113,7 +113,7 @@ static GMutex vips_tracked_mutex; /** * VIPS_ARRAY: - * @OBJ: allocate memory local to @OBJ, or %NULL for no auto-free + * @OBJ: allocate memory local to @OBJ, or `NULL` for no auto-free * @N: number of @T 's to allocate * @T: type of thing to allocate * @@ -137,11 +137,11 @@ vips_malloc_cb(VipsObject *object, char *buf) /** * vips_malloc: - * @object: (nullable): allocate memory local to this [class@Object], or %NULL + * @object: (nullable): allocate memory local to this [class@Object], or `NULL` * @size: number of bytes to allocate * * [func@GLib.malloc] local to @object, that is, the memory will be automatically - * freed for you when the object is closed. If @object is %NULL, you need to + * freed for you when the object is closed. If @object is `NULL`, you need to * free the memory explicitly with [func@GLib.free]. * * This function cannot fail. See [func@tracked_malloc] if you are @@ -170,11 +170,11 @@ vips_malloc(VipsObject *object, size_t size) /** * vips_strdup: - * @object: (nullable): allocate memory local to this [class@Object], or %NULL + * @object: (nullable): allocate memory local to this [class@Object], or `NULL` * @str: string to copy * * [func@GLib.strdup] a string. When @object is freed, the string will be freed for - * you. If @object is %NULL, you need to + * you. If @object is `NULL`, you need to * free the memory yourself with [func@GLib.free]. * * This function cannot fail. @@ -206,7 +206,7 @@ vips_strdup(VipsObject *object, const char *str) * * Only use it to free memory that was * previously allocated with [func@tracked_malloc] - * with a %NULL first argument. + * with a `NULL` first argument. * * ::: seealso * [func@tracked_malloc]. @@ -247,7 +247,7 @@ vips_tracked_free(void *s) * * Only use it to free memory that was * previously allocated with [func@tracked_aligned_alloc] - * with a %NULL first argument. + * with a `NULL` first argument. * * ::: seealso * [func@tracked_aligned_alloc]. @@ -290,7 +290,7 @@ vips_tracked_aligned_free(void *s) * Allocate an area of memory that will be tracked by [func@tracked_get_mem] * and friends. * - * If allocation fails, [func@tracked_malloc] returns %NULL and + * If allocation fails, [func@tracked_malloc] returns `NULL` and * sets an error message. * * You must only free the memory returned with [func@tracked_free]. @@ -298,7 +298,7 @@ vips_tracked_aligned_free(void *s) * ::: seealso * [func@tracked_free], [func@malloc]. * - * Returns: (transfer full): a pointer to the allocated memory, or %NULL on error. + * Returns: (transfer full): a pointer to the allocated memory, or `NULL` on error. */ void * vips_tracked_malloc(size_t size) @@ -355,7 +355,7 @@ vips_tracked_malloc(size_t size) * by @align that will be tracked by [func@tracked_get_mem] * and friends. * - * If allocation fails, [func@tracked_aligned_alloc] returns %NULL + * If allocation fails, [func@tracked_aligned_alloc] returns `NULL` * and sets an error message. * * You must only free the memory returned with [func@tracked_aligned_free]. @@ -363,7 +363,7 @@ vips_tracked_malloc(size_t size) * ::: seealso * [func@tracked_malloc], [func@tracked_aligned_free], [func@malloc]. * - * Returns: (transfer full): a pointer to the allocated memory, or %NULL on error. + * Returns: (transfer full): a pointer to the allocated memory, or `NULL` on error. */ void * vips_tracked_aligned_alloc(size_t size, size_t align) diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index a194c7cd74..f9c2b3c3a8 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -582,11 +582,11 @@ vips_argument_table_destroy(VipsArgumentTable *table) * @a: client data * @b: client data * - * Loop over the vips_arguments to an object. Stop when @fn returns non-%NULL + * Loop over the vips_arguments to an object. Stop when @fn returns non-`NULL` * and return that value. * - * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first - * non-%NULL value from @fn. + * Returns: `NULL` if @fn returns `NULL` for all arguments, otherwise the first + * non-`NULL` value from @fn. */ void * vips_argument_map(VipsObject *object, @@ -802,7 +802,7 @@ vips_object_get_argument(VipsObject *object, const char *name, * * Convenience: has an argument been assigned. Useful for bindings. * - * Returns: %TRUE if the argument has been assigned. + * Returns: `TRUE` if the argument has been assigned. */ gboolean vips_object_argument_isset(VipsObject *object, const char *name) @@ -2301,11 +2301,11 @@ vips_object_find_args(VipsObject *object, /** * vips_object_get_args: (skip) * @object: object whose args should be retrieved - * @names: (transfer none) (array length=n_args) (allow-none): output array of %GParamSpec names + * @names: (transfer none) (array length=n_args) (allow-none): output array of [class@GObject.ParamSpec] names * @flags: (transfer none) (array length=n_args) (allow-none): output array of [flags@ArgumentFlags] * @n_args: (allow-none): length of output arrays * - * Get all %GParamSpec names and [flags@ArgumentFlags] for an object. + * Get all [class@GObject.ParamSpec] names and [flags@ArgumentFlags] for an object. * * This is handy for language bindings. From C, it's usually more convenient to * use [func@Argument.map]. @@ -2379,7 +2379,7 @@ vips_object_new(GType type, VipsObjectSetArguments set, void *a, void *b) /** * vips_object_set_valist: * @object: object to set arguments on - * @ap: %NULL-terminated list of argument/value pairs + * @ap: `NULL`-terminated list of argument/value pairs * * See [method@Object.set]. * @@ -2418,7 +2418,7 @@ vips_object_set_valist(VipsObject *object, va_list ap) /** * vips_object_set: * @object: object to set arguments on - * @...: %NULL-terminated list of argument/value pairs + * @...: `NULL`-terminated list of argument/value pairs * * Set a list of vips object arguments. For example: * @@ -2722,10 +2722,10 @@ vips_object_map_sub(VipsObject *key, VipsObject *value, * @b: client data * * Call a function for all alive objects. - * Stop when @fn returns non-%NULL and return that value. + * Stop when @fn returns non-`NULL` and return that value. * - * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first - * non-%NULL value from @fn. + * Returns: `NULL` if @fn returns `NULL` for all arguments, otherwise the first + * non-`NULL` value from @fn. */ void * vips_object_map(VipsSListMap2Fn fn, void *a, void *b) @@ -2757,11 +2757,11 @@ vips_object_map(VipsSListMap2Fn fn, void *a, void *b) * @a: client data * @b: client data * - * Map over a type's children. Stop when @fn returns non-%NULL + * Map over a type's children. Stop when @fn returns non-`NULL` * and return that value. * - * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first - * non-%NULL value from @fn. + * Returns: `NULL` if @fn returns `NULL` for all arguments, otherwise the first + * non-`NULL` value from @fn. */ void * vips_type_map(GType base, VipsTypeMap2Fn fn, void *a, void *b) @@ -2787,10 +2787,10 @@ vips_type_map(GType base, VipsTypeMap2Fn fn, void *a, void *b) * @a: client data * * Map over a type's children, direct and indirect. Stop when @fn returns - * non-%NULL and return that value. + * non-`NULL` and return that value. * - * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first - * non-%NULL value from @fn. + * Returns: `NULL` if @fn returns `NULL` for all arguments, otherwise the first + * non-`NULL` value from @fn. */ void * vips_type_map_all(GType base, VipsTypeMapFn fn, void *a) @@ -2812,10 +2812,10 @@ vips_type_map_all(GType base, VipsTypeMapFn fn, void *a) * * Loop over all the subclasses of @type. Non-abstract classes only. * Stop when @fn returns - * non-%NULL and return that value. + * non-`NULL` and return that value. * - * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first - * non-%NULL value from @fn. + * Returns: `NULL` if @fn returns `NULL` for all arguments, otherwise the first + * non-`NULL` value from @fn. */ void * vips_class_map_all(GType type, VipsClassMapFn fn, void *a) @@ -2954,8 +2954,8 @@ vips_class_build_hash_cb(void *dummy) * @basename: name of base class * @nickname: search for a class with this nickname * - * Search below @basename, return the %GType of the class whose name or - * @nickname matches, or 0 for not found. + * Search below @basename, return the [alias@GObject.Type] of the class + * whose name or @nickname matches, or 0 for not found. * If @basename is NULL, the whole of [class@Object] is searched. * * This function uses a cache, so it should be quick. @@ -2963,7 +2963,7 @@ vips_class_build_hash_cb(void *dummy) * ::: seealso * [func@class_find] * - * Returns: the %GType of the class, or 0 if the class is not found. + * Returns: the [alias@GObject.Type] of the class, or 0 if the class is not found. */ GType vips_type_find(const char *basename, const char *nickname) @@ -3004,9 +3004,9 @@ vips_type_find(const char *basename, const char *nickname) /** * vips_nickname_find: - * @type: #GType to search for + * @type: [alias@GObject.Type] to search for * - * Return the VIPS nickname for a %GType. Handy for language bindings. + * Return the VIPS nickname for a [alias@GObject.Type]. Handy for language bindings. * * Returns: (transfer none): the class nickname. */ diff --git a/libvips/iofuncs/operation.c b/libvips/iofuncs/operation.c index 286b5c1fa5..66aaf248d1 100644 --- a/libvips/iofuncs/operation.c +++ b/libvips/iofuncs/operation.c @@ -935,8 +935,8 @@ vips_operation_get_valist_optional(VipsOperation *operation, va_list ap) /** * vips_call_required_optional: * @operation: the operation to execute - * @required: %va_list of required arguments - * @optional: NULL-terminated %va_list of name / value pairs + * @required: `va_list` of required arguments + * @optional: `NULL`-terminated `va_list` of name / value pairs * * This is the main entry point for the C and C++ varargs APIs. @operation * is executed, supplying @required and @optional arguments. @@ -1031,7 +1031,7 @@ vips_call_by_name(const char *operation_name, /** * vips_call: * @operation_name: name of operation to call - * @...: required args, then a %NULL-terminated list of argument/value pairs + * @...: required args, then a `NULL`-terminated list of argument/value pairs * * [func@call] calls the named operation, passing in required arguments and * then setting any optional ones from the remainder of the arguments as a set diff --git a/libvips/iofuncs/rect.c b/libvips/iofuncs/rect.c index ac83389c4c..09c1509dfb 100644 --- a/libvips/iofuncs/rect.c +++ b/libvips/iofuncs/rect.c @@ -63,7 +63,7 @@ * * Does @r contain point (@x, @y)? * - * Returns: %TRUE if @r contains (@x, @y). + * Returns: `TRUE` if @r contains (@x, @y). */ gboolean vips_rect_includespoint(const VipsRect *r, int x, int y) @@ -80,7 +80,7 @@ vips_rect_includespoint(const VipsRect *r, int x, int y) * * Is @r empty? ie. zero width or height. * - * Returns: %TRUE if @r contains no pixels. + * Returns: `TRUE` if @r contains no pixels. */ gboolean vips_rect_isempty(const VipsRect *r) @@ -95,7 +95,7 @@ vips_rect_isempty(const VipsRect *r) * * Is @r2 a subset of @r1? * - * Returns: %TRUE if @r2 is a subset of @r1. + * Returns: `TRUE` if @r2 is a subset of @r1. */ gboolean vips_rect_includesrect(const VipsRect *r1, const VipsRect *r2) @@ -113,7 +113,7 @@ vips_rect_includesrect(const VipsRect *r1, const VipsRect *r2) * * Is @r1 equal to @r2? * - * Returns: %TRUE if @r1 is equal to @r2. + * Returns: `TRUE` if @r1 is equal to @r2. */ gboolean vips_rect_equalsrect(const VipsRect *r1, const VipsRect *r2) @@ -129,7 +129,7 @@ vips_rect_equalsrect(const VipsRect *r1, const VipsRect *r2) * * Do @r1 and @r2 have a non-empty intersection? * - * Returns: %TRUE if @r2 and @r1 overlap. + * Returns: `TRUE` if @r2 and @r1 overlap. */ gboolean vips_rect_overlapsrect(const VipsRect *r1, const VipsRect *r2) diff --git a/libvips/iofuncs/sbuf.c b/libvips/iofuncs/sbuf.c index 3d5282a054..bc9bedf29a 100644 --- a/libvips/iofuncs/sbuf.c +++ b/libvips/iofuncs/sbuf.c @@ -175,7 +175,7 @@ vips_sbuf_refill(VipsSbuf *sbuf) * * Fetch the next character from the source. * - * If you can, use the macro VIPS_SBUF_GETC() instead for speed. + * If you can, use the macro [func@SBUF_GETC] instead for speed. * * Returns: the next char from @sbuf, -1 on read error or EOF. */ @@ -209,7 +209,7 @@ vips_sbuf_getc(VipsSbuf *sbuf) * unget more than one character is undefined. Unget at the start of the file * does nothing. * - * If you can, use the macro VIPS_SBUF_UNGETC() instead for speed. + * If you can, use the macro [func@SBUF_UNGETC] instead for speed. */ void vips_sbuf_ungetc(VipsSbuf *sbuf) @@ -290,7 +290,7 @@ vips_sbuf_require(VipsSbuf *sbuf, int require) * @require: need this many characters * * Make sure at least @require characters are available for - * VIPS_SBUF_PEEK() and VIPS_SBUF_FETCH(). + * [func@SBUF_PEEK] and [func@SBUF_FETCH]. * * Returns: 0 on success, -1 on read error or EOF. */ @@ -299,7 +299,7 @@ vips_sbuf_require(VipsSbuf *sbuf, int require) * VIPS_SBUF_PEEK: * @sbuf: source to operate on * - * After a successful VIPS_SBUF_REQUIRE(), you can index this to get + * After a successful [func@SBUF_REQUIRE], you can index this to get * require characters of input. * * Returns: a pointer to the next require characters of input. @@ -309,7 +309,7 @@ vips_sbuf_require(VipsSbuf *sbuf, int require) * VIPS_SBUF_FETCH: * @sbuf: source to operate on * - * After a successful VIPS_SBUF_REQUIRE(), you can use this require times + * After a successful [func@SBUF_REQUIRE], you can use this require times * to fetch characters of input. * * Returns: the next input character. diff --git a/libvips/iofuncs/sinkdisc.c b/libvips/iofuncs/sinkdisc.c index fbf743fe1b..83eb615dd7 100644 --- a/libvips/iofuncs/sinkdisc.c +++ b/libvips/iofuncs/sinkdisc.c @@ -474,9 +474,9 @@ write_free(Write *write) * @a: client data * * The function should write the pixels in @area from @region. @a is the - * value passed into vips_sink_disc(). + * value passed into [method@Image.sink_disc]. * - * See also: vips_sink_disc(). + * See also: [method@Image.sink_disc]. * * Returns: 0 on success, -1 on error. */ @@ -487,7 +487,7 @@ write_free(Write *write) * @write_fn: (scope call) (closure a): called for every batch of pixels * @a: client data * - * vips_sink_disc() loops over @im, top-to-bottom, generating it in sections. + * [method@Image.sink_disc] loops over @im, top-to-bottom, generating it in sections. * As each section is produced, @write_fn is called. * * @write_fn is always called single-threaded (though not always from the same @@ -495,10 +495,10 @@ write_free(Write *write) * sections in top-to-bottom order, and there are never any gaps. * * This operation is handy for making image sinks which output to things like - * disc files. Things like vips_jpegsave(), for example, use this to write + * disc files. Things like [method@Image.jpegsave], for example, use this to write * images to files in JPEG format. * - * See also: vips_concurrency_set(). + * See also: [func@concurrency_set]. * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/iofuncs/sinkscreen.c b/libvips/iofuncs/sinkscreen.c index b5505f4ab4..5e9ade24bc 100644 --- a/libvips/iofuncs/sinkscreen.c +++ b/libvips/iofuncs/sinkscreen.c @@ -1163,7 +1163,7 @@ vips__sink_screen_once(void *data) * pixels are ready. In a glib-based application, this is easily done with * [func@GLib.idle_add]. * - * If @notify_fn is %NULL then [method@Image.sink_screen] runs synchronously. + * If @notify_fn is `NULL` then [method@Image.sink_screen] runs synchronously. * [method@Region.prepare] on @out will always block until the pixels have been * calculated. * diff --git a/libvips/iofuncs/source.c b/libvips/iofuncs/source.c index bff7c25d0c..64c6111fb4 100644 --- a/libvips/iofuncs/source.c +++ b/libvips/iofuncs/source.c @@ -1023,10 +1023,10 @@ vips_source_descriptor_to_memory(VipsSource *source) * @source: source to operate on * * Some sources can be efficiently mapped into memory. - * You can still use [method@Source.map] if this function returns %FALSE, + * You can still use [method@Source.map] if this function returns `FALSE`, * but it will be slow. * - * Returns: %TRUE if the source can be efficiently mapped into memory. + * Returns: `TRUE` if the source can be efficiently mapped into memory. */ gboolean vips_source_is_mappable(VipsSource *source) @@ -1055,7 +1055,7 @@ vips_source_is_mappable(VipsSource *source) * Use this to add basic source support for older loaders which can only work * on files. * - * Returns: %TRUE if the source is a simple file. + * Returns: `TRUE` if the source is a simple file. */ gboolean vips_source_is_file(VipsSource *source) diff --git a/libvips/iofuncs/sourcecustom.c b/libvips/iofuncs/sourcecustom.c index 3dd95ab7e0..9fe9c32e19 100644 --- a/libvips/iofuncs/sourcecustom.c +++ b/libvips/iofuncs/sourcecustom.c @@ -181,8 +181,8 @@ vips_source_custom_class_init(VipsSourceCustomClass *class) /** * VipsSourceCustom::read: * @source_custom: the source being operated on - * @buffer: %gpointer, buffer to fill - * @size: %gint64, size of buffer + * @buffer: `gpointer`, buffer to fill + * @size: `gint64`, size of buffer * * This signal is emitted to read bytes from the source into @buffer. * @@ -200,8 +200,8 @@ vips_source_custom_class_init(VipsSourceCustomClass *class) /** * VipsSourceCustom::seek: * @source_custom: the source being operated on - * @offset: %gint64, seek offset - * @whence: %gint, seek origin + * @offset: `gint64`, seek offset + * @whence: `gint`, seek origin * * This signal is emitted to seek the source. The handler should * change the source position appropriately. diff --git a/libvips/iofuncs/system.c b/libvips/iofuncs/system.c index f6e8137668..fa9ef261b6 100644 --- a/libvips/iofuncs/system.c +++ b/libvips/iofuncs/system.c @@ -323,7 +323,7 @@ vips_system_init(VipsSystem *system) /** * vips_system: * @cmd_format: command to run - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * ::: note "Optional arguments" * * @in: array of input images @@ -349,7 +349,7 @@ vips_system_init(VipsSystem *system) * You can put a number between the `%` and the `s` to change the order * in which the substitution occurs. * - * The command is executed with popen() and the output captured in @log. + * The command is executed with [`popen()`](man:popen(3)) and the output captured in @log. * * After the command finishes, if @out_format is set, the output image is * opened and returned in @out. You can append `[options]` to @out_format to diff --git a/libvips/iofuncs/targetcustom.c b/libvips/iofuncs/targetcustom.c index da68025c45..832226d5a3 100644 --- a/libvips/iofuncs/targetcustom.c +++ b/libvips/iofuncs/targetcustom.c @@ -249,8 +249,8 @@ vips_target_custom_class_init(VipsTargetCustomClass *class) /** * VipsTargetCustom::write: * @target_custom: the target being operated on - * @data: %pointer, bytes to write - * @length: %gint64, number of bytes + * @data: `gpointer`, bytes to write + * @length: `gint64`, number of bytes * * This signal is emitted to write bytes to the target. * @@ -268,8 +268,8 @@ vips_target_custom_class_init(VipsTargetCustomClass *class) /** * VipsTargetCustom::read: * @target_custom: the target being operated on - * @buffer: %gpointer, buffer to fill - * @size: %gint64, size of buffer + * @buffer: `gpointer`, buffer to fill + * @size: `gint64`, size of buffer * * This signal is emitted to read bytes from the target into @buffer. * @@ -289,8 +289,8 @@ vips_target_custom_class_init(VipsTargetCustomClass *class) /** * VipsTargetCustom::seek: * @target_custom: the target being operated on - * @offset: %gint64, seek offset - * @whence: %gint, seek origin + * @offset: `gint64`, seek offset + * @whence: `gint`, seek origin * * This signal is emitted to seek the target. The handler should * change the target position appropriately. diff --git a/libvips/iofuncs/thread.c b/libvips/iofuncs/thread.c index 24bbaa0371..06b55a97f4 100644 --- a/libvips/iofuncs/thread.c +++ b/libvips/iofuncs/thread.c @@ -122,7 +122,7 @@ vips_thread_run(gpointer data) * * Wrapper for [ctor@GLib.Thread.try_new]. * - * Returns: (transfer full): the new [struct@GLib.Thread], or %NULL if an + * Returns: (transfer full): the new [struct@GLib.Thread], or `NULL` if an * error occurred */ GThread * diff --git a/libvips/iofuncs/threadpool.c b/libvips/iofuncs/threadpool.c index 808eb16a88..57c4d01801 100644 --- a/libvips/iofuncs/threadpool.c +++ b/libvips/iofuncs/threadpool.c @@ -568,7 +568,7 @@ vips_threadpool_new(VipsImage *im) * always single-threaded, so it can modify per-pool state (such as a * counter). * - * It should set @stop to %TRUE to indicate that no work could be allocated + * It should set @stop to `TRUE` to indicate that no work could be allocated * because the job is done. * * ::: seealso @@ -611,7 +611,7 @@ vips_threadpool_new(VipsImage *im) * @start: (scope async): allocate per-thread state * @allocate: (scope async): allocate a work unit * @work: (scope async): process a work unit - * @progress: (scope async): give progress feedback about a work unit, or %NULL + * @progress: (scope async): give progress feedback about a work unit, or `NULL` * @a: client data * * This function runs a set of threads over an image. Each thread first calls @@ -619,7 +619,7 @@ vips_threadpool_new(VipsImage *im) * @allocate to set up a new work unit (perhaps the next tile in an image, for * example), then @work to process that work unit. After each unit is * processed, @progress is called, so that the operation can give - * progress feedback. @progress may be %NULL. + * progress feedback. @progress may be `NULL`. * * The object returned by @start must be an instance of a subclass of * [class@ThreadState]. Use this to communicate between @allocate and @work. diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index cf03a7a4fd..1fcb6971eb 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -218,13 +218,14 @@ VipsArrayImage_unref(VipsArrayImage *array) * @data: (transfer full): data will be freed with this function * * A VipsArea wraps a chunk of memory. It adds reference counting and a free - * function. It also keeps a count and a %GType, so the area can be an array. + * function. It also keeps a count and a [alias@GObject.Type], so the area can + * be an array. * * This type is used for things like passing an array of double or an array of * [class@Object] pointers to operations, and for reference-counted immutable * strings. * - * Initial count == 1, so _unref() after attaching somewhere. + * Initial count == 1, so [method@Area.unref] after attaching somewhere. * * ::: seealso * [method@Area.unref]. @@ -289,12 +290,12 @@ vips__type_leak(void) /** * vips_area_new_array: - * @type: %GType of elements to store - * @sizeof_type: sizeof() an element in the array + * @type: [alias@GObject.Type] of elements to store + * @sizeof_type: `sizeof()` an element in the array * @n: number of elements in the array * - * An area which holds an array of elements of some %GType. To set values for - * the elements, get the pointer and write. + * An area which holds an array of elements of some [alias@GObject.Type]. + * To set values for the elements, get the pointer and write. * * ::: seealso * [method@Area.unref]. @@ -369,11 +370,11 @@ vips_area_new_array_object(int n) * @length: (out) (optional): optionally return length in bytes here * @n: (out) (optional): optionally return number of elements here * @type: (out) (optional): optionally return element type here - * @sizeof_type: (out) (optional): optionally return sizeof() element type here + * @sizeof_type: (out) (optional): optionally return `sizeof()` element type here * * Return the data pointer plus optionally the length in bytes of an area, - * the number of elements, the %GType of each element and the sizeof() each - * element. + * the number of elements, the [alias@GObject.Type] of each element and the + * `sizeof()` each element. * * Returns: (transfer none): The pointer held by @area. */ @@ -625,7 +626,7 @@ G_DEFINE_BOXED_TYPE_WITH_CODE(VipsRefString, vips_ref_string, * @length: number of bytes in @data * * Like [ctor@Area.new], but track a length as well. The returned [struct@Blob] - * takes ownership of @data and will free it with @free_fn. Pass %NULL for + * takes ownership of @data and will free it with @free_fn. Pass `NULL` for * @free_fn to not transfer ownership. * * An area of mem with a free func and a length (some sort of binary object, @@ -1577,8 +1578,8 @@ vips_value_set_save_string(GValue *value, const char *str) /** * vips_value_set_save_stringf: * @value: (out): GValue to set - * @fmt: printf()-style format string - * @...: arguments to printf()-formatted @fmt + * @fmt: `printf()`-style format string + * @...: arguments to `printf()`-formatted @fmt * * Generates a string and copies it into @value. */ diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index a51792817f..9bb8788097 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -103,8 +103,8 @@ vips_slist_equal(GSList *l1, GSList *l2) * * Map over a slist. _copy() the list in case the callback changes it. * - * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first - * non-%NULL value from @fn. + * Returns: `NULL` if @fn returns `NULL` for all arguments, otherwise the first + * non-`NULL` value from @fn. */ void * vips_slist_map2(GSList *list, VipsSListMap2Fn fn, void *a, void *b) @@ -131,8 +131,8 @@ vips_slist_map2(GSList *list, VipsSListMap2Fn fn, void *a, void *b) * * Map backwards. We _reverse() rather than recurse and unwind to save stack. * - * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first - * non-%NULL value from @fn. + * Returns: `NULL` if @fn returns `NULL` for all arguments, otherwise the first + * non-`NULL` value from @fn. */ void * vips_slist_map2_rev(GSList *list, VipsSListMap2Fn fn, void *a, void *b) @@ -162,8 +162,8 @@ vips_slist_map2_rev(GSList *list, VipsSListMap2Fn fn, void *a, void *b) * * Map over a slist. _copy() the list in case the callback changes it. * - * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first - * non-%NULL value from @fn. + * Returns: `NULL` if @fn returns `NULL` for all arguments, otherwise the first + * non-`NULL` value from @fn. */ void * vips_slist_map4(GSList *list, @@ -193,8 +193,8 @@ vips_slist_map4(GSList *list, * * Fold over a slist, applying @fn to each element. * - * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first - * non-%NULL value from @fn. + * Returns: `NULL` if @fn returns `NULL` for all arguments, otherwise the first + * non-`NULL` value from @fn. */ void * vips_slist_fold2(GSList *list, void *start, @@ -306,8 +306,8 @@ vips_hash_table_predicate(const char *key, void *value, Pair *pair) * * Like slist map, but for a hash table. * - * Returns: %NULL if @fn returns %NULL for all arguments, otherwise the first - * non-%NULL value from @fn. + * Returns: `NULL` if @fn returns `NULL` for all arguments, otherwise the first + * non-`NULL` value from @fn. */ void * vips_hash_table_map(GHashTable *hash, VipsSListMap2Fn fn, void *a, void *b) diff --git a/libvips/morphology/countlines.c b/libvips/morphology/countlines.c index 0a1ccf85ba..916d4fc9cb 100644 --- a/libvips/morphology/countlines.c +++ b/libvips/morphology/countlines.c @@ -160,7 +160,7 @@ vips_countlines_init(VipsCountlines *countlines) * @in: input image * @nolines: (out): output average number of lines * @direction: count lines horizontally or vertically - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Function which calculates the number of transitions * between black and white for the horizontal or the vertical diff --git a/libvips/morphology/labelregions.c b/libvips/morphology/labelregions.c index 79162559cc..bd7ac22045 100644 --- a/libvips/morphology/labelregions.c +++ b/libvips/morphology/labelregions.c @@ -143,7 +143,7 @@ vips_labelregions_init(VipsLabelregions *labelregions) * vips_labelregions: (method) * @in: image to test * @mask: write labelled regions here - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Label regions of equal pixels in an image. * @@ -163,7 +163,7 @@ vips_labelregions_init(VipsLabelregions *labelregions) * Use [method@Image.hist_find_indexed] to (for example) find blob coordinates. * * ::: tip "Optional arguments" - * * @segments: %gint, return number of regions found here + * * @segments: `gint`, return number of regions found here * * ::: seealso * [method@Image.hist_find_indexed]. diff --git a/libvips/morphology/morph.c b/libvips/morphology/morph.c index aeaf83fe7c..a02a9cd568 100644 --- a/libvips/morphology/morph.c +++ b/libvips/morphology/morph.c @@ -990,7 +990,7 @@ vips_morph_init(VipsMorph *morph) * @out: (out): output image * @mask: morphology with this mask * @morph: operation to perform - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Performs a morphological operation on @in using @mask as a * structuring element. diff --git a/libvips/morphology/nearest.c b/libvips/morphology/nearest.c index 5243c0cf10..f1a6aa225c 100644 --- a/libvips/morphology/nearest.c +++ b/libvips/morphology/nearest.c @@ -327,7 +327,7 @@ vips_fill_nearest_init(VipsFillNearest *nearest) * vips_fill_nearest: (method) * @in: image to test * @out: image with zero pixels filled with the nearest non-zero pixel - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Fill outwards from every non-zero pixel in @in, setting pixels in @distance * and @value. diff --git a/libvips/morphology/rank.c b/libvips/morphology/rank.c index b18766b12f..85b782f0a4 100644 --- a/libvips/morphology/rank.c +++ b/libvips/morphology/rank.c @@ -603,7 +603,7 @@ vips_rank_init(VipsRank *rank) * @width: width of region * @height: height of region * @index: select pixel - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * [method@Image.rank] does rank filtering on an image. A window of size @width by * @height is passed over the image. At each position, the pixels inside the @@ -646,7 +646,7 @@ vips_rank(VipsImage *in, VipsImage **out, * @in: input image * @out: (out): output image * @size: size of region - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * A convenience function equivalent to: * diff --git a/libvips/mosaicing/global_balance.c b/libvips/mosaicing/global_balance.c index 65f52823ad..29c16aaf8f 100644 --- a/libvips/mosaicing/global_balance.c +++ b/libvips/mosaicing/global_balance.c @@ -1951,7 +1951,7 @@ vips_globalbalance_init(VipsGlobalbalance *globalbalance) * vips_globalbalance: (method) * @in: mosaic to rebuild * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * [method@Image.globalbalance] can be used to remove contrast differences in * an assembled mosaic. @@ -1978,8 +1978,8 @@ vips_globalbalance_init(VipsGlobalbalance *globalbalance) * this package. * * ::: tip "Optional arguments" - * * @gamma: %gdouble, gamma of source images - * * @int_output: %gboolean, %TRUE for integer image output + * * @gamma: `gdouble`, gamma of source images + * * @int_output: `gboolean`, `TRUE` for integer image output * * ::: seealso * [method@Image.mosaic]. diff --git a/libvips/mosaicing/match.c b/libvips/mosaicing/match.c index 8ca669b91e..166bbb5da4 100644 --- a/libvips/mosaicing/match.c +++ b/libvips/mosaicing/match.c @@ -315,20 +315,20 @@ vips_match_init(VipsMatch *match) * @yr2: second reference tie-point * @xs2: second secondary tie-point * @ys2: second secondary tie-point - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Scale, rotate and translate @sec so that the tie-points line up. * - * If @search is %TRUE, before performing the transformation, the tie-points + * If @search is `TRUE`, before performing the transformation, the tie-points * are improved by searching an area of @sec of size @harea for a * match of size @hwindow to @ref. * * This function will only work well for small rotates and scales. * * ::: tip "Optional arguments" - * * @search: %gboolean, search to improve tie-points - * * @hwindow: %gint, half window size - * * @harea: %gint, half search size + * * @search: `gboolean`, search to improve tie-points + * * @hwindow: `gint`, half window size + * * @harea: `gint`, half search size * * @interpolate: [class@Interpolate], interpolate pixels with this * * Returns: 0 on success, -1 on error diff --git a/libvips/mosaicing/matrixinvert.c b/libvips/mosaicing/matrixinvert.c index 02bce4de2d..7de4dd2e11 100644 --- a/libvips/mosaicing/matrixinvert.c +++ b/libvips/mosaicing/matrixinvert.c @@ -462,7 +462,7 @@ vips_matrixinvert_init(VipsMatrixinvert *matrix) * vips_matrixinvert: (method) * @m: matrix to invert * @out: (out): output matrix - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation calculates the inverse of the matrix represented in @m. * The scale and offset members of the input matrix are ignored. diff --git a/libvips/mosaicing/matrixmultiply.c b/libvips/mosaicing/matrixmultiply.c index 9c62675ea3..13b2ed1bd4 100644 --- a/libvips/mosaicing/matrixmultiply.c +++ b/libvips/mosaicing/matrixmultiply.c @@ -172,7 +172,7 @@ vips_matrixmultiply_init(VipsMatrixmultiply *matrix) * @left: input matrix * @right: input matrix * @out: (out): output matrix - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Multiplies two matrix images. * diff --git a/libvips/mosaicing/merge.c b/libvips/mosaicing/merge.c index b8c7368b72..29fa0579ed 100644 --- a/libvips/mosaicing/merge.c +++ b/libvips/mosaicing/merge.c @@ -179,7 +179,7 @@ vips_merge_init(VipsMerge *merge) * @direction: horizontal or vertical merge * @dx: displacement of ref from sec * @dy: displacement of ref from sec - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation joins two images left-right (with @ref on the left) or * up-down (with @ref above) with a smooth seam. @@ -206,7 +206,7 @@ vips_merge_init(VipsMerge *merge) * This makes it possible to join non-rectangular images. * * ::: tip "Optional arguments" - * * @mblend: %gint, maximum blend size + * * @mblend: `gint`, maximum blend size * * ::: seealso * [method@Image.mosaic], [method@Image.insert]. diff --git a/libvips/mosaicing/mosaic.c b/libvips/mosaicing/mosaic.c index be7cdce97b..d4e4947ad1 100644 --- a/libvips/mosaicing/mosaic.c +++ b/libvips/mosaicing/mosaic.c @@ -318,7 +318,7 @@ vips_mosaic_init(VipsMosaic *mosaic) * @yref: position in reference image * @xsec: position in secondary image * @ysec: position in secondary image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation joins two images left-right (with @ref on the left) or * top-bottom (with @ref above) given an approximate overlap. @@ -340,16 +340,16 @@ vips_mosaic_init(VipsMosaic *mosaic) * @dx1, @dy1. * * ::: tip "Optional arguments" - * * @bandno: %gint, band to search for features - * * @hwindow: %gint, half window size - * * @harea: %gint, half search size - * * @mblend: %gint, maximum blend size - * * @dx0: %gint, output, detected displacement - * * @dy0: %gint, output, detected displacement - * * @scale1: %gdouble, output, detected first order scale - * * @angle1: %gdouble, output, detected first order rotation - * * @dx1: %gdouble, output, detected first order displacement - * * @dy1: %gdouble, output, detected first order displacement + * * @bandno: `gint`, band to search for features + * * @hwindow: `gint`, half window size + * * @harea: `gint`, half search size + * * @mblend: `gint`, maximum blend size + * * @dx0: `gint`, output, detected displacement + * * @dy0: `gint`, output, detected displacement + * * @scale1: `gdouble`, output, detected first order scale + * * @angle1: `gdouble`, output, detected first order rotation + * * @dx1: `gdouble`, output, detected first order displacement + * * @dy1: `gdouble`, output, detected first order displacement * * ::: seealso * [method@Image.merge], [method@Image.insert]. diff --git a/libvips/mosaicing/mosaic1.c b/libvips/mosaicing/mosaic1.c index 44b5f56f53..d83d5be9c7 100644 --- a/libvips/mosaicing/mosaic1.c +++ b/libvips/mosaicing/mosaic1.c @@ -639,14 +639,14 @@ vips_mosaic1_init(VipsMosaic1 *mosaic1) * @yr2: second reference tie-point * @xs2: second secondary tie-point * @ys2: second secondary tie-point - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operation joins two images top-bottom (with @sec on the right) * or left-right (with @sec at the bottom) * given an approximate pair of tie-points. @sec is scaled and rotated as * necessary before the join. * - * If @search is %TRUE, before performing the transformation, the tie-points + * If @search is `TRUE`, before performing the transformation, the tie-points * are improved by searching an area of @sec of size @harea for a * object of size @hwindow in @ref. * @@ -668,11 +668,11 @@ vips_mosaic1_init(VipsMosaic1 *mosaic1) * [arithmetic](libvips-arithmetic.html)). * * ::: tip "Optional arguments" - * * @search: %gboolean, search to improve tie-points - * * @hwindow: %gint, half window size - * * @harea: %gint, half search size + * * @search: `gboolean`, search to improve tie-points + * * @hwindow: `gint`, half window size + * * @harea: `gint`, half search size * * @interpolate: [class@Interpolate], interpolate pixels with this - * * @mblend: %gint, maximum blend size + * * @mblend: `gint`, maximum blend size * * ::: seealso * [method@Image.merge], [method@Image.insert], [method@Image.globalbalance]. diff --git a/libvips/mosaicing/remosaic.c b/libvips/mosaicing/remosaic.c index f0cdd83bfd..d6410ed885 100644 --- a/libvips/mosaicing/remosaic.c +++ b/libvips/mosaicing/remosaic.c @@ -198,7 +198,7 @@ vips_remosaic_init(VipsRemosaic *remosaic) * @out: (out): output image * @old_str: gamma of source images * @new_str: gamma of source images - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * [method@Image.remosaic] works rather as [method@Image.globalbalance]. It * takes apart the mosaiced image @in and rebuilds it, substituting images. diff --git a/libvips/resample/affine.c b/libvips/resample/affine.c index 7207779591..5c79e3ae6f 100644 --- a/libvips/resample/affine.c +++ b/libvips/resample/affine.c @@ -725,7 +725,7 @@ vips_affine_init(VipsAffine *affine) * @b: transformation matrix coefficient * @c: transformation matrix coefficient * @d: transformation matrix coefficient - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operator performs an affine transform on an image using @interpolate. * @@ -767,13 +767,13 @@ vips_affine_init(VipsAffine *affine) * ::: tip "Optional arguments" * * @interpolate: [class@Interpolate], interpolate pixels with this * * @oarea: [struct@ArrayInt], output rectangle - * * @idx: %gdouble, input horizontal offset - * * @idy: %gdouble, input vertical offset - * * @odx: %gdouble, output horizontal offset - * * @ody: %gdouble, output vertical offset + * * @idx: `gdouble`, input horizontal offset + * * @idy: `gdouble`, input vertical offset + * * @odx: `gdouble`, output horizontal offset + * * @ody: `gdouble`, output vertical offset * * @extend: [enum@Extend], how to generate new pixels * * @background: [struct@ArrayDouble] colour for new pixels - * * @premultiplied: %gboolean, images are already premultiplied + * * @premultiplied: `gboolean`, images are already premultiplied * * ::: seealso * [method@Image.shrink], [method@Image.resize], [class@Interpolate]. diff --git a/libvips/resample/mapim.c b/libvips/resample/mapim.c index 6ca97eb4a8..da879adddf 100644 --- a/libvips/resample/mapim.c +++ b/libvips/resample/mapim.c @@ -598,7 +598,7 @@ vips_mapim_init(VipsMapim *mapim) * @in: input image * @out: (out): output image * @index: index image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operator resamples @in using @index to look up pixels. * @@ -619,7 +619,7 @@ vips_mapim_init(VipsMapim *mapim) * @interpolate defaults to bilinear. * * By default, new pixels are filled with @background. This defaults to - * zero (black). You can set other extend types with @extend. #VIPS_EXTEND_COPY + * zero (black). You can set other extend types with @extend. [enum@Vips.Extend.COPY] * is better for image upsizing. * * Image are normally treated as unpremultiplied, so this operation can be used @@ -635,7 +635,7 @@ vips_mapim_init(VipsMapim *mapim) * * @interpolate: [class@Interpolate], interpolate pixels with this * * @extend: [enum@Vips.Extend], how to generate new pixels * * @background: [struct@ArrayDouble], colour for new pixels - * * @premultiplied: %gboolean, images are already premultiplied + * * @premultiplied: `gboolean`, images are already premultiplied * * ::: seealso * [ctor@Image.xyz], [method@Image.affine], [method@Image.resize], diff --git a/libvips/resample/quadratic.c b/libvips/resample/quadratic.c index 8635676639..6ea47193d9 100644 --- a/libvips/resample/quadratic.c +++ b/libvips/resample/quadratic.c @@ -341,7 +341,7 @@ vips_quadratic_init(VipsQuadratic *quadratic) * @in: input image * @out: (out): output image * @coeff: horizontal quadratic - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Transform an image with a 0, 1, 2, or 3rd order polynomial. * diff --git a/libvips/resample/reduce.c b/libvips/resample/reduce.c index 07b8f48341..9d356fd299 100644 --- a/libvips/resample/reduce.c +++ b/libvips/resample/reduce.c @@ -69,7 +69,7 @@ * @VIPS_KERNEL_MKS2013: Convolve with Magic Kernel Sharp 2013. * @VIPS_KERNEL_MKS2021: Convolve with Magic Kernel Sharp 2021. * - * The resampling kernels vips supports. See vips_reduce(), for example. + * The resampling kernels vips supports. See [method@Image.reduce], for example. */ @@ -204,7 +204,7 @@ vips_reduce_init(VipsReduce *reduce) * @out: (out): output image * @hshrink: horizontal shrink * @vshrink: vertical shrink - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Reduce @in by a pair of factors with a pair of 1D kernels. * diff --git a/libvips/resample/reduceh.cpp b/libvips/resample/reduceh.cpp index f9b3247f80..d98805247a 100644 --- a/libvips/resample/reduceh.cpp +++ b/libvips/resample/reduceh.cpp @@ -634,7 +634,7 @@ vips_reduceh_init(VipsReduceh *reduceh) * @in: input image * @out: (out): output image * @hshrink: horizontal reduce - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Reduce @in horizontally by a float factor. * @@ -654,7 +654,7 @@ vips_reduceh_init(VipsReduceh *reduceh) * * ::: tip "Optional arguments" * * @kernel: [enum@Kernel], to use to interpolate (default: lanczos3) - * * @gap: %gboolean, reducing gap to use (default: 0.0) + * * @gap: `gboolean`, reducing gap to use (default: 0.0) * * ::: seealso * [method@Image.shrink], [method@Image.resize], [method@Image.affine]. diff --git a/libvips/resample/reducev.cpp b/libvips/resample/reducev.cpp index 5fd5afd57d..f17d98737f 100644 --- a/libvips/resample/reducev.cpp +++ b/libvips/resample/reducev.cpp @@ -1118,7 +1118,7 @@ vips_reducev_init(VipsReducev *reducev) * @in: input image * @out: (out): output image * @vshrink: vertical reduce - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Reduce @in vertically by a float factor. * @@ -1138,7 +1138,7 @@ vips_reducev_init(VipsReducev *reducev) * * ::: tip "Optional arguments" * * @kernel: [enum@Kernel], to use to interpolate (default: lanczos3) - * * @gap: %gboolean, reducing gap to use (default: 0.0) + * * @gap: `gboolean`, reducing gap to use (default: 0.0) * * ::: seealso * [method@Image.shrink], [method@Image.resize], [method@Image.affine]. diff --git a/libvips/resample/resize.c b/libvips/resample/resize.c index ccbc880085..7d50fb4c97 100644 --- a/libvips/resample/resize.c +++ b/libvips/resample/resize.c @@ -400,7 +400,7 @@ vips_resize_init(VipsResize *resize) * @in: input image * @out: (out): output image * @scale: scale factor - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Resize an image. * @@ -435,9 +435,9 @@ vips_resize_init(VipsResize *resize) * channel, you should use [method@Image.premultiply] on it first. * * ::: tip "optional arguments" - * * @vscale: %gdouble, vertical scale factor + * * @vscale: `gdouble`, vertical scale factor * * @kernel: [enum@Kernel], to reduce with - * * @gap: %gdouble, reducing gap to use (default: 2.0) + * * @gap: `gdouble`, reducing gap to use (default: 2.0) * * ::: seealso * [method@Image.premultiply], [method@Image.shrink], [method@Image.reduce]. diff --git a/libvips/resample/shrink.c b/libvips/resample/shrink.c index c013f39b02..74d2def9d5 100644 --- a/libvips/resample/shrink.c +++ b/libvips/resample/shrink.c @@ -187,7 +187,7 @@ vips_shrink_init(VipsShrink *shrink) * @out: (out): output image * @hshrink: horizontal shrink * @vshrink: vertical shrink - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Shrink @in by a pair of factors with a simple box filter. * @@ -202,7 +202,7 @@ vips_shrink_init(VipsShrink *shrink) * be updated by the application. * * ::: tip "Optional arguments" - * * @ceil: %gboolean, round-up output dimensions + * * @ceil: `gboolean`, round-up output dimensions * * ::: seealso * [method@Image.resize], [method@Image.reduce]. diff --git a/libvips/resample/shrinkh.c b/libvips/resample/shrinkh.c index 88229ba277..6049a0e916 100644 --- a/libvips/resample/shrinkh.c +++ b/libvips/resample/shrinkh.c @@ -466,7 +466,7 @@ vips_shrinkh_init(VipsShrinkh *shrink) * @in: input image * @out: (out): output image * @hshrink: horizontal shrink - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Shrink @in horizontally by an integer factor. * Each pixel in the output is @@ -479,7 +479,7 @@ vips_shrinkh_init(VipsShrinkh *shrink) * be updated by the application. * * ::: tip "Optional arguments" - * * @ceil: %gboolean, round-up output dimensions + * * @ceil: `gboolean`, round-up output dimensions * * ::: seealso * [method@Image.shrinkv], [method@Image.shrink], [method@Image.resize], diff --git a/libvips/resample/shrinkv.c b/libvips/resample/shrinkv.c index ec8e13f53c..d45b996d2f 100644 --- a/libvips/resample/shrinkv.c +++ b/libvips/resample/shrinkv.c @@ -543,7 +543,7 @@ vips_shrinkv_init(VipsShrinkv *shrink) * @in: input image * @out: (out): output image * @vshrink: vertical shrink - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Shrink @in vertically by an integer factor. * @@ -557,7 +557,7 @@ vips_shrinkv_init(VipsShrinkv *shrink) * be updated by the application. * * ::: tip "Optional arguments" - * * @ceil: %gboolean, round-up output dimensions + * * @ceil: `gboolean`, round-up output dimensions * * ::: seealso * [method@Image.shrinkh], [method@Image.shrink], [method@Image.resize], diff --git a/libvips/resample/similarity.c b/libvips/resample/similarity.c index 5eeb12abeb..97215ee55a 100644 --- a/libvips/resample/similarity.c +++ b/libvips/resample/similarity.c @@ -220,21 +220,21 @@ vips_similarity_init(VipsSimilarity *similarity) * vips_similarity: (method) * @in: input image * @out: (out): output image - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * This operator calls [method@Image.affine] for you, calculating the matrix * for the affine transform from @scale and @angle. Other parameters are * passed on to [method@Image.affine] unaltered. * * ::: tip "Optional arguments" - * * @scale: %gdouble, scale by this factor - * * @angle: %gdouble, rotate by this many degrees clockwise + * * @scale: `gdouble`, scale by this factor + * * @angle: `gdouble`, rotate by this many degrees clockwise * * @interpolate: [class@Interpolate], interpolate pixels with this * * @background: [struct@ArrayDouble] colour for new pixels - * * @idx: %gdouble, input horizontal offset - * * @idy: %gdouble, input vertical offset - * * @odx: %gdouble, output horizontal offset - * * @ody: %gdouble, output vertical offset + * * @idx: `gdouble`, input horizontal offset + * * @idy: `gdouble`, input vertical offset + * * @odx: `gdouble`, output horizontal offset + * * @ody: `gdouble`, output vertical offset * * ::: seealso * [method@Image.affine], [class@Interpolate]. @@ -289,8 +289,8 @@ vips_rotate_init(VipsRotate *rotate) * vips_rotate: (method) * @in: input image * @out: (out): output image - * @angle: %gdouble, rotate by this many degrees clockwise - * @...: %NULL-terminated list of optional named arguments + * @angle: `gdouble`, rotate by this many degrees clockwise + * @...: `NULL`-terminated list of optional named arguments * * This operator calls [method@Image.affine] for you, calculating the matrix * for the affine transform from @scale and @angle. @@ -300,10 +300,10 @@ vips_rotate_init(VipsRotate *rotate) * ::: tip "Optional arguments" * * @interpolate: [class@Interpolate], interpolate pixels with this * * @background: [struct@ArrayDouble], colour for new pixels - * * @idx: %gdouble, input horizontal offset - * * @idy: %gdouble, input vertical offset - * * @odx: %gdouble, output horizontal offset - * * @ody: %gdouble, output vertical offset + * * @idx: `gdouble`, input horizontal offset + * * @idy: `gdouble`, input vertical offset + * * @odx: `gdouble`, output horizontal offset + * * @ody: `gdouble`, output vertical offset * * ::: seealso * [method@Image.affine], [class@Interpolate]. diff --git a/libvips/resample/thumbnail.c b/libvips/resample/thumbnail.c index f7b1f73c1b..36144e8bc5 100644 --- a/libvips/resample/thumbnail.c +++ b/libvips/resample/thumbnail.c @@ -1230,7 +1230,7 @@ vips_thumbnail_file_init(VipsThumbnailFile *file) * @filename: file to read from * @out: (out): output image * @width: target width in pixels - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Make a thumbnail from a file. * @@ -1256,17 +1256,15 @@ vips_thumbnail_file_init(VipsThumbnailFile *file) * details on the cropping strategy. * * Normally the operation will upsize or downsize as required to fit the image - * inside or outside the target size. If @size is set - * to #VIPS_SIZE_UP, the operation will only upsize and will just - * copy if asked to downsize. - * If @size is set - * to #VIPS_SIZE_DOWN, the operation will only downsize and will just - * copy if asked to upsize. - * If @size is #VIPS_SIZE_FORCE, the image aspect ratio will be broken and the - * image will be forced to fit the target. + * inside or outside the target size. If @size is set to [enum@Vips.Size.UP], + * the operation will only upsize and will just copy if asked to downsize. + * If @size is set to [enum@Vips.Size.DOWN], the operation will only downsize + * and will just copy if asked to upsize. + * If @size is [enum@Vips.Size.FORCE], the image aspect ratio will be broken + * and the image will be forced to fit the target. * * Normally any orientation tags on the input image (such as EXIF tags) are - * interpreted to rotate the image upright. If you set @no_rotate to %TRUE, + * interpreted to rotate the image upright. If you set @no_rotate to `TRUE`, * these tags will not be interpreted. * * Shrinking is normally done in sRGB colourspace. Set @linear to shrink in @@ -1281,19 +1279,19 @@ vips_thumbnail_file_init(VipsThumbnailFile *file) * input image is broken. * * Use @intent to set the rendering intent for any ICC transform. The default - * is #VIPS_INTENT_RELATIVE. + * is [enum@Vips.Intent.RELATIVE]. * * Use @fail_on to control the types of error that will cause loading to fail. - * The default is #VIPS_FAIL_ON_NONE, ie. thumbnail is permissive. + * The default is [enum@Vips.FailOn.NONE], ie. thumbnail is permissive. * * ::: tip "Optional arguments" - * * @height: %gint, target height in pixels + * * @height: `gint`, target height in pixels * * @size: [enum@Size], upsize, downsize, both or force - * * @no_rotate: %gboolean, don't rotate upright using orientation tag + * * @no_rotate: `gboolean`, don't rotate upright using orientation tag * * @crop: [enum@Interesting], shrink and crop to fill target - * * @linear: %gboolean, perform shrink in linear light - * * @input_profile: %gchararray, fallback input ICC profile - * * @output_profile: %gchararray, output ICC profile + * * @linear: `gboolean`, perform shrink in linear light + * * @input_profile: `gchararray`, fallback input ICC profile + * * @output_profile: `gchararray`, output ICC profile * * @intent: [enum@Intent], rendering intent * * @fail_on: [enum@FailOn], load error types to fail on * @@ -1487,7 +1485,7 @@ vips_thumbnail_buffer_init(VipsThumbnailBuffer *buffer) * @len: (type gsize): size of memory area * @out: (out): output image * @width: target width in pixels - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.thumbnail], but read from a memory buffer. * @@ -1495,16 +1493,16 @@ vips_thumbnail_buffer_init(VipsThumbnailBuffer *buffer) * underlying loader. * * ::: tip "Optional arguments" - * * @height: %gint, target height in pixels + * * @height: `gint`, target height in pixels * * @size: [enum@Size], upsize, downsize, both or force - * * @no_rotate: %gboolean, don't rotate upright using orientation tag + * * @no_rotate: `gboolean`, don't rotate upright using orientation tag * * @crop: [enum@Interesting], shrink and crop to fill target - * * @linear: %gboolean, perform shrink in linear light - * * @input_profile: %gchararray, fallback input ICC profile - * * @output_profile: %gchararray, output ICC profile + * * @linear: `gboolean`, perform shrink in linear light + * * @input_profile: `gchararray`, fallback input ICC profile + * * @output_profile: `gchararray`, output ICC profile * * @intent: [enum@Intent], rendering intent * * @fail_on: [enum@FailOn], load error types to fail on - * * @option_string: %gchararray, extra loader options + * * @option_string: `gchararray`, extra loader options * * ::: seealso * [ctor@Image.thumbnail]. @@ -1700,7 +1698,7 @@ vips_thumbnail_source_init(VipsThumbnailSource *source) * @source: source to thumbnail * @out: (out): output image * @width: target width in pixels - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.thumbnail], but read from a source. * @@ -1709,16 +1707,16 @@ vips_thumbnail_source_init(VipsThumbnailSource *source) * loader. * * ::: tip "Optional arguments" - * * @height: %gint, target height in pixels + * * @height: `gint`, target height in pixels * * @size: [enum@Size], upsize, downsize, both or force - * * @no_rotate: %gboolean, don't rotate upright using orientation tag + * * @no_rotate: `gboolean`, don't rotate upright using orientation tag * * @crop: [enum@Interesting], shrink and crop to fill target - * * @linear: %gboolean, perform shrink in linear light - * * @input_profile: %gchararray, fallback input ICC profile - * * @output_profile: %gchararray, output ICC profile + * * @linear: `gboolean`, perform shrink in linear light + * * @input_profile: `gchararray`, fallback input ICC profile + * * @output_profile: `gchararray`, output ICC profile * * @intent: [enum@Intent], rendering intent * * @fail_on: [enum@FailOn], load error types to fail on - * * @option_string: %gchararray, extra loader options + * * @option_string: `gchararray`, extra loader options * * ::: seealso * [ctor@Image.thumbnail]. @@ -1818,7 +1816,7 @@ vips_thumbnail_image_init(VipsThumbnailImage *image) * @in: input image * @out: (out): output image * @width: target width in pixels - * @...: %NULL-terminated list of optional named arguments + * @...: `NULL`-terminated list of optional named arguments * * Exactly as [ctor@Image.thumbnail], but read from an existing image. * @@ -1828,13 +1826,13 @@ vips_thumbnail_image_init(VipsThumbnailImage *image) * output. Only use this operation if you really have to. * * ::: tip "Optional arguments" - * * @height: %gint, target height in pixels + * * @height: `gint`, target height in pixels * * @size: [enum@Size], upsize, downsize, both or force - * * @no_rotate: %gboolean, don't rotate upright using orientation tag + * * @no_rotate: `gboolean`, don't rotate upright using orientation tag * * @crop: [enum@Interesting], shrink and crop to fill target - * * @linear: %gboolean, perform shrink in linear light - * * @input_profile: %gchararray, fallback input ICC profile - * * @output_profile: %gchararray, output ICC profile + * * @linear: `gboolean`, perform shrink in linear light + * * @input_profile: `gchararray`, fallback input ICC profile + * * @output_profile: `gchararray`, output ICC profile * * @intent: [enum@Intent], rendering intent * * @fail_on: [enum@FailOn], load error types to fail on * From d71e242100761f5273b89edb8a172b7797f48644 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 8 May 2025 15:18:49 +0100 Subject: [PATCH 162/174] turn http links in doc comments to markdown --- libvips/colour/LabQ2sRGB.c | 3 ++- libvips/colour/icc_transform.c | 8 ++++---- libvips/conversion/conversion.c | 5 ++--- libvips/create/perlin.c | 7 ++----- libvips/create/worley.c | 7 ++----- 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/libvips/colour/LabQ2sRGB.c b/libvips/colour/LabQ2sRGB.c index a09cb15521..55a9335bb7 100644 --- a/libvips/colour/LabQ2sRGB.c +++ b/libvips/colour/LabQ2sRGB.c @@ -394,7 +394,8 @@ vips_col_scRGB2BW(int range, int *lut, float R, float G, float B, int Yi; float v; - /* CIE linear luminance function, see https://en.wikipedia.org/wiki/Grayscale#Colorimetric_(perceptual_luminance-preserving)_conversion_to_grayscale + /* CIE linear luminance function, see + * https://en.wikipedia.org/wiki/Grayscale#Colorimetric_(perceptual_luminance-preserving)_conversion_to_grayscale */ Y = 0.2126F * R + 0.7152F * G + 0.0722F * B; diff --git a/libvips/colour/icc_transform.c b/libvips/colour/icc_transform.c index b3a61d5c7b..dd84b575bd 100644 --- a/libvips/colour/icc_transform.c +++ b/libvips/colour/icc_transform.c @@ -907,8 +907,8 @@ decode_xyz(guint16 *fixed, float *xyz, int n) Z *= SCALE; /* Transform XYZ D50 to D65, chromatic adaption is done with the - * Bradford transformation. - * See: https://fujiwaratko.sakura.ne.jp/infosci/colorspace/bradford_e.html + * Bradford transformation. See: + * https://fujiwaratko.sakura.ne.jp/infosci/colorspace/bradford_e.html */ xyz[0] = 0.955513F * X + -0.023073F * Y + @@ -1070,8 +1070,8 @@ encode_xyz(float *in, float *out, int n) float Z = in[2] / SCALE; /* Transform XYZ D65 to D50, chromatic adaption is done with the - * Bradford transformation. - * See: https://fujiwaratko.sakura.ne.jp/infosci/colorspace/bradford_e.html + * Bradford transformation. See: + * https://fujiwaratko.sakura.ne.jp/infosci/colorspace/bradford_e.html */ out[0] = 1.047886F * X + 0.022919F * Y + diff --git a/libvips/conversion/conversion.c b/libvips/conversion/conversion.c index 72b6d9d885..050144efa4 100644 --- a/libvips/conversion/conversion.c +++ b/libvips/conversion/conversion.c @@ -153,9 +153,8 @@ * The various Porter-Duff and PDF blend modes. See [func@Image.composite], * for example. * - * The Cairo docs have a nice explanation of all the blend modes: - * - * https://www.cairographics.org/operators + * The Cairo docs have [a nice explanation of all the blend + * modes](https://www.cairographics.org/operators). * * The non-separable modes are not implemented. */ diff --git a/libvips/create/perlin.c b/libvips/create/perlin.c index f9e2f4a3e6..19ee8a1cad 100644 --- a/libvips/create/perlin.c +++ b/libvips/create/perlin.c @@ -341,11 +341,8 @@ vips_perlin_init(VipsPerlin *perlin) * @height: vertical size * @...: `NULL`-terminated list of optional named arguments * - * Create a one-band float image of Perlin noise. - * - * See: - * - * https://en.wikipedia.org/wiki/Perlin_noise + * Create a one-band float image of [Perlin + * noise](https://en.wikipedia.org/wiki/Perlin_noise). * * Use @cell_size to set the size of the cells from which the image is * constructed. The default is 256 x 256. diff --git a/libvips/create/worley.c b/libvips/create/worley.c index 3db7a1e5e1..a4f7b9d894 100644 --- a/libvips/create/worley.c +++ b/libvips/create/worley.c @@ -347,11 +347,8 @@ vips_worley_init(VipsWorley *worley) * @height: vertical size * @...: `NULL`-terminated list of optional named arguments * - * Create a one-band float image of Worley noise. - * - * See: - * - * https://en.wikipedia.org/wiki/Worley_noise + * Create a one-band float image of [Worley + * noise](https://en.wikipedia.org/wiki/Worley_noise). * * Use @cell_size to set the size of the cells from which the image is * constructed. The default is 256 x 256. From cdecf6e73631d1128519c22e36b2ee52b91a7507 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 8 May 2025 15:25:52 +0100 Subject: [PATCH 163/174] use "--" for dash, not "---" markdown uses "--" for a long dash, not "---". --- libvips/arithmetic/boolean.c | 2 +- libvips/arithmetic/math.c | 2 +- libvips/arithmetic/math2.c | 2 +- libvips/arithmetic/relational.c | 2 +- libvips/arithmetic/round.c | 2 +- libvips/arithmetic/stats.c | 2 +- libvips/conversion/bandbool.c | 2 +- libvips/conversion/conversion.c | 12 ++++++------ libvips/conversion/ifthenelse.c | 2 +- libvips/conversion/insert.c | 2 +- libvips/convolution/conva.c | 4 ++-- libvips/convolution/convf.c | 2 +- libvips/convolution/convi.c | 2 +- libvips/create/mask_butterworth.c | 2 +- libvips/create/mask_butterworth_band.c | 2 +- libvips/create/mask_butterworth_ring.c | 2 +- libvips/deprecated/im_vips2dz.c | 2 +- libvips/deprecated/rename.c | 4 ++-- libvips/deprecated/vips7compat.c | 2 +- libvips/foreign/cgifsave.c | 2 +- libvips/foreign/foreign.c | 6 +++--- libvips/foreign/jpeg2vips.c | 2 +- libvips/foreign/magick.c | 2 +- libvips/foreign/svgload.c | 2 +- libvips/foreign/tiff2vips.c | 4 ++-- libvips/foreign/webpsave.c | 2 +- libvips/histogram/hist_local.c | 2 +- libvips/iofuncs/error.c | 2 +- libvips/iofuncs/gate.c | 4 ++-- libvips/iofuncs/generate.c | 2 +- libvips/iofuncs/image.c | 8 ++++---- libvips/iofuncs/init.c | 2 +- libvips/iofuncs/memory.c | 8 ++++---- libvips/iofuncs/vips.c | 2 +- libvips/morphology/morph.c | 2 +- libvips/morphology/rank.c | 2 +- libvips/mosaicing/chkpair.c | 2 +- libvips/mosaicing/global_balance.c | 2 +- 38 files changed, 55 insertions(+), 55 deletions(-) diff --git a/libvips/arithmetic/boolean.c b/libvips/arithmetic/boolean.c index dc9a54a1ab..6a679b04c7 100644 --- a/libvips/arithmetic/boolean.c +++ b/libvips/arithmetic/boolean.c @@ -1,4 +1,4 @@ -/* boolean.c --- various bit operations +/* boolean.c -- various bit operations * * Modified: * 15/12/94 JC diff --git a/libvips/arithmetic/math.c b/libvips/arithmetic/math.c index 243f435921..18832715d1 100644 --- a/libvips/arithmetic/math.c +++ b/libvips/arithmetic/math.c @@ -1,4 +1,4 @@ -/* VipsMath --- call various -lm functions (trig, log etc.) on images +/* VipsMath -- call various -lm functions (trig, log etc.) on images * * Copyright: 1990, N. Dessipris, based on im_powtra() * Author: Nicos Dessipris diff --git a/libvips/arithmetic/math2.c b/libvips/arithmetic/math2.c index 3f4c83e041..9fcaecfef4 100644 --- a/libvips/arithmetic/math2.c +++ b/libvips/arithmetic/math2.c @@ -1,4 +1,4 @@ -/* math2.c --- 2ary math funcs +/* math2.c -- 2ary math funcs * * Copyright: 1990, N. Dessipris * diff --git a/libvips/arithmetic/relational.c b/libvips/arithmetic/relational.c index 54ad5a615a..1ecbe0810e 100644 --- a/libvips/arithmetic/relational.c +++ b/libvips/arithmetic/relational.c @@ -1,4 +1,4 @@ -/* relational.c --- various relational operations +/* relational.c -- various relational operations * * Modified: * 26/7/93 JC diff --git a/libvips/arithmetic/round.c b/libvips/arithmetic/round.c index 361f283665..76e22e3965 100644 --- a/libvips/arithmetic/round.c +++ b/libvips/arithmetic/round.c @@ -1,4 +1,4 @@ -/* round.c --- various rounding operations +/* round.c -- various rounding operations * * 20/6/02 JC * - adapted from im_abs() diff --git a/libvips/arithmetic/stats.c b/libvips/arithmetic/stats.c index a6b826cbbb..e16681f087 100644 --- a/libvips/arithmetic/stats.c +++ b/libvips/arithmetic/stats.c @@ -14,7 +14,7 @@ 31/8/93 JC - forgot to init global max/min properly! sorry. 21/6/95 JC - - still did not init max and min correctly --- now fixed for good + - still did not init max and min correctly -- now fixed for good * 13/1/05 * - use 64 bit arithmetic diff --git a/libvips/conversion/bandbool.c b/libvips/conversion/bandbool.c index 07592cc268..69f6109d6d 100644 --- a/libvips/conversion/bandbool.c +++ b/libvips/conversion/bandbool.c @@ -1,4 +1,4 @@ -/* bandbool.c --- bool op across image bands +/* bandbool.c -- bool op across image bands * * 7/12/12 * - from boolean.c diff --git a/libvips/conversion/conversion.c b/libvips/conversion/conversion.c index 050144efa4..4787e9ad1e 100644 --- a/libvips/conversion/conversion.c +++ b/libvips/conversion/conversion.c @@ -259,19 +259,19 @@ * When the edges of an image are extended, you can specify * how you want the extension done. * - * [enum@Vips.Extend.BLACK] --- new pixels are black, ie. all bits are zero. + * [enum@Vips.Extend.BLACK] -- new pixels are black, ie. all bits are zero. * - * [enum@Vips.Extend.COPY] --- each new pixel takes the value of the nearest edge + * [enum@Vips.Extend.COPY] -- each new pixel takes the value of the nearest edge * pixel * - * [enum@Vips.Extend.REPEAT] --- the image is tiled to fill the new area + * [enum@Vips.Extend.REPEAT] -- the image is tiled to fill the new area * - * [enum@Vips.Extend.MIRROR] --- the image is reflected and tiled to reduce hash + * [enum@Vips.Extend.MIRROR] -- the image is reflected and tiled to reduce hash * edges * - * [enum@Vips.Extend.WHITE] --- new pixels are white, ie. all bits are set + * [enum@Vips.Extend.WHITE] -- new pixels are white, ie. all bits are set * - * [enum@Vips.Extend.BACKGROUND] --- colour set from the @background property + * [enum@Vips.Extend.BACKGROUND] -- colour set from the @background property * * We have to specify the exact value of each enum member since we have to * keep these frozen for back compat with vips7. diff --git a/libvips/conversion/ifthenelse.c b/libvips/conversion/ifthenelse.c index 265af4a1e3..d89e7ddd9b 100644 --- a/libvips/conversion/ifthenelse.c +++ b/libvips/conversion/ifthenelse.c @@ -1,4 +1,4 @@ -/* ifthenelse.c --- use a condition image to join two images together +/* ifthenelse.c -- use a condition image to join two images together * * Modified: * 9/2/95 JC diff --git a/libvips/conversion/insert.c b/libvips/conversion/insert.c index 92f787f112..c38945db1e 100644 --- a/libvips/conversion/insert.c +++ b/libvips/conversion/insert.c @@ -139,7 +139,7 @@ vips__insert_just_one(VipsRegion *out_region, VipsRegion *ir, int x, int y) return 0; } -/* Paste in parts of ir that fall within out_region --- ir is an input REGION +/* Paste in parts of ir that fall within out_region -- ir is an input REGION * for an image positioned at pos within out_region. * * Also used by vips_arrayjoin. diff --git a/libvips/convolution/conva.c b/libvips/convolution/conva.c index 06f17c5e67..bf69ea7e22 100644 --- a/libvips/convolution/conva.c +++ b/libvips/convolution/conva.c @@ -983,7 +983,7 @@ vips_conva_horizontal(VipsConva *conva, VipsImage *in, VipsImage **out) { VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(conva); - /* Prepare output. Consider a 7x7 mask and a 7x7 image --- the output + /* Prepare output. Consider a 7x7 mask and a 7x7 image -- the output * would be 1x1. */ *out = vips_image_new(); @@ -1233,7 +1233,7 @@ vips_conva_vertical(VipsConva *conva, VipsImage *in, VipsImage **out) VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(conva); VipsConvolution *convolution = (VipsConvolution *) conva; - /* Prepare output. Consider a 7x7 mask and a 7x7 image --- the output + /* Prepare output. Consider a 7x7 mask and a 7x7 image -- the output * would be 1x1. */ *out = vips_image_new(); diff --git a/libvips/convolution/convf.c b/libvips/convolution/convf.c index 8bd3b18862..0d19592b5d 100644 --- a/libvips/convolution/convf.c +++ b/libvips/convolution/convf.c @@ -347,7 +347,7 @@ vips_convf_build(VipsObject *object) convolution->out->Xoffset = 0; convolution->out->Yoffset = 0; - /* Prepare output. Consider a 7x7 mask and a 7x7 image --- the output + /* Prepare output. Consider a 7x7 mask and a 7x7 image -- the output * would be 1x1. */ if (vips_band_format_isint(in->BandFmt)) diff --git a/libvips/convolution/convi.c b/libvips/convolution/convi.c index 185e01e83e..68c9b31dc3 100644 --- a/libvips/convolution/convi.c +++ b/libvips/convolution/convi.c @@ -1213,7 +1213,7 @@ vips_convi_build(VipsObject *object) convolution->out->Xoffset = 0; convolution->out->Yoffset = 0; - /* Prepare output. Consider a 7x7 mask and a 7x7 image --- the output + /* Prepare output. Consider a 7x7 mask and a 7x7 image -- the output * would be 1x1. */ convolution->out->Xsize -= M->Xsize - 1; diff --git a/libvips/create/mask_butterworth.c b/libvips/create/mask_butterworth.c index 4982670426..c1dff6da31 100644 --- a/libvips/create/mask_butterworth.c +++ b/libvips/create/mask_butterworth.c @@ -133,7 +133,7 @@ vips_mask_butterworth_init(VipsMaskButterworth *butterworth) * range 0 - 1. * * The shape of the curve is controlled by - * @order --- higher values give a sharper transition. See Gonzalez and Wintz, + * @order -- higher values give a sharper transition. See Gonzalez and Wintz, * Digital Image Processing, 1987. * * ::: tip "Optional arguments" diff --git a/libvips/create/mask_butterworth_band.c b/libvips/create/mask_butterworth_band.c index 7053bcbddd..40bd010b68 100644 --- a/libvips/create/mask_butterworth_band.c +++ b/libvips/create/mask_butterworth_band.c @@ -175,7 +175,7 @@ vips_mask_butterworth_band_init( * @frequency_cutoff_y, of radius @radius. * * The shape of the curve is controlled by - * @order --- higher values give a sharper transition. See Gonzalez and Wintz, + * @order -- higher values give a sharper transition. See Gonzalez and Wintz, * Digital Image Processing, 1987. * * ::: tip "Optional arguments" diff --git a/libvips/create/mask_butterworth_ring.c b/libvips/create/mask_butterworth_ring.c index bccb2e6fdb..ecca3291ea 100644 --- a/libvips/create/mask_butterworth_ring.c +++ b/libvips/create/mask_butterworth_ring.c @@ -135,7 +135,7 @@ vips_mask_butterworth_ring_init( * in the range 0 - 1. * * The shape of the curve is controlled by - * @order --- higher values give a sharper transition. See Gonzalez and Wintz, + * @order -- higher values give a sharper transition. See Gonzalez and Wintz, * Digital Image Processing, 1987. * * ::: tip "Optional arguments" diff --git a/libvips/deprecated/im_vips2dz.c b/libvips/deprecated/im_vips2dz.c index c4c0c648e1..d64bc33a34 100644 --- a/libvips/deprecated/im_vips2dz.c +++ b/libvips/deprecated/im_vips2dz.c @@ -63,7 +63,7 @@ im_vips2dz(IMAGE *in, const char *filename) gboolean centre = FALSE; VipsAngle angle = VIPS_ANGLE_D0; - /* We can't use im_filename_split() --- it assumes that we have a + /* We can't use im_filename_split() -- it assumes that we have a * filename with an extension before the ':', and filename here is * actually a dirname. * diff --git a/libvips/deprecated/rename.c b/libvips/deprecated/rename.c index 0e8d2affcd..9a38453178 100644 --- a/libvips/deprecated/rename.c +++ b/libvips/deprecated/rename.c @@ -1,4 +1,4 @@ -/* rename.c --- wrappers for various renamed functions +/* rename.c -- wrappers for various renamed functions * * 20/9/09 */ @@ -467,7 +467,7 @@ vips_rawsave_fd(VipsImage *in, int fd, ...) va_list ap; int result; VipsTarget *target; - + if (!(target = vips_target_new_to_descriptor(fd))) return -1; diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 067f39fa89..b637bcaa2c 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -765,7 +765,7 @@ im_wrapmany(IMAGE **in, IMAGE *out, im_wrapmany_fn fn, void *a, void *b) bun->a = a; bun->b = b; - /* Check descriptors --- make sure that our caller has done this + /* Check descriptors -- make sure that our caller has done this * correctly. */ for (i = 0; i < n; i++) { diff --git a/libvips/foreign/cgifsave.c b/libvips/foreign/cgifsave.c index 8e02266f10..5ecca78d6c 100644 --- a/libvips/foreign/cgifsave.c +++ b/libvips/foreign/cgifsave.c @@ -499,7 +499,7 @@ vips_foreign_save_cgif_pick_quantiser(VipsForeignSaveCgif *cgif, return 0; } -/* We have a complete frame --- write! +/* We have a complete frame -- write! */ static int vips_foreign_save_cgif_write_frame(VipsForeignSaveCgif *cgif) diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index a8576f14f4..4fb4a7e76c 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -2693,7 +2693,7 @@ vips_jxlsave_target(VipsImage *in, VipsTarget *target, ...) * * Render a PDF file into a VIPS image. * - * The output image is always RGBA --- CMYK PDFs will be + * The output image is always RGBA -- CMYK PDFs will be * converted. If you need CMYK bitmaps, you should use [ctor@Image.magickload] * instead. * @@ -2701,8 +2701,8 @@ vips_jxlsave_target(VipsImage *in, VipsTarget *target, ...) * * Use @n to select the number of pages to render. The default is 1. Pages are * rendered in a vertical column, with each individual page aligned to the - * left. Set to -1 to mean "until the end of the document". Use [method@Image.grid] - * to change page layout. + * left. Set to -1 to mean "until the end of the document". Use + * [method@Image.grid] to change page layout. * * Use @dpi to set the rendering resolution. The default is 72. Additionally, * you can scale by setting @scale. If you set both, they combine. diff --git a/libvips/foreign/jpeg2vips.c b/libvips/foreign/jpeg2vips.c index fa5568d335..d6c77624fd 100644 --- a/libvips/foreign/jpeg2vips.c +++ b/libvips/foreign/jpeg2vips.c @@ -230,7 +230,7 @@ source_init_source(j_decompress_ptr cinfo) */ } -/* Fill the input buffer --- called whenever buffer is emptied. +/* Fill the input buffer -- called whenever buffer is emptied. */ static boolean source_fill_input_buffer(j_decompress_ptr cinfo) diff --git a/libvips/foreign/magick.c b/libvips/foreign/magick.c index 81beac36d8..1cf7ef1ce9 100644 --- a/libvips/foreign/magick.c +++ b/libvips/foreign/magick.c @@ -52,7 +52,7 @@ #if defined(HAVE_MAGICK6) || defined(HAVE_MAGICK7) -/* Imagemagick has weak support for some formats --- for example, AVI is +/* Imagemagick has weak support for some formats -- for example, AVI is * delegated to ffmpeg, and just getting the header can take many seconds and * many GB of memory. * diff --git a/libvips/foreign/svgload.c b/libvips/foreign/svgload.c index 6596aefabf..f94a2007c9 100644 --- a/libvips/foreign/svgload.c +++ b/libvips/foreign/svgload.c @@ -526,7 +526,7 @@ vips_foreign_load_svg_get_scaled_size(VipsForeignLoadSvg *svg, if (vips_foreign_load_svg_get_natural_size(svg, &width, &height)) return -1; - /* We scale up with cairo --- scaling with rsvg_handle_set_dpi() will + /* We scale up with cairo -- scaling with rsvg_handle_set_dpi() will * fail for SVGs with absolute sizes. */ svg->cairo_scale = svg->scale * svg->dpi / 72.0; diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index 1eb03edd3d..f9b7380f6d 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -2000,7 +2000,7 @@ rtiff_decompress_jpeg_fill_input_buffer(j_decompress_ptr cinfo) return TRUE; } -/* Skip data --- used to skip over a potentially large amount of +/* Skip data -- used to skip over a potentially large amount of * uninteresting data (such as an APPn marker). * * Writers of suspendable-input applications must note that skip_input_data @@ -2018,7 +2018,7 @@ rtiff_decompress_jpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes) /* Just a dumb implementation for now. Could use fseek() except * it doesn't work on pipes. Not clear that being smart is worth - * any trouble anyway --- large skips are infrequent. + * any trouble anyway -- large skips are infrequent. */ if (num_bytes > 0) { while (num_bytes > (long) src->bytes_in_buffer) { diff --git a/libvips/foreign/webpsave.c b/libvips/foreign/webpsave.c index 7284b64c16..2ad31c4916 100644 --- a/libvips/foreign/webpsave.c +++ b/libvips/foreign/webpsave.c @@ -312,7 +312,7 @@ vips_foreign_save_webp_get_delay(VipsForeignSaveWebp *webp, int page_number) return delay <= 10 ? 100 : delay; } -/* We have a complete frame --- write! +/* We have a complete frame -- write! */ static int vips_foreign_save_webp_write_frame(VipsForeignSaveWebp *webp) diff --git a/libvips/histogram/hist_local.c b/libvips/histogram/hist_local.c index bb5786bd87..1bb91bb4c1 100644 --- a/libvips/histogram/hist_local.c +++ b/libvips/histogram/hist_local.c @@ -257,7 +257,7 @@ vips_hist_local_generate(VipsRegion *out_region, q[b] = 255 * sum / (local->width * local->height); - /* Adapt histogram --- remove the pels from + /* Adapt histogram -- remove the pels from * the left hand column, add in pels for a * new right-hand column. */ diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index fd1e8d5932..d793919f33 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -1,4 +1,4 @@ -/* error.c --- error message handling +/* error.c -- error message handling * * Copyright: N. Dessipris * Written on: 18/03/1991 diff --git a/libvips/iofuncs/gate.c b/libvips/iofuncs/gate.c index d8db5985fe..7282ffd23c 100644 --- a/libvips/iofuncs/gate.c +++ b/libvips/iofuncs/gate.c @@ -1,4 +1,4 @@ -/* gate.c --- thread profiling +/* gate.c -- thread profiling * * Written on: 18 nov 13 */ @@ -205,7 +205,7 @@ thread_profile_destroy_notify(gpointer data) * been called. */ if (vips__thread_profile) - g_warning("discarding unsaved state for thread %p --- " + g_warning("discarding unsaved state for thread %p -- " "call vips_thread_shutdown() for this thread", profile->thread); diff --git a/libvips/iofuncs/generate.c b/libvips/iofuncs/generate.c index f568957179..b6d5594750 100644 --- a/libvips/iofuncs/generate.c +++ b/libvips/iofuncs/generate.c @@ -535,7 +535,7 @@ vips_start_many(VipsImage *out, void *a, void *b) * @out: free array when this image closes * @...: `NULL`-terminated list of input images * - * Convenience function --- make a `NULL`-terminated array of input images. + * Convenience function -- make a `NULL`-terminated array of input images. * Use with [func@start_many]. * * ::: seealso diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 9cbc517036..b1c062b625 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -2061,7 +2061,7 @@ vips_image_new_from_memory(const void *data, size_t size, if (size < VIPS_IMAGE_SIZEOF_IMAGE(image)) { vips_error("VipsImage", - _("memory area too small --- " + _("memory area too small -- " "should be %" G_GINT64_FORMAT " bytes, you passed %zd"), VIPS_IMAGE_SIZEOF_IMAGE(image), size); VIPS_UNREF(image); @@ -2366,7 +2366,7 @@ vips_image_new_matrix_from_array(int width, int height, if (size != width * height) { vips_error("VipsImage", - _("bad array length --- should be %d, you passed %d"), + _("bad array length -- should be %d, you passed %d"), width * height, size); return NULL; } @@ -2890,9 +2890,9 @@ vips_image_write_to_memory(VipsImage *in, size_t *size_out) size = VIPS_IMAGE_SIZEOF_IMAGE(in); if (!(buf = g_try_malloc(size))) { vips_error("vips_image_write_to_memory", - _("out of memory --- size == %dMB"), + _("out of memory -- size == %dMB"), (int) (size / (1024.0 * 1024.0))); - g_warning(_("out of memory --- size == %dMB"), + g_warning(_("out of memory -- size == %dMB"), (int) (size / (1024.0 * 1024.0))); return NULL; } diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 5908917479..7a0cb913ed 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -243,7 +243,7 @@ vips_get_prgname(void) * and the threading system, if necessary * * + guesses where the VIPS data files are and sets up - * internationalisation --- see [func@guess_prefix] + * internationalisation -- see [func@guess_prefix] * * + creates the main vips types, including [class@Image] and friends * diff --git a/libvips/iofuncs/memory.c b/libvips/iofuncs/memory.c index dcd814055a..7ad727d143 100644 --- a/libvips/iofuncs/memory.c +++ b/libvips/iofuncs/memory.c @@ -317,9 +317,9 @@ vips_tracked_malloc(size_t size) #endif /*DEBUG*/ vips_error("vips_tracked", - _("out of memory --- size == %dMB"), + _("out of memory -- size == %dMB"), (int) (size / (1024.0 * 1024.0))); - g_warning(_("out of memory --- size == %dMB"), + g_warning(_("out of memory -- size == %dMB"), (int) (size / (1024.0 * 1024.0))); return NULL; @@ -391,9 +391,9 @@ vips_tracked_aligned_alloc(size_t size, size_t align) #endif /*DEBUG*/ vips_error("vips_tracked", - _("out of memory --- size == %dMB"), + _("out of memory -- size == %dMB"), (int) (size / (1024.0 * 1024.0))); - g_warning(_("out of memory --- size == %dMB"), + g_warning(_("out of memory -- size == %dMB"), (int) (size / (1024.0 * 1024.0))); return NULL; diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index 879006aa9c..078e669e4a 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -372,7 +372,7 @@ vips__read_header_bytes(VipsImage *im, unsigned char *from) * pixel interpretation, don't clip them. */ - /* Coding values imply Bands and BandFmt settings --- make sure they + /* Coding values imply Bands and BandFmt settings -- make sure they * are sane. */ switch (im->Coding) { diff --git a/libvips/morphology/morph.c b/libvips/morphology/morph.c index a02a9cd568..5cdb83c417 100644 --- a/libvips/morphology/morph.c +++ b/libvips/morphology/morph.c @@ -921,7 +921,7 @@ vips_morph_build(VipsObject *object) VIPS_DEMAND_STYLE_SMALLTILE, in, NULL)) return -1; - /* Prepare output. Consider a 7x7 mask and a 7x7 image --- the output + /* Prepare output. Consider a 7x7 mask and a 7x7 image -- the output * would be 1x1. */ morph->out->Xsize -= M->Xsize - 1; diff --git a/libvips/morphology/rank.c b/libvips/morphology/rank.c index 85b782f0a4..cebb665e79 100644 --- a/libvips/morphology/rank.c +++ b/libvips/morphology/rank.c @@ -223,7 +223,7 @@ vips_rank_generate_uchar(VipsRegion *out_region, } q[b] = i; - /* Adapt histogram --- remove the pels from + /* Adapt histogram -- remove the pels from * the left hand column, add in pels for a * new right-hand column. */ diff --git a/libvips/mosaicing/chkpair.c b/libvips/mosaicing/chkpair.c index 7bcf6faf6b..75e7b74d9c 100644 --- a/libvips/mosaicing/chkpair.c +++ b/libvips/mosaicing/chkpair.c @@ -81,7 +81,7 @@ * returned, together with the correlation at that point. * * Only the first band of each image is correlated. @ref and @sec may be - * very large --- the function extracts and generates just the + * very large -- the function extracts and generates just the * parts needed. Correlation is done with [method@Image.spcor]; the position * of the maximum is found with [method@Image.max]. * diff --git a/libvips/mosaicing/global_balance.c b/libvips/mosaicing/global_balance.c index 29c16aaf8f..1ba48ff9f6 100644 --- a/libvips/mosaicing/global_balance.c +++ b/libvips/mosaicing/global_balance.c @@ -1761,7 +1761,7 @@ analyse_mosaic(SymbolTable *st, VipsImage *in) return 0; } -/* Scale im by fac --- if it's uchar/ushort, use a lut. If we can use a lut, +/* Scale im by fac -- if it's uchar/ushort, use a lut. If we can use a lut, * transform in linear space. If we can't, don't bother for efficiency. */ static VipsImage * From 06c07715288b400901e32c44f9b224168cad7fa9 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 8 May 2025 15:30:51 +0100 Subject: [PATCH 164/174] fix some optional args markup new_from_file and system had the wrong tag --- libvips/iofuncs/image.c | 2 +- libvips/iofuncs/system.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index b1c062b625..5b992c2863 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -1844,7 +1844,7 @@ vips_filename_get_options(const char *vips_filename) * @name: file to open * @...: `NULL`-terminated list of optional named arguments * - * ::: note "Optional arguments" + * ::: tip "Optional arguments" * * @access: hint [enum@Access] mode to loader * * @memory: force load via memory * diff --git a/libvips/iofuncs/system.c b/libvips/iofuncs/system.c index fa9ef261b6..8419ecd8ab 100644 --- a/libvips/iofuncs/system.c +++ b/libvips/iofuncs/system.c @@ -325,7 +325,7 @@ vips_system_init(VipsSystem *system) * @cmd_format: command to run * @...: `NULL`-terminated list of optional named arguments * - * ::: note "Optional arguments" + * ::: tip "Optional arguments" * * @in: array of input images * * @out: output image * * @in_format: write input files like this From 79fce4d176f14162a1df89333bdb51d0e58ed522 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 8 May 2025 15:39:43 +0100 Subject: [PATCH 165/174] small doc formatting improvements --- libvips/iofuncs/image.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 5b992c2863..5d681f7233 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -1846,13 +1846,13 @@ vips_filename_get_options(const char *vips_filename) * * ::: tip "Optional arguments" * * @access: hint [enum@Access] mode to loader - * * @memory: force load via memory + * * @memory: `gboolean`, force load via memory * * [ctor@Image.new_from_file] opens @name for reading. It can load files * in many image formats, including VIPS, TIFF, PNG, JPEG, FITS, Matlab, * OpenEXR, CSV, WebP, Radiance, RAW, PPM and others. * - * Load options may be appended to @filename as "[name=value,...]" or given as + * Load options may be appended to @filename as `[name=value,...]` or given as * a NULL-terminated list of name-value pairs at the end of the arguments. * Options given in the function call override options given in the filename. * Many loaders add extra options, see [ctor@Image.jpegload], for example. @@ -1895,8 +1895,7 @@ vips_filename_get_options(const char *vips_filename) * Will open "fred.tif", reading page 12. * * ```c - * VipsImage *image = vips_image_new_from_file("fred.jpg[shrink=2]", - * NULL); + * VipsImage *image = vips_image_new_from_file("fred.jpg[shrink=2]", NULL); * ``` * * Will open `fred.jpg`, downsampling by a factor of two. @@ -2135,7 +2134,7 @@ vips_image_new_from_memory_copy(const void *data, size_t size, * responsibility for the area of memory, it's up to you to make sure it's * freed when the image is closed. See for example [signal@Object::close]. * - * Load options may be given in @option_string as "[name=value,...]" or given as + * Load options may be given in @option_string as `[name=value,...]` or given as * a NULL-terminated list of name-value pairs at the end of the arguments. * Options given in the function call override options given in the filename. * @@ -2185,7 +2184,7 @@ vips_image_new_from_buffer(const void *buf, size_t len, * Loads an image from the formatted source @input, * loader recommended by [func@Foreign.find_load_source]. * - * Load options may be given in @option_string as "[name=value,...]" or given as + * Load options may be given in @option_string as `[name=value,...]` or given as * a NULL-terminated list of name-value pairs at the end of the arguments. * Options given in the function call override options given in the string. * @@ -2675,7 +2674,7 @@ vips_image_write(VipsImage *image, VipsImage *out) * Writes @in to @name using the saver recommended by * [func@Foreign.find_save]. * - * Save options may be appended to @filename as "[name=value,...]" or given as + * Save options may be appended to @filename as `[name=value,...]` or given as * a NULL-terminated list of name-value pairs at the end of the arguments. * Options given in the function call override options given in the filename. * @@ -2739,7 +2738,7 @@ vips_image_write_to_file(VipsImage *image, const char *name, ...) * * Writes @in to a memory buffer in a format specified by @suffix. * - * Save options may be appended to @suffix as "[name=value,...]" or given as + * Save options may be appended to @suffix as `[name=value,...]` or given as * a NULL-terminated list of name-value pairs at the end of the arguments. * Options given in the function call override options given in the filename. * @@ -2829,7 +2828,7 @@ vips_image_write_to_buffer(VipsImage *in, * * Writes @in to @output in format @suffix. * - * Save options may be appended to @suffix as "[name=value,...]" or given as + * Save options may be appended to @suffix as `[name=value,...]` or given as * a NULL-terminated list of name-value pairs at the end of the arguments. * Options given in the function call override options given in the filename. * From 5dc0f5cf3b013d9fa41c92b67889057b5ac46c2c Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 8 May 2025 17:44:12 +0200 Subject: [PATCH 166/174] doc: port remainder to gi-docgen linking syntax (#4504) * doc: port remainder to gi-docgen linking syntax * doc: change enum members to uppercase * doc: fix typo --- doc/file-format.md | 6 ++--- doc/libvips-arithmetic.md | 8 +++--- doc/libvips-colour.md | 44 +++++++++++++++---------------- doc/libvips-histogram.md | 2 +- doc/libvips-morphology.md | 2 +- libvips/convolution/conv.c | 2 +- libvips/convolution/convi.c | 2 +- libvips/foreign/foreign.c | 4 +-- libvips/foreign/jp2kload.c | 6 ++--- libvips/include/vips/connection.h | 8 +++--- libvips/include/vips/header.h | 6 ++--- libvips/iofuncs/buf.c | 6 ++--- libvips/iofuncs/error.c | 2 +- libvips/iofuncs/generate.c | 2 +- libvips/iofuncs/image.c | 36 ++++++++++++------------- libvips/iofuncs/memory.c | 8 +++--- libvips/iofuncs/object.c | 10 +++---- libvips/iofuncs/operation.c | 12 ++++----- libvips/iofuncs/region.c | 2 +- libvips/iofuncs/source.c | 6 ++--- libvips/iofuncs/util.c | 26 +++++++++--------- libvips/morphology/rank.c | 8 ++++-- 22 files changed, 106 insertions(+), 102 deletions(-) diff --git a/doc/file-format.md b/doc/file-format.md index 58bc23e13b..756ddf7c6e 100644 --- a/doc/file-format.md +++ b/doc/file-format.md @@ -58,7 +58,7 @@ swapping automatically. ## The image data -If `coding` is set to [enum@Vips.Coding.none], pixels are stored in native C +If `coding` is set to [enum@Vips.Coding.NONE], pixels are stored in native C format, that is, the native format of the machine that wrote the data. If you open a big-endian image on a little-endian machine, libvips will automatically byte-swap for you. libvips has 10 band formats, see [enum@BandFormat]. @@ -66,12 +66,12 @@ Image data is stored as a simple list of scanlines, from the top of the image to the bottom. Pixels are band-interleaved, so RGBRGBRGBRGB, for example. There is no padding at the end of scanlines. -If `coding` is set to [enum@Vips.Coding.labq], each pixel is four bytes, with +If `coding` is set to [enum@Vips.Coding.LABQ], each pixel is four bytes, with 10 bits for L\* and 11 bits for each of a\* and b\*. These 32 bits are packed into 4 bytes, with the most significant 8 bits of each value in the first 3 bytes, and the left-over bits packed into the final byte as 2:3:3. -If `coding` is set to [enum@Vips.Coding.rad], each pixel is RGB or XYZ float, +If `coding` is set to [enum@Vips.Coding.RAD], each pixel is RGB or XYZ float, with 8 bits of mantissa and then 8 bits of exponent, shared between the three channels. This coding style is used by the Radiance family of programs (and the HDR format) commonly used for HDR imaging. diff --git a/doc/libvips-arithmetic.md b/doc/libvips-arithmetic.md index cf492cd161..35d8c4e612 100644 --- a/doc/libvips-arithmetic.md +++ b/doc/libvips-arithmetic.md @@ -20,9 +20,9 @@ single-band images freely. Arithmetic operations try to preserve precision by increasing the number of bits in the output image when necessary. Generally, this follows the ANSI C conventions for type promotion, so multiplying two -[enum@Vips.BandFormat.uchar] images together, for example, produces a -[enum@Vips.BandFormat.ushort] image, and taking the [method@Image.cos] of a -[enum@Vips.BandFormat.ushort] image produces [enum@Vips.BandFormat.float] +[enum@Vips.BandFormat.UCHAR] images together, for example, produces a +[enum@Vips.BandFormat.USHORT] image, and taking the [method@Image.cos] of a +[enum@Vips.BandFormat.USHORT] image produces [enum@Vips.BandFormat.FLOAT] image. After processing, use [method@Image.cast] and friends to take then format @@ -30,7 +30,7 @@ back down again.[method@Image.cast_uchar], for example, will cast any image down to 8-bit unsigned. Images have an interpretation: a meaning for the pixel values. With -[enum@Vips.Interpretation.srgb], for example, the first three bands will be +[enum@Vips.Interpretation.SRGB], for example, the first three bands will be interpreted (for example, by a saver like [method@Image.jpegsave]) as R, G and B, with values in 0 - 255, and any fourth band will be interpreted as an alpha channel. diff --git a/doc/libvips-colour.md b/doc/libvips-colour.md index 9c37f03223..b37fb4bf7e 100644 --- a/doc/libvips-colour.md +++ b/doc/libvips-colour.md @@ -17,16 +17,16 @@ the HDR imaging community. The colour functions can be divided into three main groups. First, functions to transform images between the different colour spaces supported by libvips: -[enum@Vips.Interpretation.srgb], [enum@Vips.Interpretation.scrgb], -[enum@Vips.Interpretation.b_w], [enum@Vips.Interpretation.xyz], -[enum@Vips.Interpretation.yxy], [enum@Vips.Interpretation.lab], -[enum@Vips.Interpretation.lch], and [enum@Vips.Interpretation.cmc]. +[enum@Vips.Interpretation.SRGB], [enum@Vips.Interpretation.SCRGB], +[enum@Vips.Interpretation.B_W], [enum@Vips.Interpretation.XYZ], +[enum@Vips.Interpretation.YXY], [enum@Vips.Interpretation.LAB], +[enum@Vips.Interpretation.LCH], and [enum@Vips.Interpretation.CMC]. There are also a set of minor colourspaces which are one of the above in a slightly different format: -[enum@Vips.Interpretation.lab], [enum@Vips.Interpretation.labq], -[enum@Vips.Interpretation.labs], [enum@Vips.Interpretation.lch], -[enum@Vips.Interpretation.rgb16], and [enum@Vips.Interpretation.grey16]. +[enum@Vips.Interpretation.LAB], [enum@Vips.Interpretation.LABQ], +[enum@Vips.Interpretation.LABS], [enum@Vips.Interpretation.LCH], +[enum@Vips.Interpretation.RGB16], and [enum@Vips.Interpretation.GREY16]. Use [method@Image.colourspace] to move an image to a target colourspace using the best sequence of colour transform operations. @@ -41,39 +41,39 @@ This figure shows how the libvips colour spaces interconvert: The colour spaces supported by libvips are: -- [enum@Vips.Interpretation.lab]: CIELAB '76 colourspace with a D65 white. +- [enum@Vips.Interpretation.LAB]: CIELAB '76 colourspace with a D65 white. This uses three floats for each band, and bands have the obvious range.

- There are two variants, [enum@Vips.Interpretation.labq] and - [enum@Vips.Interpretation.labs], which use ints to store values. These are + There are two variants, [enum@Vips.Interpretation.LABQ] and + [enum@Vips.Interpretation.LABS], which use ints to store values. These are less precise, but can be quicker to store and process.

- [enum@Vips.Interpretation.lch] is the same, but with a\*b\* as polar + [enum@Vips.Interpretation.LCH] is the same, but with a\*b\* as polar coordinates. Hue is expressed in degrees. -- [enum@Vips.Interpretation.xyz]: CIE XYZ. This uses three floats. +- [enum@Vips.Interpretation.XYZ]: CIE XYZ. This uses three floats. See [const@D75_X0] and friends for values for the ranges under various illuminants.

- [enum@Vips.Interpretation.yxy] is the same, but with little x and y. + [enum@Vips.Interpretation.YXY] is the same, but with little x and y. -- [enum@Vips.Interpretation.scrgb]: a linear colourspace with the sRGB +- [enum@Vips.Interpretation.SCRGB]: a linear colourspace with the sRGB primaries. This is useful if you need linear light and don't care much what the primaries are.

Linearization is performed with the usual sRGB equations, see below. -- [enum@Vips.Interpretation.srgb]: the standard sRGB colourspace, see: +- [enum@Vips.Interpretation.SRGB]: the standard sRGB colourspace, see: [wikipedia sRGB](http://en.wikipedia.org/wiki/SRGB).

This uses three 8-bit values for each of RGB.

- [enum@Vips.Interpretation.rgb16] is the same, but using three 16-bit values + [enum@Vips.Interpretation.RGB16] is the same, but using three 16-bit values for RGB.

- [enum@Vips.Interpretation.hsv] is sRGB, but in polar coordinates. - [enum@Vips.Interpretation.lch] is much better, only use HSV if you have to. + [enum@Vips.Interpretation.HSV] is sRGB, but in polar coordinates. + [enum@Vips.Interpretation.LCH] is much better, only use HSV if you have to. -- [enum@Vips.Interpretation.b_w]: a monochrome image, roughly G from sRGB. - The grey value is calculated in linear [enum@Vips.Interpretation.scrgb] +- [enum@Vips.Interpretation.B_W]: a monochrome image, roughly G from sRGB. + The grey value is calculated in linear [enum@Vips.Interpretation.SCRGB] space with RGB ratios 0.2126, 0.7152, 0.0722 as defined by CIE 1931 linear luminance.

- [enum@Vips.Interpretation.grey16] is the same, but using 16 bits. + [enum@Vips.Interpretation.GREY16] is the same, but using 16 bits. -- [enum@Vips.Interpretation.cmc]: a colour space based on the CMC(1:1) +- [enum@Vips.Interpretation.CMC]: a colour space based on the CMC(1:1) colour difference measurement. This is a highly uniform colour space, and much better than CIELAB for expressing small differences.

The CMC colourspace is described in “Uniform Colour Space Based on the diff --git a/doc/libvips-histogram.md b/doc/libvips-histogram.md index c03462b807..034726c430 100644 --- a/doc/libvips-histogram.md +++ b/doc/libvips-histogram.md @@ -5,7 +5,7 @@ Title: Operator index > By section > Histogram Histograms and look-up tables are 1xn or nx1 images, where n is less than 256 or less than 65536, corresponding to 8- and 16-bit unsigned int images. They are tagged with a [enum@Interpretation] of -[enum@Vips.Interpretation.histogram] and usually displayed by user-interfaces +[enum@Vips.Interpretation.HISTOGRAM] and usually displayed by user-interfaces such as nip2 as plots rather than images. These functions can be broadly grouped as things to find or build diff --git a/doc/libvips-morphology.md b/doc/libvips-morphology.md index 40bfe16edc..6d73aa1134 100644 --- a/doc/libvips-morphology.md +++ b/doc/libvips-morphology.md @@ -32,7 +32,7 @@ VipsImage *mask = vips_image_new_matrixv(3, 3, ``` applied to an image with [method@Image.morph] -[enum@Vips.OperationMorphology.dilate] will do a 4-connected dilation. +[enum@Vips.OperationMorphology.DILATE] will do a 4-connected dilation. Dilate sets pixels in the output if any part of the mask matches, whereas erode sets pixels only if all the mask matches. diff --git a/libvips/convolution/conv.c b/libvips/convolution/conv.c index 8fd17fb902..dfd8bd9789 100644 --- a/libvips/convolution/conv.c +++ b/libvips/convolution/conv.c @@ -184,7 +184,7 @@ vips_conv_init(VipsConv *conv) * [enum@Vips.BandFormat.DOUBLE]. * * If @precision is [enum@Vips.Precision.INTEGER], then elements of @mask - * are converted to integers before convolution, using rint(), + * are converted to integers before convolution, using `rint()`, * and the output image always has the same [enum@BandFormat] as the input * image. * diff --git a/libvips/convolution/convi.c b/libvips/convolution/convi.c index 68c9b31dc3..d70cb2a9e3 100644 --- a/libvips/convolution/convi.c +++ b/libvips/convolution/convi.c @@ -1267,7 +1267,7 @@ vips_convi_init(VipsConvi *convi) * Integer convolution. This is a low-level operation, see [method@Image.conv] for * something more convenient. * - * @mask is converted to an integer mask with rint() of each element, rint of + * @mask is converted to an integer mask with `rint()` of each element, rint of * scale and rint of offset. Each output pixel is then calculated as * * ``` diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 4fb4a7e76c..29c5851187 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -702,7 +702,7 @@ vips_foreign_find_load_buffer_sub(VipsForeignLoadClass *load_class, * vips -l | grep load_buffer * * ::: seealso - * vips_image_new_from_buffer(). + * [ctor@Image.new_from_buffer]. * * Returns: (transfer none): the name of an operation on success, `NULL` on * error. @@ -764,7 +764,7 @@ vips_foreign_find_load_source_sub(void *item, void *a, void *b) * vips -l | grep load_source * * ::: seealso - * vips_image_new_from_source(). + * [ctor@Image.new_from_source]. * * Returns: (transfer none): the name of an operation on success, `NULL` on * error. diff --git a/libvips/foreign/jp2kload.c b/libvips/foreign/jp2kload.c index 54a84ad0c3..846ab52f78 100644 --- a/libvips/foreign/jp2kload.c +++ b/libvips/foreign/jp2kload.c @@ -1646,7 +1646,7 @@ vips__foreign_load_jp2k_decompress(VipsImage *out, * ::: tip "Optional arguments" * * @page: `gint`, load this page * * @oneshot: `gboolean`, load pages in one-shot mode - * * @fail_on: #VipsFailOn, types of read error to fail on + * * @fail_on: [enum@FailOn], types of read error to fail on * * ::: seealso * [ctor@Image.new_from_file]. @@ -1681,7 +1681,7 @@ vips_jp2kload(const char *filename, VipsImage **out, ...) * ::: tip "Optional arguments" * * @page: `gint`, load this page * * @oneshot: `gboolean`, load pages in one-shot mode - * * @fail_on: #VipsFailOn, types of read error to fail on + * * @fail_on: [enum@FailOn], types of read error to fail on * * Returns: 0 on success, -1 on error. */ @@ -1716,7 +1716,7 @@ vips_jp2kload_buffer(void *buf, size_t len, VipsImage **out, ...) * ::: tip "Optional arguments" * * @page: `gint`, load this page * * @oneshot: `gboolean`, load pages in one-shot mode - * * @fail_on: #VipsFailOn, types of read error to fail on + * * @fail_on: [enum@FailOn], types of read error to fail on * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/include/vips/connection.h b/libvips/include/vips/connection.h index ea3b21e9bc..ac639b9877 100644 --- a/libvips/include/vips/connection.h +++ b/libvips/include/vips/connection.h @@ -185,14 +185,14 @@ typedef struct _VipsSourceClass { */ /* Read from the source into the supplied buffer, args exactly as - * read(2). Set errno on error. + * [`read()`](man:read(2)). Set errno on error. * * We must return gint64, since ssize_t is often defined as unsigned * on Windows. */ gint64 (*read)(VipsSource *source, void *buffer, size_t length); - /* Seek to a certain position, args exactly as lseek(2). Set errno on + /* Seek to a certain position, args exactly as [`lseek()`](man:lseek(2)). Set errno on * error. * * Unseekable sources should always return -1. VipsSource will then @@ -451,14 +451,14 @@ typedef struct _VipsTargetClass { */ /* Read from the target into the supplied buffer, args exactly as - * read(2). Set errno on error. + * [`read()`](man:read(2)). Set errno on error. * * We must return gint64, since ssize_t is often defined as unsigned * on Windows. */ gint64 (*read)(VipsTarget *target, void *buffer, size_t length); - /* Seek output. Args exactly as lseek(2). + /* Seek output. Args exactly as [`lseek()`](man:lseek(2)). * * We have to use int64 rather than off_t, since we must work on * Windows, where off_t can be 32-bits. diff --git a/libvips/include/vips/header.h b/libvips/include/vips/header.h index 16c3df2fc9..24ee3e0b4f 100644 --- a/libvips/include/vips/header.h +++ b/libvips/include/vips/header.h @@ -73,7 +73,7 @@ extern "C" { * The name we use to attach an ICC profile. The file read and write * operations for TIFF, JPEG, PNG and others use this item of metadata to * attach and save ICC profiles. The profile is updated by the - * vips_icc_transform() operations. + * [method@Image.icc_transform] operations. */ #define VIPS_META_ICC_NAME "icc-profile-data" @@ -117,8 +117,8 @@ extern "C" { /** * VIPS_META_SEQUENTIAL: * - * Images loaded via vips_sequential() have this int field defined. Some - * operations (eg. vips_shrinkv()) add extra caches if they see it on their + * Images loaded via [method@Image.sequential] have this int field defined. Some + * operations (eg. [method@Image.shrinkv]) add extra caches if they see it on their * input. */ #define VIPS_META_SEQUENTIAL "vips-sequential" diff --git a/libvips/iofuncs/buf.c b/libvips/iofuncs/buf.c index 2c064cbd22..7b9ebcfc3c 100644 --- a/libvips/iofuncs/buf.c +++ b/libvips/iofuncs/buf.c @@ -494,10 +494,10 @@ vips_buf_appendd(VipsBuf *buf, int d) /** * vips_buf_appendgv: * @buf: the buffer - * @value: #GValue to format and append + * @value: [struct@GObject.Value] to format and append * - * Format and append a #GValue as a printable thing. We display text line "3144 - * bytes of binary data" for BLOBs like icc-profile-data. + * Format and append a [struct@GObject.Value] as a printable thing. + * We display text like "3144 bytes of binary data" for BLOBs like icc-profile-data. * * Use [method@Image.get_as_string] to make a text representation of a field. * That will base64-encode blobs, for example. diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index d793919f33..e6bb0dd0fb 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -248,7 +248,7 @@ vips_verror_system(int err, const char *domain, const char *fmt, va_list ap) * @fmt: `printf()`-style format string for the error * @...: arguments to the format string * - * Format the string in the style of printf() and append to the error buffer. + * Format the string in the style of [`printf()`](man:printf(3)) and append to the error buffer. * Then create and append a localised message based on the system error code, * usually the value of errno. * diff --git a/libvips/iofuncs/generate.c b/libvips/iofuncs/generate.c index b6d5594750..f860d37992 100644 --- a/libvips/iofuncs/generate.c +++ b/libvips/iofuncs/generate.c @@ -662,7 +662,7 @@ write_vips(VipsRegion *region, VipsRect *area, void *a) * * Generates an image. The action depends on the image type. * - * For images created with [ctor@Image.new], vips_image_generate() just + * For images created with [ctor@Image.new], [method@Image.generate] just * attaches the start/generate/stop callbacks and returns. * * For images created with [ctor@Image.new_memory], memory is allocated for diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 5d681f7233..b4c75634ae 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -153,9 +153,9 @@ * The type of access an operation has to supply. See [method@Image.tilecache] * and [class@Foreign]. * - * @VIPS_ACCESS_RANDOM means requests can come in any order. + * [enum@Vips.Access.RANDOM] means requests can come in any order. * - * @VIPS_ACCESS_SEQUENTIAL means requests will be top-to-bottom, but with some + * [enum@Vips.Access.SEQUENTIAL] means requests will be top-to-bottom, but with some * amount of buffering behind the read point for small non-local accesses. */ @@ -176,20 +176,20 @@ * will use the most general style requested by the operations * in the pipeline. * - * @VIPS_DEMAND_STYLE_SMALLTILE -- This is the most general demand format. + * [enum@Vips.DemandStyle.SMALLTILE] -- This is the most general demand format. * Output is demanded in small (around 100x100 pel) sections. This style works * reasonably efficiently, even for bizarre operations like 45 degree rotate. * - * @VIPS_DEMAND_STYLE_FATSTRIP -- This operation would like to output strips + * [enum@Vips.DemandStyle.FATSTRIP] -- This operation would like to output strips * the width of the image and as high as possible. This option is suitable * for area operations which do not violently transform coordinates, such * as [method@Image.conv]. * - * @VIPS_DEMAND_STYLE_THINSTRIP -- This operation would like to output strips + * [enum@Vips.DemandStyle.THINSTRIP] -- This operation would like to output strips * the width of the image and a few pels high. This option is suitable for * point-to-point operations, such as those in the arithmetic package. * - * @VIPS_DEMAND_STYLE_ANY -- This image is not being demand-read from a disc + * [enum@Vips.DemandStyle.ANY] -- This image is not being demand-read from a disc * file (even indirectly) so any demand style is OK. It's used for things like * [ctor@Image.black] where the pixels are calculated. * @@ -206,7 +206,7 @@ * @VIPS_INTERPRETATION_XYZ: the first three bands are CIE XYZ * @VIPS_INTERPRETATION_LAB: pixels are in CIE Lab space * @VIPS_INTERPRETATION_CMYK: the first four bands are in CMYK space - * @VIPS_INTERPRETATION_LABQ: implies @VIPS_CODING_LABQ + * @VIPS_INTERPRETATION_LABQ: implies [enum@Vips.Coding.LABQ] * @VIPS_INTERPRETATION_RGB: generic RGB space * @VIPS_INTERPRETATION_CMC: a uniform colourspace based on CMC(1:1) * @VIPS_INTERPRETATION_LCH: pixels are in CIE LCh space @@ -220,7 +220,7 @@ * @VIPS_INTERPRETATION_MATRIX: a matrix * * How the values in an image should be interpreted. For example, a - * three-band float image of type @VIPS_INTERPRETATION_LAB should have its + * three-band float image of type [enum@Vips.Interpretation.LAB] should have its * pixels interpreted as coordinates in CIE Lab space. * * RGB and sRGB are treated in the same way. Use the colourspace functions if @@ -327,7 +327,7 @@ * If VIPS_DEBUG is defined, you get a version that checks bounds for you. * * ::: seealso - * [method@Image.wio_input], [method@Image.inplace], VIPS_REGION_ADDR(). + * [method@Image.wio_input], [method@Image.inplace], [func@REGION_ADDR]. * * Returns: The address of pixel (@X,@Y) in @I. */ @@ -1776,7 +1776,7 @@ vips_image_new_memory(void) * vips_image_memory: (constructor) * * A renamed [ctor@Image.new_memory] ... Some gobject binding systems do not - * like more than one _new() method. + * like more than one `_new()` method. * * ::: seealso * [ctor@Image.new_memory]. @@ -2557,7 +2557,7 @@ vips_get_disc_threshold(void) * * The file is created in the temporary directory. This is set with the * environment variable TMPDIR. If this is not set, then on Unix systems, vips - * will default to /tmp. On Windows, vips uses GetTempPath() to find the + * will default to /tmp. On Windows, vips uses `GetTempPath()` to find the * temporary directory. * * ::: seealso @@ -2872,7 +2872,7 @@ vips_image_write_to_target(VipsImage *in, * * Writes @in to memory as a simple, unformatted C-style array. * - * The caller is responsible for freeing this memory with g_free(). + * The caller is responsible for freeing this memory with [func@GLib.free]. * * ::: seealso * [method@Image.write_to_buffer]. @@ -3200,7 +3200,7 @@ vips_image_write_prepare(VipsImage *image) * * Write a line of pixels to an image. This function must be called repeatedly * with @ypos increasing from 0 to [property@Image:height]. - * @linebuffer must be VIPS_IMAGE_SIZEOF_LINE() bytes long. + * @linebuffer must be [func@IMAGE_SIZEOF_LINE] bytes long. * * ::: seealso * [method@Image.generate]. @@ -3391,10 +3391,10 @@ vips_image_copy_memory(VipsImage *image) * vips_image_wio_input: * @image: image to transform * - * Check that an image is readable via the VIPS_IMAGE_ADDR() macro, that is, + * Check that an image is readable via the [func@IMAGE_ADDR] macro, that is, * that the entire image is in memory and all pixels can be read with - * VIPS_IMAGE_ADDR(). If it - * isn't, try to transform it so that VIPS_IMAGE_ADDR() can work. + * [func@IMAGE_ADDR]. If it + * isn't, try to transform it so that [func@IMAGE_ADDR] can work. * * Since this function modifies @image, it is not thread-safe. Only call it on * images which you are sure have not been shared with another thread. If the @@ -3403,7 +3403,7 @@ vips_image_copy_memory(VipsImage *image) * * ::: seealso * [method@Image.copy_memory], [method@Image.pio_input], - * [method@Image.inplace], VIPS_IMAGE_ADDR(). + * [method@Image.inplace], [func@IMAGE_ADDR]. * * Returns: 0 on success, or -1 on error. */ @@ -3569,7 +3569,7 @@ vips__image_wio_output(VipsImage *image) * * Gets @image ready for an in-place operation, such as * [method@Image.draw_circle]. After calling this function you can both read - * and write the image with VIPS_IMAGE_ADDR(). + * and write the image with [func@IMAGE_ADDR]. * * This method is called for you by the base class of the draw operations, * there's no need to call it yourself. diff --git a/libvips/iofuncs/memory.c b/libvips/iofuncs/memory.c index 7ad727d143..6e1a17cfaf 100644 --- a/libvips/iofuncs/memory.c +++ b/libvips/iofuncs/memory.c @@ -424,10 +424,10 @@ vips_tracked_aligned_alloc(size_t size, size_t align) /** * vips_tracked_open: * @pathname: name of file to open - * @flags: flags for open() + * @flags: flags for `open()` * @mode: open mode * - * Exactly as open(2), but the number of files currently open via + * Exactly as [`open()`](man:open(2)), but the number of files currently open via * [func@tracked_open] is available via [func@tracked_get_files]. This is used * by the vips operation cache to drop cache when the number of files * available is low. @@ -464,9 +464,9 @@ vips_tracked_open(const char *pathname, int flags, int mode) /** * vips_tracked_close: - * @fd: file to close() + * @fd: file to `close()` * - * Exactly as close(2), but update the number of files currently open via + * Exactly as [`close()`](man:close(2)), but update the number of files currently open via * [func@tracked_get_files]. This is used * by the vips operation cache to drop cache when the number of files * available is low. diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index f9c2b3c3a8..62b3bbad4a 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -179,20 +179,20 @@ * Input gobjects are automatically reffed, output gobjects automatically ref * us. We also automatically watch for "destroy" and unlink. * - * @VIPS_ARGUMENT_SET_ALWAYS is handy for arguments which are set from C. For + * [flags@Vips.ArgumentFlags.SET_ALWAYS] is handy for arguments which are set from C. For * example, VipsImage::width is a property that gives access to the Xsize * member of struct _VipsImage. We default its 'assigned' to TRUE * since the field is always set directly by C. * - * @VIPS_ARGUMENT_DEPRECATED arguments are not shown in help text, are not + * [flags@Vips.ArgumentFlags.DEPRECATED] arguments are not shown in help text, are not * looked for if required, are not checked for "have-been-set". You can * deprecate a required argument, but you must obviously add a new required * argument if you do. * - * Input args with @VIPS_ARGUMENT_MODIFY will be modified by the operation. + * Input args with [flags@Vips.ArgumentFlags.MODIFY] will be modified by the operation. * This is used for things like the in-place drawing operations. * - * @VIPS_ARGUMENT_NON_HASHABLE stops the argument being used in hash and + * [flags@Vips.ArgumentFlags.NON_HASHABLE] stops the argument being used in hash and * equality tests. It's useful for arguments like `revalidate` which * control the behaviour of the operator cache. */ @@ -3242,7 +3242,7 @@ vips_object_unref_outputs(VipsObject *object) * * Fetch the object description. Useful for language bindings. * - * @object.description is only available after _build(), which can be too + * [property@VipsObject:description] is only available after `_build()`, which can be too * late. This function fetches from the instance, if possible, but falls back * to the class description if we are too early. * diff --git a/libvips/iofuncs/operation.c b/libvips/iofuncs/operation.c index 66aaf248d1..6c914e2293 100644 --- a/libvips/iofuncs/operation.c +++ b/libvips/iofuncs/operation.c @@ -172,7 +172,7 @@ * * Flags we associate with an operation. * - * @VIPS_OPERATION_SEQUENTIAL means that the operation works like + * [flags@Vips.OperationFlags.SEQUENTIAL] means that the operation works like * [method@Image.conv]: it can process images top-to-bottom with only small * non-local references. * @@ -186,21 +186,21 @@ * not at the top of the image. In this case, the first part of the image will * be read and discarded * - * @VIPS_OPERATION_NOCACHE means that the operation must not be cached by + * [flags@Vips.OperationFlags.NOCACHE] means that the operation must not be cached by * vips. * - * @VIPS_OPERATION_DEPRECATED means this is an old operation kept in vips for + * [flags@Vips.OperationFlags.DEPRECATED] means this is an old operation kept in vips for * compatibility only and should be hidden from users. * - * @VIPS_OPERATION_UNTRUSTED means the operation depends on external libraries + * [flags@Vips.OperationFlags.UNTRUSTED] means the operation depends on external libraries * which have not been hardened against attack. It should probably not be used * on untrusted input. Use [func@block_untrusted_set] to block all * untrusted operations. * - * @VIPS_OPERATION_BLOCKED means the operation is prevented from executing. Use + * [flags@Vips.OperationFlags.BLOCKED] means the operation is prevented from executing. Use * [func@Operation.block_set] to enable and disable groups of operations. * - * @VIPS_OPERATION_REVALIDATE force the operation to run, updating the cache + * [flags@Vips.OperationFlags.REVALIDATE] force the operation to run, updating the cache * with the new value. This is used by eg. VipsForeignLoad to implement the * "revalidate" argument. */ diff --git a/libvips/iofuncs/region.c b/libvips/iofuncs/region.c index dc41c099b8..ff2ea280e7 100644 --- a/libvips/iofuncs/region.c +++ b/libvips/iofuncs/region.c @@ -896,7 +896,7 @@ vips_region_fill(VipsRegion *reg, * @reg->valid. * * For int images, @value is - * passed to memset(), so it usually needs to be 0 or 255. For float images, + * passed to [`memset()`](man:memset(3)), so it usually needs to be 0 or 255. For float images, * value is cast to a float and copied in to each band element. * * @r is clipped against diff --git a/libvips/iofuncs/source.c b/libvips/iofuncs/source.c index 64c6111fb4..eba0e4b59c 100644 --- a/libvips/iofuncs/source.c +++ b/libvips/iofuncs/source.c @@ -424,7 +424,7 @@ vips_source_init(VipsSource *source) * @descriptor: read from this file descriptor * * Create an source attached to a file descriptor. @descriptor is - * closed with close() when source is finalized. + * closed with [`close()`](man:close(2)) when source is finalized. * * Returns: a new source. */ @@ -780,7 +780,7 @@ vips_source_print(VipsSource *source) * Return the number of bytes actually read. If all bytes have been read from * the file, return 0. * - * Arguments exactly as read(2). + * Arguments exactly as [`read()`](man:read(2)). * * Returns: the number of bytes read, 0 on end of file, -1 on error. */ @@ -1170,7 +1170,7 @@ vips_source_map_blob(VipsSource *source) * @whence: seek relative to this point * * Move the file read position. You can't call this after pixel decode starts. - * The arguments are exactly as lseek(2). + * The arguments are exactly as [`lseek()`](man:lseek(2)). * * Returns: the new file position, or -1 on error. */ diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index 9bb8788097..345e74ec65 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -70,8 +70,8 @@ /** * vips_slist_equal: - * @l1: (element-type guint8): a #GSList - * @l2: (element-type guint8): another #GSList + * @l1: (element-type guint8): a [struct@GLib.SList] + * @l2: (element-type guint8): another [struct@GLib.SList] * * Test two lists for equality. * @@ -96,7 +96,7 @@ vips_slist_equal(GSList *l1, GSList *l2) /** * vips_slist_map2: - * @list: (element-type guint8): a #GSList + * @list: (element-type guint8): a [struct@GLib.SList] * @fn: (scope call): function to apply to each list element * @a: user data * @b: user data @@ -124,7 +124,7 @@ vips_slist_map2(GSList *list, VipsSListMap2Fn fn, void *a, void *b) /** * vips_slist_map2_rev: - * @list: (element-type guint8): a #GSList + * @list: (element-type guint8): a [struct@GLib.SList] * @fn: (scope call): function to apply to each list element * @a: user data * @b: user data @@ -153,7 +153,7 @@ vips_slist_map2_rev(GSList *list, VipsSListMap2Fn fn, void *a, void *b) /** * vips_slist_map4: - * @list: (element-type guint8): a #GSList + * @list: (element-type guint8): a [struct@GLib.SList] * @fn: (scope call): function to apply to each list element * @a: user data * @b: user data @@ -185,7 +185,7 @@ vips_slist_map4(GSList *list, /** * vips_slist_fold2: - * @list: (element-type guint8): a #GSList + * @list: (element-type guint8): a [struct@GLib.SList] * @start: initial value for the accumulator * @fn: (scope call): function to apply to each list element * @a: user data @@ -215,7 +215,7 @@ vips_slist_fold2(GSList *list, void *start, /** * vips_slist_filter: - * @list: (element-type guint8): a #GSList + * @list: (element-type guint8): a [struct@GLib.SList] * @fn: (scope call): function to call for each element. * @a: user data * @b: user data @@ -264,7 +264,7 @@ vips_slist_free_all_cb(void *thing, void *dummy) /** * vips_slist_free_all: - * @list: (element-type guint8): a #GSList + * @list: (element-type guint8): a [struct@GLib.SList] * * Free a [struct@GLib.SList] of things which need [func@GLib.free]ing. */ @@ -930,7 +930,7 @@ vips__gvalue_ref_string_new(const char *text) /** * vips__gslist_gvalue_free: - * @list: (element-type GValue): a #GSList of GValue + * @list: (element-type GValue): a [struct@GLib.SList] of GValue * * Free a GSList of GValue. */ @@ -943,7 +943,7 @@ vips__gslist_gvalue_free(GSList *list) /** * vips__gslist_gvalue_copy: - * @list: (element-type GValue): a #GSList of GValue + * @list: (element-type GValue): a [struct@GLib.SList] of GValue * * Copy a GSList of GValue. * @@ -968,8 +968,8 @@ vips__gslist_gvalue_copy(const GSList *list) /** * vips__gslist_gvalue_merge: - * @a: (element-type GValue): a #GSList of GValue - * @b: (element-type GValue): a #GSList of GValue + * @a: (element-type GValue): a [struct@GLib.SList] of GValue + * @b: (element-type GValue): a [struct@GLib.SList] of GValue * * Merge two GSList of GValue ... append to a all elements in b which are not * in a. Works for any vips refcounted type (string, blob, etc.). @@ -1015,7 +1015,7 @@ vips__gslist_gvalue_merge(GSList *a, const GSList *b) /** * vips__gslist_gvalue_get: - * @list: (element-type GValue): a #GSList of GValue + * @list: (element-type GValue): a [struct@GLib.SList] of GValue * * Make a char * from GSList of GValue. Each GValue should be a ref_string. * diff --git a/libvips/morphology/rank.c b/libvips/morphology/rank.c index cebb665e79..430b21580f 100644 --- a/libvips/morphology/rank.c +++ b/libvips/morphology/rank.c @@ -617,7 +617,9 @@ vips_rank_init(VipsRank *rank) * * For a median filter with mask size m (3 for 3x3, 5 for 5x5, etc.) use * - * vips_rank(in, out, m, m, m * m / 2); + * ```c + * vips_rank(in, out, m, m, m * m / 2); + * ``` * * The special cases n == 0 and n == m * m - 1 are useful dilate and * expand operators. @@ -650,7 +652,9 @@ vips_rank(VipsImage *in, VipsImage **out, * * A convenience function equivalent to: * - * vips_rank(in, out, size, size, (size * size) / 2); + * ```c + * vips_rank(in, out, size, size, (size * size) / 2); + * ``` * * ::: seealso * [method@Image.rank]. From 214a23fa8b5d1a689c53d9b974fc4f90b1eb84b5 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 8 May 2025 18:59:24 +0100 Subject: [PATCH 167/174] Add jxl chunked save (#4174) * start adding chunked load for jxl * update todo * sort-of works wrote some NOTES on what we need to do next * sync * sync * sync before direction change instead, try to drive libvips from data_at it should be A LOT simpler * switch back to crop * works! same speed, about half the memory use for a 10k x 10k pixel image still missing the signals you'd expect for a sink, eg. "preeval", "eval" etc. * add signals for jxlsave Add preeval, eval, posteval, minimise signals. We have to move vips_image_preeval(), vips_image_eval(), vips_image_posteval() to the public API. * fix jxlsave DEBUG mode * use crop() for paralle demand experiment with various caching strategies ... but it looks like none will work, since we will always throw away the cache on the original jpegload on minimise we're going to have to use the super-complicated sink_disc plan * works, sort of * don't emit "minimise" for sub-evaluations * small cleanups * reformat jxlload ready for chunked load to go in * update jxlload ICC profile load API * experiment with JxlDecoderSetPreferredColorProfile * fix gmutes use * Update libvips/foreign/jxlsave.c Co-authored-by: Kleis Auke Wolthuizen * Update libvips/foreign/jxlsave.c Co-authored-by: Kleis Auke Wolthuizen * update for review comments * add a loop local * fix g_mutex use in foreign/ * revise GMutex use again * more testing and polishing * Update libvips/foreign/jp2kload.c Co-authored-by: Kleis Auke Wolthuizen * review comments * revert jxlload to master * revert jxlload changes * stray comment * remove some stray args libjxl 0.11 no longer has these * catch seek errors correctly oooops --------- Co-authored-by: Kleis Auke Wolthuizen --- ChangeLog | 4 + libvips/conversion/sequential.c | 6 +- libvips/conversion/tilecache.c | 14 +- libvips/foreign/jxlload.c | 6 - libvips/foreign/jxlsave.c | 799 +++++++++++++++----------- libvips/foreign/magick6load.c | 31 +- libvips/foreign/magick7load.c | 16 +- libvips/foreign/openslideconnection.c | 1 + libvips/include/vips/image.h | 7 + libvips/include/vips/internal.h | 3 - libvips/iofuncs/image.c | 8 +- meson.build | 7 +- 12 files changed, 512 insertions(+), 390 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9b14727956..ac5201fb24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,10 @@ master consistency - restore vips_remosaic(), it was not being linked - deprecate VipsSaveable, add VipsForeignSaveable +- move vips_image_preeval(), vips_image_eval(), vips_image_posteval() into the + public API +- jxlsave writes in chunks, for lower memory use on large images (but we now + need libjxl 0.11 at minimum) 8.16.1 diff --git a/libvips/conversion/sequential.c b/libvips/conversion/sequential.c index 341334d2bd..a1d6afa63c 100644 --- a/libvips/conversion/sequential.c +++ b/libvips/conversion/sequential.c @@ -102,13 +102,13 @@ typedef VipsConversionClass VipsSequentialClass; G_DEFINE_TYPE(VipsSequential, vips_sequential, VIPS_TYPE_CONVERSION); static void -vips_sequential_dispose(GObject *gobject) +vips_sequential_finalize(GObject *gobject) { VipsSequential *sequential = (VipsSequential *) gobject; g_mutex_clear(&sequential->lock); - G_OBJECT_CLASS(vips_sequential_parent_class)->dispose(gobject); + G_OBJECT_CLASS(vips_sequential_parent_class)->finalize(gobject); } static int @@ -231,7 +231,7 @@ vips_sequential_class_init(VipsSequentialClass *class) VIPS_DEBUG_MSG("vips_sequential_class_init\n"); - gobject_class->dispose = vips_sequential_dispose; + gobject_class->finalize = vips_sequential_finalize; gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; diff --git a/libvips/conversion/tilecache.c b/libvips/conversion/tilecache.c index f18895c92f..5c6ed65b0d 100644 --- a/libvips/conversion/tilecache.c +++ b/libvips/conversion/tilecache.c @@ -153,14 +153,23 @@ vips_block_cache_drop_all(VipsBlockCache *cache) } static void -vips_block_cache_dispose(GObject *gobject) +vips_block_cache_finalize(GObject *gobject) { VipsBlockCache *cache = (VipsBlockCache *) gobject; - vips_block_cache_drop_all(cache); g_mutex_clear(&cache->lock); g_cond_clear(&cache->new_tile); + G_OBJECT_CLASS(vips_block_cache_parent_class)->finalize(gobject); +} + +static void +vips_block_cache_dispose(GObject *gobject) +{ + VipsBlockCache *cache = (VipsBlockCache *) gobject; + + vips_block_cache_drop_all(cache); + if (cache->tiles) g_assert(g_hash_table_size(cache->tiles) == 0); VIPS_FREEF(g_hash_table_destroy, cache->tiles); @@ -384,6 +393,7 @@ vips_block_cache_class_init(VipsBlockCacheClass *class) VIPS_DEBUG_MSG("vips_block_cache_class_init\n"); + gobject_class->finalize = vips_block_cache_finalize; gobject_class->dispose = vips_block_cache_dispose; gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; diff --git a/libvips/foreign/jxlload.c b/libvips/foreign/jxlload.c index 673fd3fb1d..1993057496 100644 --- a/libvips/foreign/jxlload.c +++ b/libvips/foreign/jxlload.c @@ -949,9 +949,6 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) case JXL_DEC_COLOR_ENCODING: if (JxlDecoderGetICCProfileSize(jxl->decoder, -#ifndef HAVE_LIBJXL_0_9 - &jxl->format, -#endif JXL_COLOR_PROFILE_TARGET_DATA, &jxl->icc_size)) { vips_foreign_load_jxl_error(jxl, "JxlDecoderGetICCProfileSize"); return -1; @@ -965,9 +962,6 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) return -1; if (JxlDecoderGetColorAsICCProfile(jxl->decoder, -#ifndef HAVE_LIBJXL_0_9 - &jxl->format, -#endif JXL_COLOR_PROFILE_TARGET_DATA, jxl->icc_data, jxl->icc_size)) { vips_foreign_load_jxl_error(jxl, diff --git a/libvips/foreign/jxlsave.c b/libvips/foreign/jxlsave.c index e6e7ad94fa..ac68fef793 100644 --- a/libvips/foreign/jxlsave.c +++ b/libvips/foreign/jxlsave.c @@ -4,6 +4,8 @@ * - from heifload.c * 21/5/22 * - add ICC profile support + * 8/5/25 + * - write with JxlEncoderAddChunkedFrame() for lower memory use */ /* @@ -57,17 +59,12 @@ #include "pforeign.h" /* TODO: - * - * - libjxl encode only works in one shot mode, so there's no way to write in - * chunks - * - * - add metadata support EXIF, XMP, etc. api for this is on the way - * - * - add animation support * * - libjxl is currently missing error messages (I think) * * - add support encoding images with > 4 bands. + * + * see FIXME note in _build() */ #define OUTPUT_BUFFER_SIZE (4096) @@ -87,6 +84,8 @@ typedef struct _VipsForeignSaveJxl { gboolean lossless; int Q; + gboolean error; + /* JXL multipage and animated images are the same, but multipage has * all the frame delays set to -1 (duration 0xffffffff). */ @@ -98,10 +97,11 @@ typedef struct _VipsForeignSaveJxl { int *delay; int delay_length; - /* The image we save. This is a copy of save->ready since we need to - * be able to update the metadata. + /* Image geometry. */ - VipsImage *image; + int page_height; + int page_count; + int page_number; /* Base image properties. */ @@ -114,23 +114,27 @@ typedef struct _VipsForeignSaveJxl { void *runner; JxlEncoder *encoder; - /* The current y position in the frame, page height, - * total number of pages, and the current page index. + /* Write buffer. */ - int write_y; - int page_height; - int page_count; - int page_number; + uint8_t output_buffer[OUTPUT_BUFFER_SIZE]; - /* VipsRegion is not always contiguous, but we need contiguous RGB(A) - * for libjxl. We need to copy each frame to a local buffer. + /* Chunk reader. */ - VipsPel *frame_bytes; - size_t frame_size; + struct JxlChunkedFrameInputSource input_source; - /* Write buffer. + /* Map thread ids to regions with this hash table, gate access to it with + * the mutex. */ - uint8_t output_buffer[OUTPUT_BUFFER_SIZE]; + GHashTable *tile_hash; + GMutex tile_lock; + + /* Current page we are saving. + */ + VipsImage *page; + + /* Track number of pixels saved here for eval reporting. + */ + guint64 processed; } VipsForeignSaveJxl; @@ -139,30 +143,179 @@ typedef VipsForeignSaveClass VipsForeignSaveJxlClass; G_DEFINE_ABSTRACT_TYPE(VipsForeignSaveJxl, vips_foreign_save_jxl, VIPS_TYPE_FOREIGN_SAVE); -/* String-based metadata fields we add. - */ -typedef struct _VipsForeignSaveJxlMetadata { - const char *name; /* as understood by libvips */ - JxlBoxType box_type; /* as understood by libjxl */ -} VipsForeignSaveJxlMetadata; +static void * +vips_foreign_save_jxl_get_buffer(void *opaque, size_t *size) +{ + VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) opaque; -static VipsForeignSaveJxlMetadata libjxl_metadata[] = { - { VIPS_META_EXIF_NAME, "Exif" }, - { VIPS_META_XMP_NAME, "xml " } -}; + *size = OUTPUT_BUFFER_SIZE; + return jxl->output_buffer; +} static void -vips_foreign_save_jxl_dispose(GObject *gobject) +vips_foreign_save_jxl_output_release_buffer(void *opaque, size_t written_bytes) { - VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) gobject; + VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) opaque; - VIPS_FREEF(JxlThreadParallelRunnerDestroy, jxl->runner); - VIPS_FREEF(JxlEncoderDestroy, jxl->encoder); - VIPS_FREE(jxl->frame_bytes); + if (vips_target_write(jxl->target, jxl->output_buffer, written_bytes)) + jxl->error = TRUE; +} - VIPS_UNREF(jxl->target); +static void +vips_foreign_save_jxl_seek(void *opaque, uint64_t position) +{ + VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) opaque; - G_OBJECT_CLASS(vips_foreign_save_jxl_parent_class)->dispose(gobject); + if (vips_target_seek(jxl->target, position, SEEK_SET) < 0) + jxl->error = TRUE; +} + +static void +vips_foreign_save_jxl_set_finalized_position(void *opaque, uint64_t position) +{ + // don't need this +} + +static void +vips_foreign_save_jxl_set_output_processor(VipsForeignSaveJxl *jxl) +{ + JxlEncoderSetOutputProcessor(jxl->encoder, + (struct JxlEncoderOutputProcessor) { + .opaque = jxl, + .get_buffer = vips_foreign_save_jxl_get_buffer, + .release_buffer = vips_foreign_save_jxl_output_release_buffer, + .seek = vips_foreign_save_jxl_seek, + .set_finalized_position = vips_foreign_save_jxl_set_finalized_position, + }); +} + +static void +vips_foreign_save_jxl_pixel_format(void *opaque, JxlPixelFormat *format) +{ +#ifdef DEBUG + printf("vips_foreign_save_jxl_pixel_format:\n"); +#endif /*DEBUG*/ + + VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) opaque; + + *format = jxl->format; +} + +static void +vips_foreign_save_jxl_extra_pixel_format(void *opaque, + size_t ec_index, JxlPixelFormat *format) +{ +#ifdef DEBUG + printf("vips_foreign_save_jxl_extra_pixel_format:\n"); +#endif /*DEBUG*/ + + return vips_foreign_save_jxl_pixel_format(opaque, format); +} + +static const void * +vips_foreign_save_jxl_data_at(void *opaque, + size_t xpos, size_t ypos, size_t xsize, size_t ysize, + size_t *row_offset) +{ + VipsForeignSave *save = (VipsForeignSave *) opaque; + VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) opaque; + +#ifdef DEBUG + printf("vips_foreign_save_jxl_data_at: " + "left = %zd, top = %zd, width = %zd, height = %zd\n", + xpos, ypos, xsize, ysize); +#endif /*DEBUG*/ + + /* Handy for testing. + if (ypos > 1000) { + jxl->error = TRUE; + vips_error("jxlsave", "%s", _("experimental early exit")); + return NULL; + } + */ + + VipsImage *tile; + if (vips_crop(jxl->page, &tile, xpos, ypos, xsize, ysize, NULL)) { + jxl->error = TRUE; + /* Returning NULL from data_at won't crash, but will cause a lot of + * messy libjxl diagnostic output. At least it stops save. + */ + return NULL; + } + + // disable progress reporting from this copy_memory() + vips_image_set_int(tile, "hide-progress", 1); + + VipsImage *memory; + if (!(memory = vips_image_copy_memory(tile))) { + VIPS_UNREF(tile); + jxl->error = TRUE; + return NULL; + } + VIPS_UNREF(tile); + + VipsPel *pels = VIPS_IMAGE_ADDR(memory, 0, 0); + *row_offset = VIPS_IMAGE_SIZEOF_LINE(memory); + + g_mutex_lock(&jxl->tile_lock); + + g_assert(!g_hash_table_lookup(jxl->tile_hash, pels)); + g_hash_table_insert(jxl->tile_hash, pels, memory); + +#ifdef DEBUG + printf("\tgenerated pels = %p\n", pels); +#endif /*DEBUG*/ + + g_mutex_unlock(&jxl->tile_lock); + + /* Trigger any eval callbacks on our source image and + * check for cancel. + */ + jxl->processed += xsize * ysize; + vips_image_eval(save->ready, jxl->processed); + if (vips_image_iskilled(save->ready)) + return NULL; + + return pels; +} + +static const void * +vips_foreign_save_jxl_extra_data_at(void* opaque, size_t ec_index, + size_t xpos, size_t ypos, size_t xsize, size_t ysize, size_t* row_offset) +{ +#ifdef DEBUG + printf("vips_foreign_save_jxl_extra_data_at:\n"); +#endif /*DEBUG*/ + + return vips_foreign_save_jxl_data_at(opaque, + xpos, ypos, xsize, ysize, row_offset); +} + +static void +vips_foreign_save_jxl_input_release_buffer(void *opaque, const void *pels) +{ + VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) opaque; + +#ifdef DEBUG + printf("vips_foreign_save_jxl_input_release_buffer: pels = %p\n", pels); +#endif /*DEBUG*/ + + g_assert(g_hash_table_lookup(jxl->tile_hash, pels)); + g_hash_table_remove(jxl->tile_hash, pels); +} + +static void +vips_foreign_save_jxl_set_input_source(VipsForeignSaveJxl *jxl) +{ + jxl->input_source = (struct JxlChunkedFrameInputSource) { + .opaque = jxl, + .get_color_channels_pixel_format = vips_foreign_save_jxl_pixel_format, + .get_color_channel_data_at = vips_foreign_save_jxl_data_at, + .get_extra_channel_pixel_format = + vips_foreign_save_jxl_extra_pixel_format, + .get_extra_channel_data_at = vips_foreign_save_jxl_extra_data_at, + .release_buffer = vips_foreign_save_jxl_input_release_buffer + }; } static void @@ -170,9 +323,10 @@ vips_foreign_save_jxl_error(VipsForeignSaveJxl *jxl, const char *details) { VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(jxl); - /* TODO ... jxl has no way to get error messages at the moment. + /* TODO ... libjxl seems to have no way to get error messages at the + * moment. */ - vips_error(class->nickname, "error %s", details); + vips_error(class->nickname, "%s error", details); } #ifdef DEBUG @@ -256,10 +410,6 @@ vips_foreign_save_jxl_print_status(JxlEncoderStatus status) printf("JXL_ENC_NEED_MORE_OUTPUT\n"); break; - case JXL_ENC_NOT_SUPPORTED: - printf("JXL_ENC_NOT_SUPPORTED\n"); - break; - default: printf("JXL_ENC_\n"); break; @@ -267,155 +417,182 @@ vips_foreign_save_jxl_print_status(JxlEncoderStatus status) } #endif /*DEBUG*/ -static int -vips_foreign_save_jxl_process_output(VipsForeignSaveJxl *jxl) +/* String-based metadata fields we add. + */ +typedef struct _VipsForeignSaveJxlMetadata { + const char *name; /* as understood by libvips */ + JxlBoxType box_type; /* as understood by libjxl */ +} VipsForeignSaveJxlMetadata; + +static VipsForeignSaveJxlMetadata libjxl_metadata[] = { + { VIPS_META_EXIF_NAME, "Exif" }, + { VIPS_META_XMP_NAME, "xml " } +}; + +static void +vips_foreign_save_jxl_finalize(GObject *gobject) { - JxlEncoderStatus status; - uint8_t *out; - size_t avail_out; - - do { - out = jxl->output_buffer; - avail_out = OUTPUT_BUFFER_SIZE; - status = JxlEncoderProcessOutput(jxl->encoder, - &out, &avail_out); - switch (status) { - case JXL_ENC_SUCCESS: - case JXL_ENC_NEED_MORE_OUTPUT: - if (OUTPUT_BUFFER_SIZE > avail_out && - vips_target_write(jxl->target, - jxl->output_buffer, - OUTPUT_BUFFER_SIZE - avail_out)) - return -1; - break; + VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) gobject; - default: - vips_foreign_save_jxl_error(jxl, - "JxlEncoderProcessOutput"); -#ifdef DEBUG - vips_foreign_save_jxl_print_status(status); -#endif /*DEBUG*/ - return -1; - } - } while (status != JXL_ENC_SUCCESS); + VIPS_FREEF(JxlThreadParallelRunnerDestroy, jxl->runner); + VIPS_FREEF(JxlEncoderDestroy, jxl->encoder); - return 0; + g_mutex_clear(&jxl->tile_lock); + + G_OBJECT_CLASS(vips_foreign_save_jxl_parent_class)->finalize(gobject); } -static int -vips_foreign_save_jxl_get_delay(VipsForeignSaveJxl *jxl, int page_number) +static void +vips_foreign_save_jxl_dispose(GObject *gobject) { - int delay; + VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) gobject; - if (jxl->delay && - page_number < jxl->delay_length) - delay = jxl->delay[page_number]; - else - // the old gif delay field was in centiseconds, so convert to ms - delay = jxl->gif_delay * 10; + VIPS_UNREF(jxl->target); + VIPS_FREEF(g_hash_table_destroy, jxl->tile_hash); - /* Force frames with a small or no duration to 100ms for consistency - * with web browsers and other transcoding tools. - */ - return delay <= 10 ? 100 : delay; + G_OBJECT_CLASS(vips_foreign_save_jxl_parent_class)->dispose(gobject); } static int -vips_foreign_save_jxl_add_frame(VipsForeignSaveJxl *jxl) +vips_foreign_save_jxl_set_header(VipsForeignSaveJxl *jxl, VipsImage *in) { -#ifdef HAVE_LIBJXL_0_7 - JxlEncoderFrameSettings *frame_settings; -#else - JxlEncoderOptions *frame_settings; -#endif - -#ifdef HAVE_LIBJXL_0_7 - frame_settings = JxlEncoderFrameSettingsCreate(jxl->encoder, NULL); - JxlEncoderFrameSettingsSetOption(frame_settings, - JXL_ENC_FRAME_SETTING_DECODING_SPEED, jxl->tier); - JxlEncoderSetFrameDistance(frame_settings, jxl->distance); - JxlEncoderFrameSettingsSetOption(frame_settings, - JXL_ENC_FRAME_SETTING_EFFORT, jxl->effort); - JxlEncoderSetFrameLossless(frame_settings, jxl->lossless); + VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(jxl); - if (jxl->info.have_animation) { - JxlFrameHeader header; - memset(&header, 0, sizeof(JxlFrameHeader)); + JxlEncoderInitBasicInfo(&jxl->info); - if (!jxl->is_animated) - header.duration = 0xffffffff; - else - header.duration = - vips_foreign_save_jxl_get_delay(jxl, jxl->page_number); + switch (in->BandFmt) { + case VIPS_FORMAT_UCHAR: + jxl->info.bits_per_sample = 8; + jxl->info.exponent_bits_per_sample = 0; + jxl->format.data_type = JXL_TYPE_UINT8; + break; - JxlEncoderSetFrameHeader(frame_settings, &header); + case VIPS_FORMAT_USHORT: + jxl->info.bits_per_sample = 16; + jxl->info.exponent_bits_per_sample = 0; + jxl->format.data_type = JXL_TYPE_UINT16; + break; + + case VIPS_FORMAT_FLOAT: + jxl->info.bits_per_sample = 32; + jxl->info.exponent_bits_per_sample = 8; + jxl->format.data_type = JXL_TYPE_FLOAT; + break; + + default: + g_assert_not_reached(); + break; } -#else - frame_settings = JxlEncoderOptionsCreate(jxl->encoder, NULL); - JxlEncoderOptionsSetDecodingSpeed(frame_settings, jxl->tier); - JxlEncoderOptionsSetDistance(frame_settings, jxl->distance); - JxlEncoderOptionsSetEffort(frame_settings, jxl->effort); - JxlEncoderOptionsSetLossless(frame_settings, jxl->lossless); -#endif - - if (JxlEncoderAddImageFrame(frame_settings, &jxl->format, - jxl->frame_bytes, jxl->frame_size)) { - vips_foreign_save_jxl_error(jxl, "JxlEncoderAddImageFrame"); - return -1; + + switch (in->Type) { + case VIPS_INTERPRETATION_B_W: + case VIPS_INTERPRETATION_GREY16: + jxl->info.num_color_channels = VIPS_MIN(1, in->Bands); + break; + + case VIPS_INTERPRETATION_sRGB: + case VIPS_INTERPRETATION_scRGB: + case VIPS_INTERPRETATION_RGB16: + jxl->info.num_color_channels = VIPS_MIN(3, in->Bands); + break; + + default: + jxl->info.num_color_channels = in->Bands; } + jxl->info.num_extra_channels = VIPS_MAX(0, + in->Bands - jxl->info.num_color_channels); - jxl->page_number += 1; + jxl->info.xsize = in->Xsize; + jxl->info.ysize = jxl->page_height; + jxl->format.num_channels = in->Bands; + jxl->format.endianness = JXL_NATIVE_ENDIAN; + jxl->format.align = 0; - /* We should close frames before processing the output - * if we have written the last frame - */ - if (jxl->page_number == jxl->page_count) - JxlEncoderCloseFrames(jxl->encoder); + if (jxl->page_count > 1) { + int num_loops = 0; - return vips_foreign_save_jxl_process_output(jxl); -} + if (vips_image_get_typeof(in, "loop")) + vips_image_get_int(in, "loop", &num_loops); -/* Another chunk of pixels have arrived from the pipeline. Add to frame, and - * if the frame completes, compress and write to the target. - */ -static int -vips_foreign_save_jxl_sink_disc(VipsRegion *region, VipsRect *area, void *a) -{ - VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) a; - size_t sz = VIPS_IMAGE_SIZEOF_PEL(region->im) * area->width; + jxl->info.have_animation = TRUE; + jxl->info.animation.tps_numerator = 1000; + jxl->info.animation.tps_denominator = 1; + jxl->info.animation.num_loops = num_loops; + jxl->info.animation.have_timecodes = FALSE; + } + + if (vips_image_hasalpha(in)) { + jxl->info.alpha_bits = jxl->info.bits_per_sample; + jxl->info.alpha_exponent_bits = jxl->info.exponent_bits_per_sample; + } + else { + jxl->info.alpha_exponent_bits = 0; + jxl->info.alpha_bits = 0; + } + + if (vips_image_get_typeof(in, "stonits")) { + double stonits; - int i; + if (vips_image_get_double(in, "stonits", &stonits)) + return -1; + jxl->info.intensity_target = stonits; + } - /* Write the new pixels into the frame. + /* uses_original_profile forces libjxl to not use lossy XYB + * colourspace. The name is very confusing. */ - for (i = 0; i < area->height; i++) { - memcpy(jxl->frame_bytes + sz * jxl->write_y, - VIPS_REGION_ADDR(region, 0, area->top + i), - sz); + jxl->info.uses_original_profile = jxl->lossless; - jxl->write_y += 1; + if (JxlEncoderSetBasicInfo(jxl->encoder, &jxl->info)) { + vips_foreign_save_jxl_error(jxl, "JxlEncoderSetBasicInfo"); + return -1; + } - /* If we've filled the frame, add it to the encoder. - */ - if (jxl->write_y == jxl->page_height) { - if (vips_foreign_save_jxl_add_frame(jxl)) - return -1; + /* Set any ICC profile. + */ + if (vips_image_get_typeof(in, VIPS_META_ICC_NAME)) { + const void *data; + size_t length; + + if (vips_image_get_blob(in, VIPS_META_ICC_NAME, &data, &length)) + return -1; - jxl->write_y = 0; +#ifdef DEBUG + printf("attaching %zd bytes of ICC\n", length); +#endif /*DEBUG*/ + if (JxlEncoderSetICCProfile(jxl->encoder, (guint8 *) data, length)) { + vips_foreign_save_jxl_error(jxl, "JxlEncoderSetColorEncoding"); + return -1; } } + else { + /* If there's no ICC profile, we must set the colour encoding + * ourselves. + */ + if (in->Type == VIPS_INTERPRETATION_scRGB) { +#ifdef DEBUG + printf("setting scRGB colourspace\n"); +#endif /*DEBUG*/ - return 0; -} + JxlColorEncodingSetToLinearSRGB(&jxl->color_encoding, + jxl->format.num_channels < 3); + } + else { +#ifdef DEBUG + printf("setting sRGB colourspace\n"); +#endif /*DEBUG*/ -static int -vips_foreign_save_jxl_add_metadata(VipsForeignSaveJxl *jxl, VipsImage *in) -{ -#ifdef HAVE_LIBJXL_0_7 - VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(jxl); - int i; + JxlColorEncodingSetToSRGB(&jxl->color_encoding, + jxl->format.num_channels < 3); + } - for (i = 0; i < VIPS_NUMBER(libjxl_metadata); i++) + if (JxlEncoderSetColorEncoding(jxl->encoder, &jxl->color_encoding)) { + vips_foreign_save_jxl_error(jxl, "JxlEncoderSetColorEncoding"); + return -1; + } + } + + for (int i = 0; i < VIPS_NUMBER(libjxl_metadata); i++) if (vips_image_get_typeof(in, libjxl_metadata[i].name)) { uint8_t *data; size_t length; @@ -475,7 +652,98 @@ vips_foreign_save_jxl_add_metadata(VipsForeignSaveJxl *jxl, VipsImage *in) /* It's safe to call JxlEncoderCloseBoxes even if we don't use boxes */ JxlEncoderCloseBoxes(jxl->encoder); -#endif /*HAVE_LIBJXL_0_7*/ + + return 0; +} + +static int +vips_foreign_save_jxl_get_delay(VipsForeignSaveJxl *jxl, int page_number) +{ + int delay; + + if (jxl->delay && + page_number < jxl->delay_length) + delay = jxl->delay[page_number]; + else + // the old gif delay field was in centiseconds, so convert to ms + delay = jxl->gif_delay * 10; + + /* Force frames with a small or no duration to 100ms for consistency + * with web browsers and other transcoding tools. + */ + return delay <= 10 ? 100 : delay; +} + +static int +vips_foreign_save_jxl_save_page(VipsForeignSaveJxl *jxl, + int n, VipsImage *page) +{ + jxl->page = page; + jxl->tile_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) g_object_unref); + + JxlEncoderFrameSettings *frame_settings = + JxlEncoderFrameSettingsCreate(jxl->encoder, NULL); + JxlEncoderFrameSettingsSetOption(frame_settings, + JXL_ENC_FRAME_SETTING_DECODING_SPEED, jxl->tier); + JxlEncoderSetFrameDistance(frame_settings, + jxl->distance); + JxlEncoderFrameSettingsSetOption(frame_settings, + JXL_ENC_FRAME_SETTING_EFFORT, jxl->effort); + JxlEncoderSetFrameLossless(frame_settings, + jxl->lossless); + + if (jxl->info.have_animation) { + JxlFrameHeader header = { 0 }; + + if (!jxl->is_animated) + header.duration = 0xffffffff; + else + header.duration = vips_foreign_save_jxl_get_delay(jxl, n); + + JxlEncoderSetFrameHeader(frame_settings, &header); + } + + if (JxlEncoderAddChunkedFrame(frame_settings, + n == jxl->page_count - 1, jxl->input_source)) { + VIPS_FREEF(g_hash_table_destroy, jxl->tile_hash); + vips_foreign_save_jxl_error(jxl, "JxlEncoderAddImageFrame"); + return -1; + } + +#ifdef DEBUG + printf("end of frame encode, %d regions\n", + g_hash_table_size(jxl->tile_hash)); +#endif /*DEBUG*/ + + VIPS_FREEF(g_hash_table_destroy, jxl->tile_hash); + + return 0; +} + +static int +vips_foreign_save_jxl_save(VipsForeignSaveJxl *jxl, VipsImage *in) +{ + vips_foreign_save_jxl_set_output_processor(jxl); + vips_foreign_save_jxl_set_input_source(jxl); + + for (int n = 0; n < jxl->page_count; n++) { + VipsImage *page; + + if (vips_crop(in, &page, + 0, n * jxl->page_height, in->Xsize, jxl->page_height, NULL)) + return -1; + + if (vips_foreign_save_jxl_save_page(jxl, n, page)) { + VIPS_UNREF(page); + return -1; + } + + VIPS_UNREF(page); + + if (jxl->error) + return -1; + } return 0; } @@ -485,7 +753,7 @@ vips_foreign_save_jxl_build(VipsObject *object) { VipsForeignSave *save = (VipsForeignSave *) object; VipsForeignSaveJxl *jxl = (VipsForeignSaveJxl *) object; - VipsImage **t = (VipsImage **) vips_object_local_array(object, 2); + VipsImage **t = (VipsImage **) vips_object_local_array(object, 4); VipsImage *in; VipsBandFormat format; @@ -493,27 +761,14 @@ vips_foreign_save_jxl_build(VipsObject *object) if (VIPS_OBJECT_CLASS(vips_foreign_save_jxl_parent_class)->build(object)) return -1; -#ifdef HAVE_LIBJXL_0_7 jxl->page_height = vips_image_get_page_height(save->ready); -#else - /* libjxl prior to 0.7 doesn't seem to have API for saving animations - */ - jxl->page_height = save->ready->Ysize; -#endif /*HAVE_LIBJXL_0_7*/ - jxl->page_count = save->ready->Ysize / jxl->page_height; /* If Q is set and distance is not, use Q to set a rough distance * value. */ if (!vips_object_argument_isset(object, "distance")) -#ifdef HAVE_LIBJXL_0_9 jxl->distance = JxlEncoderDistanceFromQuality((float) jxl->Q); -#else - jxl->distance = jxl->Q >= 30 - ? 0.1 + (100 - jxl->Q) * 0.09 - : 53.0 / 3000.0 * jxl->Q * jxl->Q - 23.0 / 20.0 * jxl->Q + 25.0; -#endif /* Distance 0 is lossless. libjxl will fail for lossy distance 0. */ @@ -557,152 +812,19 @@ vips_foreign_save_jxl_build(VipsObject *object) in = t[1]; } - JxlEncoderInitBasicInfo(&jxl->info); - - switch (in->BandFmt) { - case VIPS_FORMAT_UCHAR: - jxl->info.bits_per_sample = 8; - jxl->info.exponent_bits_per_sample = 0; - jxl->format.data_type = JXL_TYPE_UINT8; - break; - - case VIPS_FORMAT_USHORT: - jxl->info.bits_per_sample = 16; - jxl->info.exponent_bits_per_sample = 0; - jxl->format.data_type = JXL_TYPE_UINT16; - break; - - case VIPS_FORMAT_FLOAT: - jxl->info.bits_per_sample = 32; - jxl->info.exponent_bits_per_sample = 8; - jxl->format.data_type = JXL_TYPE_FLOAT; - break; - - default: - g_assert_not_reached(); - break; - } - - switch (in->Type) { - case VIPS_INTERPRETATION_B_W: - case VIPS_INTERPRETATION_GREY16: - jxl->info.num_color_channels = VIPS_MIN(1, in->Bands); - break; - - case VIPS_INTERPRETATION_sRGB: - case VIPS_INTERPRETATION_scRGB: - case VIPS_INTERPRETATION_RGB16: - jxl->info.num_color_channels = VIPS_MIN(3, in->Bands); - break; - - default: - jxl->info.num_color_channels = in->Bands; - } - jxl->info.num_extra_channels = VIPS_MAX(0, - in->Bands - jxl->info.num_color_channels); - - jxl->info.xsize = in->Xsize; - jxl->info.ysize = jxl->page_height; - jxl->format.num_channels = in->Bands; - jxl->format.endianness = JXL_NATIVE_ENDIAN; - jxl->format.align = 0; - -#ifdef HAVE_LIBJXL_0_7 - if (jxl->page_count > 1) { - int num_loops = 0; - - if (vips_image_get_typeof(in, "loop")) - vips_image_get_int(in, "loop", &num_loops); - - // libjxl uses "have_animation" for multipage images too, but sets - // duration to 0xffffffff - jxl->info.have_animation = TRUE; - jxl->info.animation.tps_numerator = 1000; - jxl->info.animation.tps_denominator = 1; - jxl->info.animation.num_loops = num_loops; - jxl->info.animation.have_timecodes = FALSE; - } -#endif /*HAVE_LIBJXL_0_7*/ - - if (vips_image_hasalpha(in)) { - jxl->info.alpha_bits = jxl->info.bits_per_sample; - jxl->info.alpha_exponent_bits = - jxl->info.exponent_bits_per_sample; - } - else { - jxl->info.alpha_exponent_bits = 0; - jxl->info.alpha_bits = 0; - } - - if (vips_image_get_typeof(in, "stonits")) { - double stonits; - - if (vips_image_get_double(in, "stonits", &stonits)) - return -1; - jxl->info.intensity_target = stonits; - } - - /* uses_original_profile forces libjxl to not use lossy XYB - * colourspace. The name is very confusing. - */ - jxl->info.uses_original_profile = jxl->lossless; - - if (JxlEncoderSetBasicInfo(jxl->encoder, &jxl->info)) { - vips_foreign_save_jxl_error(jxl, "JxlEncoderSetBasicInfo"); - return -1; - } - - /* Set any ICC profile. + /* We need to cache a complete line of jxl 2k x 2k tiles, plus a bit. + * We don't need to allow threaded access -- libjxl will never try to + * encode tiles in parallel (sadly). */ - if (vips_image_get_typeof(in, VIPS_META_ICC_NAME)) { - const void *data; - size_t length; - - if (vips_image_get_blob(in, - VIPS_META_ICC_NAME, &data, &length)) - return -1; - -#ifdef DEBUG - printf("attaching %zd bytes of ICC\n", length); -#endif /*DEBUG*/ - if (JxlEncoderSetICCProfile(jxl->encoder, - (guint8 *) data, length)) { - vips_foreign_save_jxl_error(jxl, - "JxlEncoderSetColorEncoding"); - return -1; - } - } - else { - /* If there's no ICC profile, we must set the colour encoding - * ourselves. - */ - if (in->Type == VIPS_INTERPRETATION_scRGB) { -#ifdef DEBUG - printf("setting scRGB colourspace\n"); -#endif /*DEBUG*/ - - JxlColorEncodingSetToLinearSRGB(&jxl->color_encoding, - jxl->format.num_channels < 3); - } - else { -#ifdef DEBUG - printf("setting sRGB colourspace\n"); -#endif /*DEBUG*/ - - JxlColorEncodingSetToSRGB(&jxl->color_encoding, - jxl->format.num_channels < 3); - } - - if (JxlEncoderSetColorEncoding(jxl->encoder, &jxl->color_encoding)) { - vips_foreign_save_jxl_error(jxl, "JxlEncoderSetColorEncoding"); - return -1; - } - } - - if (vips_foreign_save_jxl_add_metadata(jxl, in)) + if (vips_tilecache(in, &t[2], + "tile-width", in->Xsize, + "tile-height", 512, + "max_tiles", 3500 / 512, + NULL)) return -1; + in = t[2]; - if (vips_foreign_save_jxl_process_output(jxl)) + if (vips_foreign_save_jxl_set_header(jxl, in)) return -1; if (jxl->info.have_animation) { @@ -711,15 +833,15 @@ vips_foreign_save_jxl_build(VipsObject *object) * There might just be the old gif-delay field. This is centiseconds. */ jxl->gif_delay = 10; - if (vips_image_get_typeof(save->ready, "gif-delay") && - vips_image_get_int(save->ready, "gif-delay", &jxl->gif_delay)) + if (vips_image_get_typeof(in, "gif-delay") && + vips_image_get_int(in, "gif-delay", &jxl->gif_delay)) return -1; /* New images have an array of ints instead. */ jxl->delay = NULL; - if (vips_image_get_typeof(save->ready, "delay") && - vips_image_get_array_int(save->ready, "delay", + if (vips_image_get_typeof(in, "delay") && + vips_image_get_array_int(in, "delay", &jxl->delay, &jxl->delay_length)) return -1; @@ -741,31 +863,24 @@ vips_foreign_save_jxl_build(VipsObject *object) printf(" lossless = %d\n", jxl->lossless); #endif /*DEBUG*/ - /* RGB(A) frame as a contiguous buffer. + /* _save() is not a vips_sink_*() iterator, so we must emit + * the various signals by hand. */ - jxl->frame_size = VIPS_IMAGE_SIZEOF_LINE(in) * jxl->page_height; - jxl->frame_bytes = g_try_malloc(jxl->frame_size); - if (jxl->frame_bytes == NULL) { - vips_error("jxlsave", - _("failed to allocate %zu bytes"), jxl->frame_size); - return -1; - } + vips_image_preeval(save->ready); - if (vips_sink_disc(in, vips_foreign_save_jxl_sink_disc, jxl)) - return -1; + int result = vips_foreign_save_jxl_save(jxl, in); - /* This function must be called after the final frame and/or box, - * otherwise the codestream will not be encoded correctly. - */ - JxlEncoderCloseInput(jxl->encoder); + vips_image_posteval(save->ready); + + vips_image_minimise_all(save->ready); - if (vips_foreign_save_jxl_process_output(jxl)) + if (jxl->error) return -1; if (vips_target_end(jxl->target)) return -1; - return 0; + return result; } /* Save a bit of typing. @@ -790,6 +905,7 @@ vips_foreign_save_jxl_class_init(VipsForeignSaveJxlClass *class) VipsForeignClass *foreign_class = (VipsForeignClass *) class; VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class; + gobject_class->finalize = vips_foreign_save_jxl_finalize; gobject_class->dispose = vips_foreign_save_jxl_dispose; gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; @@ -847,11 +963,10 @@ vips_foreign_save_jxl_class_init(VipsForeignSaveJxlClass *class) static void vips_foreign_save_jxl_init(VipsForeignSaveJxl *jxl) { - jxl->tier = 0; jxl->distance = 1.0; jxl->effort = 7; - jxl->lossless = FALSE; jxl->Q = 75; + g_mutex_init(&jxl->tile_lock); } typedef struct _VipsForeignSaveJxlFile { diff --git a/libvips/foreign/magick6load.c b/libvips/foreign/magick6load.c index 61fcf7fba1..cd3ac4eba1 100644 --- a/libvips/foreign/magick6load.c +++ b/libvips/foreign/magick6load.c @@ -193,12 +193,12 @@ vips_foreign_load_magick_get_flags(VipsForeignLoad *load) } static void -vips_foreign_load_magick_dispose(GObject *gobject) +vips_foreign_load_magick_finalize(GObject *gobject) { VipsForeignLoadMagick *magick = (VipsForeignLoadMagick *) gobject; #ifdef DEBUG - printf("vips_foreign_load_magick_dispose: %p\n", gobject); + printf("vips_foreign_load_magick_finalize: %p\n", gobject); #endif /*DEBUG*/ VIPS_FREEF(DestroyImageList, magick->image); @@ -207,7 +207,7 @@ vips_foreign_load_magick_dispose(GObject *gobject) VIPS_FREEF(magick_destroy_exception, magick->exception); g_mutex_clear(&magick->lock); - G_OBJECT_CLASS(vips_foreign_load_magick_parent_class)->dispose(gobject); + G_OBJECT_CLASS(vips_foreign_load_magick_parent_class)->finalize(gobject); } static int @@ -223,7 +223,6 @@ vips_foreign_load_magick_build(VipsObject *object) magick->image_info = CloneImageInfo(NULL); magick->exception = magick_acquire_exception(); - g_mutex_init(&magick->lock); if (!magick->image_info) return -1; @@ -248,12 +247,10 @@ vips_foreign_load_magick_build(VipsObject *object) * These window settings are attached as vips metadata, so our caller * can interpret them if it wants. */ - magick_set_image_option(magick->image_info, - "dcm:display-range", "reset"); + magick_set_image_option(magick->image_info, "dcm:display-range", "reset"); if (magick->page > 0) - magick_set_number_scenes(magick->image_info, - magick->page, magick->n); + magick_set_number_scenes(magick->image_info, magick->page, magick->n); if (VIPS_OBJECT_CLASS(vips_foreign_load_magick_parent_class)->build(object)) return -1; @@ -270,7 +267,7 @@ vips_foreign_load_magick_class_init(VipsForeignLoadMagickClass *class) VipsForeignClass *foreign_class = (VipsForeignClass *) class; VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; - gobject_class->dispose = vips_foreign_load_magick_dispose; + gobject_class->finalize = vips_foreign_load_magick_finalize; gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; @@ -329,6 +326,7 @@ static void vips_foreign_load_magick_init(VipsForeignLoadMagick *magick) { magick->n = 1; + g_mutex_init(&magick->lock); } static int @@ -847,15 +845,13 @@ vips_foreign_load_magick_fill_region(VipsRegion *out_region, vips__worker_lock(&magick->lock); - pixels = get_pixels(magick->frames[frame], - r->left, line, r->width, 1); + pixels = get_pixels(magick->frames[frame], r->left, line, r->width, 1); g_mutex_unlock(&magick->lock); if (!pixels) { vips_foreign_load_invalidate(im); - vips_error(class->nickname, - "%s", _("unable to read pixels")); + vips_error(class->nickname, "%s", _("unable to read pixels")); return -1; } @@ -872,24 +868,21 @@ vips_foreign_load_magick_load(VipsForeignLoadMagick *magick) VipsForeignLoad *load = (VipsForeignLoad *) magick; Image *p; - int i; #ifdef DEBUG printf("vips_foreign_load_magick_load: %p\n", magick); #endif /*DEBUG*/ - if (vips_foreign_load_magick_parse(magick, - magick->image, load->out)) + if (vips_foreign_load_magick_parse(magick, magick->image, load->out)) return -1; /* Record frame pointers. */ g_assert(!magick->frames); - if (!(magick->frames = - VIPS_ARRAY(NULL, magick->n_frames, Image *))) + if (!(magick->frames = VIPS_ARRAY(NULL, magick->n_frames, Image *))) return -1; p = magick->image; - for (i = 0; i < magick->n_frames; i++) { + for (int i = 0; i < magick->n_frames; i++) { magick->frames[i] = p; p = GetNextImageInList(p); } diff --git a/libvips/foreign/magick7load.c b/libvips/foreign/magick7load.c index 9c615b6d87..62defc0a57 100644 --- a/libvips/foreign/magick7load.c +++ b/libvips/foreign/magick7load.c @@ -268,14 +268,14 @@ vips_foreign_load_magick7_get_flags(VipsForeignLoad *load) } static void -vips_foreign_load_magick7_dispose(GObject *gobject) +vips_foreign_load_magick7_finalize(GObject *gobject) { VipsForeignLoadMagick7 *magick7 = (VipsForeignLoadMagick7 *) gobject; int i; #ifdef DEBUG - printf("vips_foreign_load_magick7_dispose: %p\n", gobject); + printf("vips_foreign_load_magick7_finalize: %p\n", gobject); #endif /*DEBUG*/ for (i = 0; i < magick7->n_frames; i++) { @@ -288,7 +288,7 @@ vips_foreign_load_magick7_dispose(GObject *gobject) VIPS_FREEF(magick_destroy_exception, magick7->exception); g_mutex_clear(&magick7->lock); - G_OBJECT_CLASS(vips_foreign_load_magick7_parent_class)->dispose(gobject); + G_OBJECT_CLASS(vips_foreign_load_magick7_parent_class)->finalize(gobject); } static int @@ -304,7 +304,6 @@ vips_foreign_load_magick7_build(VipsObject *object) magick7->image_info = CloneImageInfo(NULL); magick7->exception = magick_acquire_exception(); - g_mutex_init(&magick7->lock); if (!magick7->image_info) return -1; @@ -330,10 +329,8 @@ vips_foreign_load_magick7_build(VipsObject *object) magick_set_number_scenes(magick7->image_info, magick7->page, magick7->n); - if (VIPS_OBJECT_CLASS(vips_foreign_load_magick7_parent_class)->build(object)) - return -1; - - return 0; + return VIPS_OBJECT_CLASS(vips_foreign_load_magick7_parent_class)-> + build(object); } static void @@ -345,7 +342,7 @@ vips_foreign_load_magick7_class_init(VipsForeignLoadMagick7Class *class) VipsForeignClass *foreign_class = (VipsForeignClass *) class; VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; - gobject_class->dispose = vips_foreign_load_magick7_dispose; + gobject_class->finalize = vips_foreign_load_magick7_finalize; gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; @@ -404,6 +401,7 @@ static void vips_foreign_load_magick7_init(VipsForeignLoadMagick7 *magick7) { magick7->n = 1; + g_mutex_init(&magick7->lock); } static void diff --git a/libvips/foreign/openslideconnection.c b/libvips/foreign/openslideconnection.c index 61e7dcb46b..1c75a7d80c 100644 --- a/libvips/foreign/openslideconnection.c +++ b/libvips/foreign/openslideconnection.c @@ -158,6 +158,7 @@ vips_openslideconnection_new(const char *filename) connection = g_new0(VipsOpenslideConnection, 1); connection->filename = g_strdup(filename); + g_mutex_init(&connection->osr_lock); g_assert(!g_hash_table_lookup(vips_openslideconnection_cache, filename)); diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index 2454275faa..f9b91241c1 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -442,6 +442,13 @@ void vips_image_minimise_all(VipsImage *image); VIPS_API gboolean vips_image_is_sequential(VipsImage *image); +VIPS_API +void vips_image_preeval(VipsImage *image); +VIPS_API +void vips_image_eval(VipsImage *image, guint64 processed); +VIPS_API +void vips_image_posteval(VipsImage *image); + VIPS_API void vips_image_set_progress(VipsImage *image, gboolean progress); VIPS_API diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index f27caa79f1..8a583961ca 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -236,9 +236,6 @@ int vips__image_meta_copy(VipsImage *dst, const VipsImage *src); extern GMutex vips__global_lock; int vips_image_written(VipsImage *image); -void vips_image_preeval(VipsImage *image); -void vips_image_eval(VipsImage *image, guint64 processed); -void vips_image_posteval(VipsImage *image); /* Defined in `vips.h`, unless building with `-Ddeprecated=false` */ diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index b4c75634ae..6951205bf6 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -1427,6 +1427,11 @@ vips_image_minimise_all_cb(VipsImage *image, void *a, void *b) void vips_image_minimise_all(VipsImage *image) { + /* Just like the eval callbacks, don't minimise for sub-evaluations. + */ + if (vips_image_get_typeof(image, "hide-progress")) + return; + /* Minimisation will modify things like sources, so we can't run it * from many threads. */ @@ -1548,8 +1553,7 @@ vips_image_eval(VipsImage *image, guint64 processed) * the image we are actually generating. */ if (image->progress_signal->time != image->time) - vips_progress_update(image->progress_signal->time, - processed); + vips_progress_update(image->progress_signal->time, processed); if (!vips_image_get_typeof(image, "hide-progress")) g_signal_emit(image->progress_signal, diff --git a/meson.build b/meson.build index 2b0e993970..19ffe04882 100644 --- a/meson.build +++ b/meson.build @@ -514,8 +514,9 @@ if libheif_dep.found() cfg_var.set('HAVE_HEIF_GET_DISABLED_SECURITY_LIMITS', cpp.has_function('heif_get_disabled_security_limits', prefix: '#include ', dependencies: libheif_dep)) endif -libjxl_dep = dependency('libjxl', version: '>=0.6', required: get_option('jpeg-xl')) -libjxl_threads_dep = dependency('libjxl_threads', version: '>=0.6', required: get_option('jpeg-xl')) +# need v0.11+ for chunked write +libjxl_dep = dependency('libjxl', version: '>=0.11', required: get_option('jpeg-xl')) +libjxl_threads_dep = dependency('libjxl_threads', version: '>=0.11', required: get_option('jpeg-xl')) libjxl_found = libjxl_dep.found() and libjxl_threads_dep.found() libjxl_module = false if libjxl_found @@ -529,8 +530,6 @@ if libjxl_found external_deps += libjxl_threads_dep endif cfg_var.set('HAVE_LIBJXL', true) - cfg_var.set('HAVE_LIBJXL_0_7', libjxl_dep.version().version_compare('>=0.7')) - cfg_var.set('HAVE_LIBJXL_0_9', libjxl_dep.version().version_compare('>=0.9')) endif # only if pdfium not found From a8f3725e19fb9b789bb3ef3cf316ec2852e6488c Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 9 May 2025 13:53:16 +0200 Subject: [PATCH 168/174] Silence a clang warning (#4505) --- libvips/foreign/foreign.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 29c5851187..7c4a07adfd 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1588,7 +1588,6 @@ vips__foreign_convert_saveable(VipsImage *in, VipsImage **ready, int max_bands; // use a sanity-checked interpretation - max_bands = 0; switch (vips_image_guess_interpretation(in)) { case VIPS_INTERPRETATION_B_W: case VIPS_INTERPRETATION_GREY16: @@ -1614,6 +1613,8 @@ vips__foreign_convert_saveable(VipsImage *in, VipsImage **ready, break; default: + max_bands = 0; + break; } if (saveable & VIPS_FOREIGN_SAVEABLE_ALPHA) From 1d45a12bf663246dd1626c080086e8e4f713154e Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 10 May 2025 13:07:42 +0200 Subject: [PATCH 169/174] Regenerate C++ binding and function list (#4507) --- cplusplus/gen-operators.py | 11 ++++++++--- cplusplus/include/vips/VImage8.h | 17 ++++++++-------- cplusplus/vips-operators.cpp | 3 +++ doc/fixup-gir-for-doc.py | 1 + doc/function-list.md | 3 ++- doc/gen-function-list.py | 34 +++++++++++++++++++++----------- 6 files changed, 45 insertions(+), 24 deletions(-) diff --git a/cplusplus/gen-operators.py b/cplusplus/gen-operators.py index f76af70d0b..6407c67a23 100755 --- a/cplusplus/gen-operators.py +++ b/cplusplus/gen-operators.py @@ -4,10 +4,9 @@ # operators. # this needs pyvips -# # pip install --user pyvips -# Rebuild with: +# rebuild with: # meson compile -Cbuild vips-operators-header # meson compile -Cbuild vips-operators-source @@ -262,8 +261,14 @@ def add_nickname(gtype, a, b): all_nicknames = list(set(all_nicknames) - set(hidden_savers)) all_nicknames.sort() + indent = '\t' if declarations_only else '' + + print(f'''{indent}// {'headers' if declarations_only else 'bodies'} for vips operations +{indent}// this file is generated automatically, do not edit! +{indent}// clang-format off''') + for nickname in all_nicknames: - print(generate_operation(nickname, declarations_only, '\t' if declarations_only else '')) + print(generate_operation(nickname, declarations_only, indent)) parser = argparse.ArgumentParser(description='C++ binding generator') diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h index 6a56c18ae8..c40095ccd5 100644 --- a/cplusplus/include/vips/VImage8.h +++ b/cplusplus/include/vips/VImage8.h @@ -2082,6 +2082,7 @@ class VImage : public VObject { // headers for vips operations // this file is generated automatically, do not edit! + // clang-format off /** * Transform lch to cmc. @@ -5879,8 +5880,8 @@ class VImage : public VObject { * - **no_rotate** -- Don't use orientation tags to rotate image upright, bool. * - **crop** -- Reduce to fill target rectangle, then crop, VipsInteresting. * - **linear** -- Reduce in linear light, bool. - * - **import_profile** -- Fallback import profile, const char *. - * - **export_profile** -- Fallback export profile, const char *. + * - **input_profile** -- Fallback input profile, const char *. + * - **output_profile** -- Fallback output profile, const char *. * - **intent** -- Rendering intent, VipsIntent. * - **fail_on** -- Error level to fail on, VipsFailOn. * @@ -5901,8 +5902,8 @@ class VImage : public VObject { * - **no_rotate** -- Don't use orientation tags to rotate image upright, bool. * - **crop** -- Reduce to fill target rectangle, then crop, VipsInteresting. * - **linear** -- Reduce in linear light, bool. - * - **import_profile** -- Fallback import profile, const char *. - * - **export_profile** -- Fallback export profile, const char *. + * - **input_profile** -- Fallback input profile, const char *. + * - **output_profile** -- Fallback output profile, const char *. * - **intent** -- Rendering intent, VipsIntent. * - **fail_on** -- Error level to fail on, VipsFailOn. * @@ -5922,8 +5923,8 @@ class VImage : public VObject { * - **no_rotate** -- Don't use orientation tags to rotate image upright, bool. * - **crop** -- Reduce to fill target rectangle, then crop, VipsInteresting. * - **linear** -- Reduce in linear light, bool. - * - **import_profile** -- Fallback import profile, const char *. - * - **export_profile** -- Fallback export profile, const char *. + * - **input_profile** -- Fallback input profile, const char *. + * - **output_profile** -- Fallback output profile, const char *. * - **intent** -- Rendering intent, VipsIntent. * - **fail_on** -- Error level to fail on, VipsFailOn. * @@ -5943,8 +5944,8 @@ class VImage : public VObject { * - **no_rotate** -- Don't use orientation tags to rotate image upright, bool. * - **crop** -- Reduce to fill target rectangle, then crop, VipsInteresting. * - **linear** -- Reduce in linear light, bool. - * - **import_profile** -- Fallback import profile, const char *. - * - **export_profile** -- Fallback export profile, const char *. + * - **input_profile** -- Fallback input profile, const char *. + * - **output_profile** -- Fallback output profile, const char *. * - **intent** -- Rendering intent, VipsIntent. * - **fail_on** -- Error level to fail on, VipsFailOn. * diff --git a/cplusplus/vips-operators.cpp b/cplusplus/vips-operators.cpp index 7c56408e11..27ddfe8c7c 100644 --- a/cplusplus/vips-operators.cpp +++ b/cplusplus/vips-operators.cpp @@ -1,3 +1,6 @@ +// bodies for vips operations +// this file is generated automatically, do not edit! +// clang-format off VImage VImage::CMC2LCh(VOption *options) const diff --git a/doc/fixup-gir-for-doc.py b/doc/fixup-gir-for-doc.py index 414b6ff54d..c6e507ac78 100755 --- a/doc/fixup-gir-for-doc.py +++ b/doc/fixup-gir-for-doc.py @@ -61,6 +61,7 @@ def fixup_gir_for_doc(args): # Functions that take multiple images as input argument ... make them # part of the Image class. + # Keep-in-sync with gen-function-list.py image_funcs = [ 'arrayjoin', 'bandjoin', diff --git a/doc/function-list.md b/doc/function-list.md index 0c82e8310a..283e5f635c 100644 --- a/doc/function-list.md +++ b/doc/function-list.md @@ -289,6 +289,7 @@ API docs each function links to for more details. | `relational_const` | Relational operations against a constant | [method@Image.relational_const], [method@Image.equal_const], [method@Image.notequal_const], [method@Image.less_const], [method@Image.lesseq_const], [method@Image.more_const], [method@Image.moreeq_const], [method@Image.relational_const1], [method@Image.equal_const1], [method@Image.notequal_const1], [method@Image.less_const1], [method@Image.lesseq_const1], [method@Image.more_const1], [method@Image.moreeq_const1] | | `remainder` | Remainder after integer division of two images | [method@Image.remainder] | | `remainder_const` | Remainder after integer division of an image and a constant | [method@Image.remainder_const], [method@Image.remainder_const1] | +| `remosaic` | Rebuild an mosaiced image | [method@Image.remosaic] | | `replicate` | Replicate an image | [method@Image.replicate] | | `resize` | Resize an image | [method@Image.resize] | | `rot` | Rotate an image | [method@Image.rot] | @@ -299,7 +300,7 @@ API docs each function links to for more details. | `sRGB2scRGB` | Convert an srgb image to scrgb | [method@Image.sRGB2scRGB] | | `scRGB2BW` | Convert scrgb to bw | [method@Image.scRGB2BW] | | `scRGB2XYZ` | Transform scrgb to xyz | [method@Image.scRGB2XYZ] | -| `scRGB2sRGB` | Convert an scrgb image to srgb | [method@Image.scRGB2sRGB] | +| `scRGB2sRGB` | Convert scrgb to srgb | [method@Image.scRGB2sRGB] | | `scale` | Scale an image to uchar | [method@Image.scale] | | `scharr` | Scharr edge detector | [method@Image.scharr] | | `sdf` | Create an sdf image | [ctor@Image.sdf] | diff --git a/doc/gen-function-list.py b/doc/gen-function-list.py index 2e87802e90..d1d12cfd93 100755 --- a/doc/gen-function-list.py +++ b/doc/gen-function-list.py @@ -4,16 +4,13 @@ # for docs # this needs pyvips -# # pip install --user pyvips -# sample output: +# rebuild with: +# ./gen-function-list.py > function-list.md -# -# gamma -# Gamma an image -# vips_gamma() -# +# sample output: +# | `gamma` | Gamma an image | [method@Image.gamma] | from pyvips import Introspect, Operation, Error, \ ffi, type_map, type_from_name, nickname_find @@ -25,10 +22,25 @@ def gen_function(operation_name, overloads): intro = Introspect.get(operation_name) - c_operations = 'vips_{}()'.format(operation_name) + # Keep-in-sync with fixup-gir-for-doc.py + image_funcs = [ + 'arrayjoin', + 'bandjoin', + 'bandrank', + 'composite', + 'sum', + 'switch', + ] + + if operation_name in image_funcs: + c_operations = f'[func@Image.{operation_name}]' + else: + operation_type = 'ctor' if intro.member_x is None else 'method' + operation_class = 'Blob' if operation_name == 'profile_load' else 'Image' + c_operations = f'[{operation_type}@{operation_class}.{operation_name}]' if overloads: - c_operations += ', ' + (', '.join('vips_{}()'.format(n) for n in overloads)) + c_operations += ', ' + (', '.join(f'[method@Image.{n}]' for n in overloads)) result = f"| `{operation_name}` | {intro.description.capitalize()} | {c_operations} |" @@ -111,9 +123,7 @@ def add_nickname(gtype, a, b): if __name__ == '__main__': - print("""Title: All libvips functions and operators - -# Introduction + print("""Title: Operator index / Alphabetical libvips has a set of operators, each of which computes some useful image processing operation. Each operator is implemented as a [class@GObject.Object] From da92837f3cf26d9debacfa8c122da10d79996de4 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 10 May 2025 15:00:03 +0200 Subject: [PATCH 170/174] doc: avoid gi-docgen linking syntax for non-doc comments (#4506) --- libvips/iofuncs/image.c | 10 +++++----- libvips/iofuncs/object.c | 2 +- libvips/iofuncs/operation.c | 2 +- libvips/iofuncs/region.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 6951205bf6..0521cc11dd 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -1523,7 +1523,7 @@ vips_image_preeval(VipsImage *image) /* For vips7 compat, we also have to make sure ->time on the * image that was originally marked with - * [method@Image.set_progress] is valid. + * vips_image_set_progress() is valid. */ (void) vips_progress_add(image->progress_signal); @@ -2655,7 +2655,7 @@ vips_image_write(VipsImage *image, VipsImage *out) * * If it's not partial, perhaps a file we write to or a memory image, * we need to break any links between @image and @out created by - * [method@Image.pipelinev]. + * vips_image_pipelinev(). */ if (vips_image_ispartial(out)) { vips_object_local(out, image); @@ -3223,7 +3223,7 @@ vips_image_write_line(VipsImage *image, int ypos, VipsPel *linebuffer) return -1; /* Always clear kill before we start looping. See the - * call to [method@Image.iskilled] below. + * call to vips_image_iskilled() below. */ vips_image_set_kill(image, FALSE); vips_image_write_prepare(image); @@ -3469,7 +3469,7 @@ vips_image_wio_input(VipsImage *image) g_object_unref(t1); /* We need to zap any start/gen/stop callbacks. If we don't, - * calling [method@Region.prepare_to] later to read from this + * calling vips_region_prepare_to() later to read from this * image will fail, since it will think it needs to create the * image, not read from it. */ @@ -3553,7 +3553,7 @@ vips__image_wio_output(VipsImage *image) * * We used to check that ->data was null and warn about * writing twice, but we no longer insist that this is called - * before [method@Image.write_prepare], so we can't do that any + * before vips_image_write_prepare(), so we can't do that any * more. */ break; diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 62b3bbad4a..593d76a671 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -933,7 +933,7 @@ vips_object_dispose_argument(VipsObject *object, GParamSpec *pspec, /* Free all args on this object which may be holding resources. * - * Note that this is not the same as [method@Object.unref_outputs]. That + * Note that this is not the same as vips_object_unref_outputs(). That * looks for output objects which may have been created during _build() which * hold refs to this object and unrefs them. * diff --git a/libvips/iofuncs/operation.c b/libvips/iofuncs/operation.c index 6c914e2293..eb8be37a20 100644 --- a/libvips/iofuncs/operation.c +++ b/libvips/iofuncs/operation.c @@ -1425,7 +1425,7 @@ vips_call_argv_output(VipsObject *object, * the GOption parser already, see above. * * We don't create the operation, so we must not unref it. The caller must - * unref on error too. The caller must also call [method@Object.unref_outputs] on + * unref on error too. The caller must also call vips_object_unref_outputs() on * all code paths. */ int diff --git a/libvips/iofuncs/region.c b/libvips/iofuncs/region.c index ff2ea280e7..55218eb299 100644 --- a/libvips/iofuncs/region.c +++ b/libvips/iofuncs/region.c @@ -1799,7 +1799,7 @@ vips_region_prepare_to(VipsRegion *reg, /* clip r first against the size of reg->im, then again against the * memory we have available to write to on dest. Just like - * [method@Region.region] + * vips_region_region() */ image.top = 0; image.left = 0; From ec0b7fa62fa878bfbc981f978cd480a21fa22b38 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 10 May 2025 16:52:43 +0200 Subject: [PATCH 171/174] shrinkv: align chunking with shrinkh (#4474) * shrinkv: re-introduce sum buffer In preparation for the next commit. This partially reverts commit 77e8451f13c0aeb949648b299a4148eaec2584a9. * Revert "Better shrinkv chunking" This partially reverts commit da53d0e12bbdea61ccb32761db28b977ba168344. * shrinkv: align chunking with shrinkh i.e. read up to 16 (i.e. fatstrip) scanlines at a time. * shrinkv: prevent overallocation of the sum buffer --- libvips/resample/presample.h | 6 +- libvips/resample/shrinkv.c | 392 ++++++++++++++++++++----------- libvips/resample/shrinkv_hwy.cpp | 116 +++++---- 3 files changed, 320 insertions(+), 194 deletions(-) diff --git a/libvips/resample/presample.h b/libvips/resample/presample.h index 56c436e9ff..9a5f079b71 100644 --- a/libvips/resample/presample.h +++ b/libvips/resample/presample.h @@ -80,8 +80,10 @@ void vips_reducev_uchar_hwy(VipsPel *pout, VipsPel *pin, void vips_shrinkh_uchar_hwy(VipsPel *pout, VipsPel *pin, int width, int hshrink, int bands); -void vips_shrinkv_uchar_hwy(VipsPel *pout, VipsPel *pin, - int ne, int vshrink, int lskip); +void vips_shrinkv_add_line_uchar_hwy(VipsPel *pin, + int ne, unsigned int *restrict sum); +void vips_shrinkv_write_line_uchar_hwy(VipsPel *pout, + int ne, int vshrink, unsigned int *restrict sum); #ifdef __cplusplus } diff --git a/libvips/resample/shrinkv.c b/libvips/resample/shrinkv.c index d45b996d2f..9b0f1c1df3 100644 --- a/libvips/resample/shrinkv.c +++ b/libvips/resample/shrinkv.c @@ -49,8 +49,6 @@ * - use a double sum buffer for int32 types * 22/4/22 kleisauke * - add @ceil option - * 12/8/23 jcupitt - * - improve chunking for small shrinks */ /* @@ -90,6 +88,7 @@ #include #include +#include #include #include @@ -103,7 +102,8 @@ typedef struct _VipsShrinkv { VipsResample parent_instance; - int vshrink; /* Shrink factor */ + int vshrink; /* Shrink factor */ + size_t sizeof_line_buffer; gboolean ceil; /* Round operation */ } VipsShrinkv; @@ -112,139 +112,189 @@ typedef VipsResampleClass VipsShrinkvClass; G_DEFINE_TYPE(VipsShrinkv, vips_shrinkv, VIPS_TYPE_RESAMPLE); +/* Our per-sequence parameter struct. Somewhere to sum band elements. + */ +typedef struct { + VipsRegion *ir; + + VipsPel *sum; +} VipsShrinkvSequence; + +/* Free a sequence value. + */ +static int +vips_shrinkv_stop(void *vseq, void *a, void *b) +{ + VipsShrinkvSequence *seq = (VipsShrinkvSequence *) vseq; + + VIPS_FREEF(g_object_unref, seq->ir); + VIPS_FREE(seq->sum); + VIPS_FREE(seq); + + return 0; +} + +/* Make a sequence value. + */ +static void * +vips_shrinkv_start(VipsImage *out, void *a, void *b) +{ + VipsImage *in = (VipsImage *) a; + VipsShrinkv *shrink = (VipsShrinkv *) b; + VipsShrinkvSequence *seq; + + if (!(seq = VIPS_NEW(NULL, VipsShrinkvSequence))) + return NULL; + + seq->ir = vips_region_new(in); + + /* Big enough for the largest intermediate .. a couple of scanlines. + */ + seq->sum = VIPS_ARRAY(NULL, shrink->sizeof_line_buffer, VipsPel); + + return (void *) seq; +} + +#define ADD(ACC_TYPE, TYPE) \ + { \ + ACC_TYPE *restrict sum = (ACC_TYPE *) seq->sum + sz * y; \ + TYPE *restrict p = (TYPE *) in; \ +\ + for (x = 0; x < sz; x++) \ + sum[x] += p[x]; \ + } + +/* Add a line of pixels to sum. + */ +static void +vips_shrinkv_add_line(VipsShrinkv *shrink, VipsShrinkvSequence *seq, + VipsRegion *ir, int left, int top, int width, int y) +{ + VipsResample *resample = VIPS_RESAMPLE(shrink); + const int bands = resample->in->Bands * + (vips_band_format_iscomplex(resample->in->BandFmt) ? 2 : 1); + const int sz = bands * width; + + int x; + + VipsPel *in = VIPS_REGION_ADDR(ir, left, top); + switch (resample->in->BandFmt) { + case VIPS_FORMAT_UCHAR: + ADD(int, unsigned char); + break; + case VIPS_FORMAT_CHAR: + ADD(int, char); + break; + case VIPS_FORMAT_USHORT: + ADD(int, unsigned short); + break; + case VIPS_FORMAT_SHORT: + ADD(int, short); + break; + case VIPS_FORMAT_UINT: + ADD(gint64, unsigned int); + break; + case VIPS_FORMAT_INT: + ADD(gint64, int); + break; + case VIPS_FORMAT_FLOAT: + ADD(double, float); + break; + case VIPS_FORMAT_DOUBLE: + ADD(double, double); + break; + case VIPS_FORMAT_COMPLEX: + ADD(double, float); + break; + case VIPS_FORMAT_DPCOMPLEX: + ADD(double, double); + break; + + default: + g_assert_not_reached(); + } +} + /* Fixed-point arithmetic path for uchar images. */ -#define UCHAR_SHRINK(BANDS) \ +#define UCHAR_AVG() \ { \ - unsigned char *restrict p = (unsigned char *) in; \ + int *restrict sum = (int *) seq->sum + sz * y; \ unsigned char *restrict q = (unsigned char *) out; \ + int amend = shrink->vshrink / 2; \ + unsigned int multiplier = (1LL << 32) / ((1 << 8) * shrink->vshrink); \ \ - for (x = 0; x < width; x++) { \ - for (b = 0; b < BANDS; b++) { \ - int sum = amend; \ - unsigned char *restrict ptr = p + b; \ - unsigned char *restrict end = ptr + (shrink->vshrink * ls); \ - for (; ptr < end; ptr += ls) \ - sum += *ptr; \ - q[b] = (sum * multiplier) >> 24; \ - } \ - p += BANDS; \ - q += BANDS; \ - } \ + for (x = 0; x < sz; x++) \ + q[x] = ((sum[x] + amend) * multiplier) >> 24; \ } -/* Integer shrink. +/* Integer average. */ -#define ISHRINK(ACC_TYPE, TYPE, BANDS) \ +#define IAVG(ACC_TYPE, TYPE) \ { \ - TYPE *restrict p = (TYPE *) in; \ + ACC_TYPE *restrict sum = (ACC_TYPE *) seq->sum + sz * y; \ TYPE *restrict q = (TYPE *) out; \ + int amend = shrink->vshrink / 2; \ \ - for (x = 0; x < width; x++) { \ - for (b = 0; b < BANDS; b++) { \ - ACC_TYPE sum = amend; \ - TYPE *restrict ptr = p + b; \ - TYPE *restrict end = ptr + (shrink->vshrink * ls); \ - for (; ptr < end; ptr += ls) \ - sum += *ptr; \ - q[b] = sum / shrink->vshrink; \ - } \ - p += BANDS; \ - q += BANDS; \ - } \ + for (x = 0; x < sz; x++) \ + q[x] = (sum[x] + amend) / shrink->vshrink; \ } -/* Float shrink. +/* Float average. */ -#define FSHRINK(TYPE) \ +#define FAVG(TYPE) \ { \ - TYPE *restrict p = (TYPE *) in; \ + double *restrict sum = (double *) seq->sum + sz * y; \ TYPE *restrict q = (TYPE *) out; \ \ - for (x = 0; x < width; x++) { \ - for (b = 0; b < bands; b++) { \ - double sum = 0.0; \ - TYPE *restrict ptr = p + b; \ - TYPE *restrict end = ptr + (shrink->vshrink * ls); \ - for (; ptr < end; ptr += ls) \ - sum += *ptr; \ - q[b] = sum / shrink->vshrink; \ - } \ - p += bands; \ - q += bands; \ - } \ + for (x = 0; x < sz; x++) \ + q[x] = sum[x] / shrink->vshrink; \ } -/* Generate an area of @out_region. @ir is large enough. +/* Average the line of sums to out. */ static void -vips_shrinkv_gen2(VipsShrinkv *shrink, VipsRegion *out_region, VipsRegion *ir, - int left, int top, int width) +vips_shrinkv_write_line(VipsShrinkv *shrink, VipsShrinkvSequence *seq, + VipsRegion *out_region, int left, int top, int width, int y) { VipsResample *resample = VIPS_RESAMPLE(shrink); const int bands = resample->in->Bands * (vips_band_format_iscomplex(resample->in->BandFmt) ? 2 : 1); - const int ls = VIPS_REGION_LSKIP(ir) / - VIPS_IMAGE_SIZEOF_ELEMENT(resample->in); - VipsPel *out = VIPS_REGION_ADDR(out_region, left, top); - VipsPel *in = VIPS_REGION_ADDR(ir, left, top * shrink->vshrink); - - int amend = shrink->vshrink / 2; + const int sz = bands * width; - int x, b; + int x; + VipsPel *out = VIPS_REGION_ADDR(out_region, left, top); switch (resample->in->BandFmt) { - case VIPS_FORMAT_UCHAR: { - unsigned int multiplier = (1LL << 32) / ((1 << 8) * shrink->vshrink); - - /* Generate a special path for 1, 3 and 4 band uchar data. The - * compiler will be able to vectorise these. - * - * Vectorisation doesn't help much for 16, 32-bit or float - * data, don't bother with them. - */ - switch (bands) { - case 1: - UCHAR_SHRINK(1); - break; - case 3: - UCHAR_SHRINK(3); - break; - case 4: - UCHAR_SHRINK(4); - break; - default: - UCHAR_SHRINK(bands); - break; - } + case VIPS_FORMAT_UCHAR: + UCHAR_AVG(); break; - } case VIPS_FORMAT_CHAR: - ISHRINK(int, char, bands); + IAVG(int, char); break; case VIPS_FORMAT_USHORT: - ISHRINK(int, unsigned short, bands); + IAVG(int, unsigned short); break; case VIPS_FORMAT_SHORT: - ISHRINK(int, short, bands); + IAVG(int, short); break; case VIPS_FORMAT_UINT: - ISHRINK(gint64, unsigned int, bands); + IAVG(gint64, unsigned int); break; case VIPS_FORMAT_INT: - ISHRINK(gint64, int, bands); + IAVG(gint64, int); break; case VIPS_FORMAT_FLOAT: - FSHRINK(float); + FAVG(float); break; case VIPS_FORMAT_DOUBLE: - FSHRINK(double); + FAVG(double); break; case VIPS_FORMAT_COMPLEX: - FSHRINK(float); + FAVG(float); break; case VIPS_FORMAT_DPCOMPLEX: - FSHRINK(double); + FAVG(double); break; default: @@ -254,24 +304,25 @@ vips_shrinkv_gen2(VipsShrinkv *shrink, VipsRegion *out_region, VipsRegion *ir, static int vips_shrinkv_gen(VipsRegion *out_region, - void *seq, void *a, void *b, gboolean *stop) + void *vseq, void *a, void *b, gboolean *stop) { + VipsShrinkvSequence *seq = (VipsShrinkvSequence *) vseq; VipsShrinkv *shrink = (VipsShrinkv *) b; - VipsRegion *ir = (VipsRegion *) seq; + VipsRegion *ir = seq->ir; VipsRect *r = &out_region->valid; - /* How do we chunk up the output image? We don't want to prepare the - * whole of the input region corresponding to *r since it could be huge. + /* How do we chunk up the image? We don't want to prepare the whole of + * the input region corresponding to *r since it could be huge. * - * We also don't want to fetch a line at a time, since that can make - * upstream coordinate changes very expensive. + * Reading a line at a time could cause a lot of overcomputation, depending + * on what's upstream from us. In SMALLTILE, output scanlines could be + * quite small. * - * Instead, aim for a minimum of tile_height on the input image. + * Use fatstrip height as a compromise. */ - int input_target = VIPS_MAX(shrink->vshrink, r->height); - int dy = input_target / shrink->vshrink; + int dy = vips__fatstrip_height; - int y, y1; + int y, y1, y2; #ifdef DEBUG printf("vips_shrinkv_gen: generating %d x %d at %d x %d\n", @@ -281,24 +332,42 @@ vips_shrinkv_gen(VipsRegion *out_region, for (y = 0; y < r->height; y += dy) { int chunk_height = VIPS_MIN(dy, r->height - y); - VipsRect s; + memset(seq->sum, 0, shrink->sizeof_line_buffer); - s.left = r->left; - s.top = (r->top + y) * shrink->vshrink; - s.width = r->width; - s.height = chunk_height * shrink->vshrink; + const int start = (r->top + y) * shrink->vshrink; + const int end = (r->top + y + chunk_height) * shrink->vshrink; + + for (y1 = start; y1 < end; y1 += dy) { + VipsRect s; + + s.left = r->left; + s.top = y1; + s.width = r->width; + s.height = VIPS_MIN(dy, end - y1); #ifdef DEBUG - printf("vips_shrinkv_gen: requesting %d lines from %d\n", - s.height, s.top); + printf("vips_shrinkv_gen: requesting %d lines from %d\n", + s.height, s.top); #endif /*DEBUG*/ - if (vips_region_prepare(ir, &s)) - return -1; + if (vips_region_prepare(ir, &s)) + return -1; + + VIPS_GATE_START("vips_shrinkv_gen: work"); + + for (y2 = 0; y2 < s.height; y2++) { + int chunk_y = (y1 + y2 - start) / shrink->vshrink; + + vips_shrinkv_add_line(shrink, seq, ir, + s.left, y1 + y2, s.width, chunk_y); + } + + VIPS_GATE_STOP("vips_shrinkv_gen: work"); + } VIPS_GATE_START("vips_shrinkv_gen: work"); for (y1 = 0; y1 < chunk_height; y1++) - vips_shrinkv_gen2(shrink, out_region, ir, - r->left, r->top + y + y1, r->width); + vips_shrinkv_write_line(shrink, seq, out_region, + r->left, r->top + y + y1, r->width, y1); VIPS_GATE_STOP("vips_shrinkv_gen: work"); } @@ -311,27 +380,28 @@ vips_shrinkv_gen(VipsRegion *out_region, #ifdef HAVE_HWY static int vips_shrinkv_uchar_vector_gen(VipsRegion *out_region, - void *seq, void *a, void *b, gboolean *stop) + void *vseq, void *a, void *b, gboolean *stop) { + VipsShrinkvSequence *seq = (VipsShrinkvSequence *) vseq; VipsImage *in = (VipsImage *) a; VipsShrinkv *shrink = (VipsShrinkv *) b; - VipsRegion *ir = (VipsRegion *) seq; + VipsRegion *ir = seq->ir; VipsRect *r = &out_region->valid; const int bands = in->Bands; int ne = r->width * bands; - /* How do we chunk up the output image? We don't want to prepare the - * whole of the input region corresponding to *r since it could be huge. + /* How do we chunk up the image? We don't want to prepare the whole of + * the input region corresponding to *r since it could be huge. * - * We also don't want to fetch a line at a time, since that can make - * upstream coordinate changes very expensive. + * Reading a line at a time could cause a lot of overcomputation, depending + * on what's upstream from us. In SMALLTILE, output scanlines could be + * quite small. * - * Instead, aim for a minimum of tile_height on the input image. + * Use fatstrip height as a compromise. */ - int input_target = VIPS_MAX(shrink->vshrink, r->height); - int dy = input_target / shrink->vshrink; + int dy = vips__fatstrip_height; - int y, y1; + int y, y1, y2; #ifdef DEBUG printf("vips_shrinkv_uchar_vector_gen: generating %d x %d at %d x %d\n", @@ -341,32 +411,47 @@ vips_shrinkv_uchar_vector_gen(VipsRegion *out_region, for (y = 0; y < r->height; y += dy) { int chunk_height = VIPS_MIN(dy, r->height - y); - VipsRect s; + memset(seq->sum, 0, shrink->sizeof_line_buffer); + + const int start = (r->top + y) * shrink->vshrink; + const int end = (r->top + y + chunk_height) * shrink->vshrink; - s.left = r->left; - s.top = (r->top + y) * shrink->vshrink; - s.width = r->width; - s.height = chunk_height * shrink->vshrink; + for (y1 = start; y1 < end; y1 += dy) { + VipsRect s; + + s.left = r->left; + s.top = y1; + s.width = r->width; + s.height = VIPS_MIN(dy, end - y1); #ifdef DEBUG - printf("vips_shrinkv_uchar_vector_gen: requesting %d lines from %d\n", - s.height, s.top); + printf( + "vips_shrinkv_uchar_vector_gen: requesting %d lines from %d\n", + s.height, s.top); #endif /*DEBUG*/ - if (vips_region_prepare(ir, &s)) - return -1; + if (vips_region_prepare(ir, &s)) + return -1; - VIPS_GATE_START("vips_shrinkv_uchar_vector_gen: work"); + VIPS_GATE_START("vips_shrinkv_uchar_vector_gen: work"); - const int lskip = VIPS_REGION_LSKIP(ir); + for (y2 = 0; y2 < s.height; y2++) { + VipsPel *p = VIPS_REGION_ADDR(ir, r->left, y1 + y2); + int chunk_y = (y1 + y2 - start) / shrink->vshrink; - // each output line - for (y1 = 0; y1 < chunk_height; y1++) { - // top of this line in the output - int top = r->top + y + y1; + vips_shrinkv_add_line_uchar_hwy(p, ne, + (unsigned int *) seq->sum + ne * chunk_y); + } - VipsPel *q = VIPS_REGION_ADDR(out_region, r->left, top); - VipsPel *p = VIPS_REGION_ADDR(ir, r->left, top * shrink->vshrink); + VIPS_GATE_STOP("vips_shrinkv_uchar_vector_gen: work"); + } + + VIPS_GATE_START("vips_shrinkv_uchar_vector_gen: work"); - vips_shrinkv_uchar_hwy(q, p, ne, shrink->vshrink, lskip); + for (y1 = 0; y1 < chunk_height; y1++) { + VipsPel *q = VIPS_REGION_ADDR(out_region, r->left, + r->top + y + y1); + + vips_shrinkv_write_line_uchar_hwy(q, ne, shrink->vshrink, + (unsigned int *) seq->sum + ne * y1); } VIPS_GATE_STOP("vips_shrinkv_uchar_vector_gen: work"); @@ -388,6 +473,7 @@ vips_shrinkv_build(VipsObject *object) VipsImage *in; VipsGenerateFn generate; + size_t acc_size; if (VIPS_OBJECT_CLASS(vips_shrinkv_parent_class)->build(object)) return -1; @@ -414,6 +500,32 @@ vips_shrinkv_build(VipsObject *object) return -1; in = t[1]; + /* Determine the accumulator size based on the band format. + */ + switch (resample->in->BandFmt) { + case VIPS_FORMAT_UINT: + case VIPS_FORMAT_INT: + acc_size = sizeof(gint64); + break; + case VIPS_FORMAT_FLOAT: + case VIPS_FORMAT_COMPLEX: + case VIPS_FORMAT_DOUBLE: + case VIPS_FORMAT_DPCOMPLEX: + acc_size = sizeof(double); + break; + default: + acc_size = sizeof(int); + break; + } + + if (vips_band_format_iscomplex(resample->in->BandFmt)) + acc_size *= 2; + + /* We have to keep a line buffer as we sum columns. + */ + shrink->sizeof_line_buffer = + in->Xsize * in->Bands * vips__fatstrip_height * acc_size; + /* For uchar input, try to make a vector path. */ #ifdef HAVE_HWY @@ -459,7 +571,7 @@ vips_shrinkv_build(VipsObject *object) #endif /*DEBUG*/ if (vips_image_generate(t[2], - vips_start_one, generate, vips_stop_one, + vips_shrinkv_start, generate, vips_shrinkv_stop, in, shrink)) return -1; diff --git a/libvips/resample/shrinkv_hwy.cpp b/libvips/resample/shrinkv_hwy.cpp index fad6387008..99f57ce68b 100644 --- a/libvips/resample/shrinkv_hwy.cpp +++ b/libvips/resample/shrinkv_hwy.cpp @@ -75,12 +75,51 @@ constexpr int32_t max_bits = 1 << 8; #endif HWY_ATTR void -vips_shrinkv_uchar_hwy(VipsPel *pout, VipsPel *pin, - int32_t ne, int32_t vshrink, int32_t lskip) +vips_shrinkv_add_line_uchar_hwy(VipsPel *pin, + int32_t ne, uint32_t *HWY_RESTRICT sum) { #if HWY_TARGET != HWY_SCALAR - const auto l1 = lskip / sizeof(uint8_t); +#if !defined(HAVE_HWY_1_1_0) && \ + (HWY_ARCH_RVV || (HWY_ARCH_ARM_A64 && HWY_TARGET <= HWY_SVE)) + /* Ensure we do not cross 128-bit block boundaries on RVV/SVE. + */ + const int32_t N = 8; +#else + const int32_t N = Lanes(du16); +#endif + const auto zero = Zero(du16); + auto *HWY_RESTRICT p = (uint8_t *) pin; + + /* Main sum loop: unrolled. + */ + int32_t x = 0; + for (; x + N <= ne; x += N) { + auto pix0 = PromoteTo(du16, LoadU(du8x16, p + x)); + + auto sum0 = LoadU(du32, &sum[x + 0 * N / 2]); + auto sum1 = LoadU(du32, &sum[x + 1 * N / 2]); + + sum0 = Add(sum0, BitCast(du32, InterleaveLower(du16, pix0, zero))); + sum1 = Add(sum1, BitCast(du32, InterleaveUpper(du16, pix0, zero))); + + StoreU(sum0, du32, &sum[x + 0 * N / 2]); + StoreU(sum1, du32, &sum[x + 1 * N / 2]); + } + + /* `ne` was not a multiple of the vector length `N`; + * proceed one by one. + */ + for (; x < ne; ++x) + sum[x] += p[x]; +#endif +} + +HWY_ATTR void +vips_shrinkv_write_line_uchar_hwy(VipsPel *pout, + int32_t ne, int32_t vshrink, uint32_t *HWY_RESTRICT sum) +{ +#if HWY_TARGET != HWY_SCALAR #if !defined(HAVE_HWY_1_1_0) && \ (HWY_ARCH_RVV || (HWY_ARCH_ARM_A64 && HWY_TARGET <= HWY_SVE)) /* Ensure we do not cross 128-bit block boundaries on RVV/SVE. @@ -93,39 +132,20 @@ vips_shrinkv_uchar_hwy(VipsPel *pout, VipsPel *pin, const uint32_t multiplier = max_uint32 / (max_bits * vshrink); const uint32_t amend = vshrink / 2; - const auto zero = Zero(du16); const auto multiplier_v = Set(du32, multiplier); const auto amend_v = Set(du32, amend); - /* Main loop: unrolled. + /* Main write loop: unrolled. */ int32_t x = 0; for (; x + N <= ne; x += N) { - auto *HWY_RESTRICT p = (uint8_t *) pin + x; auto *HWY_RESTRICT q = (uint8_t *) pout + x; - auto sum0 = amend_v; - auto sum1 = amend_v; - - int32_t yy = 0; - for (; yy + 2 <= vshrink; yy += 2) { - auto pix0 = PromoteTo(du16, LoadU(du8x16, p)); - p += l1; - auto pix1 = PromoteTo(du16, LoadU(du8x16, p)); - p += l1; - - pix0 = Add(pix0, pix1); - - sum0 = Add(sum0, BitCast(du32, InterleaveLower(du16, pix0, zero))); - sum1 = Add(sum1, BitCast(du32, InterleaveUpper(du16, pix0, zero))); - } - for (; yy < vshrink; ++yy) { - auto pix0 = PromoteTo(du16, LoadU(du8x16, p)); - p += l1; + auto sum0 = LoadU(du32, &sum[x + 0 * N / 2]); + auto sum1 = LoadU(du32, &sum[x + 1 * N / 2]); - sum0 = Add(sum0, BitCast(du32, InterleaveLower(du16, pix0, zero))); - sum1 = Add(sum1, BitCast(du32, InterleaveUpper(du16, pix0, zero))); - } + sum0 = Add(sum0, amend_v); + sum1 = Add(sum1, amend_v); sum0 = Mul(sum0, multiplier_v); sum1 = Mul(sum1, multiplier_v); @@ -156,28 +176,9 @@ vips_shrinkv_uchar_hwy(VipsPel *pout, VipsPel *pin, * proceed one by one. */ for (; x < ne; ++x) { - auto *HWY_RESTRICT p = (uint8_t *) pin + x; auto *HWY_RESTRICT q = (uint8_t *) pout + x; - uint32_t sum = amend; - - int32_t yy = 0; - for (; yy + 2 <= vshrink; yy += 2) { - auto pix0 = *p; - p += l1; - auto pix1 = *p; - p += l1; - - sum += pix0 + pix1; - } - for (; yy < vshrink; ++yy) { - auto pix0 = *p; - p += l1; - - sum += pix0; - } - - *q = (sum * multiplier) >> 24; + *q = ((sum[x] + amend) * multiplier) >> 24; } #endif } @@ -188,15 +189,26 @@ vips_shrinkv_uchar_hwy(VipsPel *pout, VipsPel *pin, } /*namespace HWY_NAMESPACE*/ #if HWY_ONCE -HWY_EXPORT(vips_shrinkv_uchar_hwy); +HWY_EXPORT(vips_shrinkv_add_line_uchar_hwy); +HWY_EXPORT(vips_shrinkv_write_line_uchar_hwy); + +void +vips_shrinkv_add_line_uchar_hwy(VipsPel *pin, + int ne, unsigned int *restrict sum) +{ + /* clang-format off */ + HWY_DYNAMIC_DISPATCH(vips_shrinkv_add_line_uchar_hwy)(pin, + ne, sum); + /* clang-format on */ +} void -vips_shrinkv_uchar_hwy(VipsPel *pout, VipsPel *pin, - int ne, int vshrink, int lskip) +vips_shrinkv_write_line_uchar_hwy(VipsPel *pout, + int ne, int vshrink, unsigned int *restrict sum) { /* clang-format off */ - HWY_DYNAMIC_DISPATCH(vips_shrinkv_uchar_hwy)(pout, pin, - ne, vshrink, lskip); + HWY_DYNAMIC_DISPATCH(vips_shrinkv_write_line_uchar_hwy)(pout, + ne, vshrink, sum); /* clang-format on */ } #endif /*HWY_ONCE*/ From 8e54323a549a9ccbb578a8074a4e7d0b35cd9139 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 10 May 2025 17:01:03 +0200 Subject: [PATCH 172/174] cache: minor improvements (#4493) * cache: prefer use of `g_hash_table_new_full()` * cache: avoid unnecessary cache entry lookups --- libvips/iofuncs/cache.c | 217 ++++++++++++++++------------------------ 1 file changed, 86 insertions(+), 131 deletions(-) diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index bb3a9fa00d..0a23084d8b 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -131,7 +131,7 @@ typedef struct _VipsOperationCacheEntry { * VipsImage. generics are much faster to compare. */ static unsigned int -vips_value_hash(GParamSpec *pspec, GValue *value) +vips_value_hash(GParamSpec *pspec, const GValue *value) { GType generic = G_PARAM_SPEC_TYPE(pspec); @@ -227,7 +227,7 @@ vips_value_hash(GParamSpec *pspec, GValue *value) * could be of type VipsImage. generics are much faster to compare. */ static gboolean -vips_value_equal(GParamSpec *pspec, GValue *v1, GValue *v2) +vips_value_equal(GParamSpec *pspec, const GValue *v1, const GValue *v2) { GType generic = G_PARAM_SPEC_TYPE(pspec); GType t1 = G_VALUE_TYPE(v1); @@ -335,7 +335,7 @@ vips_object_hash_arg(VipsObject *object, return NULL; } -/* Find a hash from the input arguments to a VipsOperstion. +/* Find a hash from the input arguments to a VipsOperation. */ unsigned int vips_operation_hash(VipsOperation *operation) @@ -468,12 +468,67 @@ vips_operation_copy(VipsOperation *operation) return new; } +static void * +vips_object_unref_arg(VipsObject *object, + GParamSpec *pspec, + VipsArgumentClass *argument_class, + VipsArgumentInstance *argument_instance, + void *a, void *b) +{ + if ((argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && + (argument_class->flags & VIPS_ARGUMENT_OUTPUT) && + argument_instance->assigned && + G_IS_PARAM_SPEC_OBJECT(pspec)) { + GObject *value; + + /* This will up the ref count for us. + */ + g_object_get(G_OBJECT(object), + g_param_spec_get_name(pspec), &value, NULL); + + /* This operation is probably going, so we must wipe the cache + * entry pointer on the object. + */ + g_object_set_data(value, "libvips-cache-entry", NULL); + + /* Drop the ref we just got, then drop the ref we make when we + * added to the cache. + */ + g_object_unref(value); + g_object_unref(value); + } + + return NULL; +} + +static void +vips_cache_free_cb(VipsOperationCacheEntry *entry) +{ +#ifdef DEBUG + printf("vips_cache_free_cb: "); + vips_object_print_summary(VIPS_OBJECT(entry->operation)); +#endif /*DEBUG*/ + + if (entry->invalidate_id) { + g_signal_handler_disconnect(entry->operation, entry->invalidate_id); + entry->invalidate_id = 0; + } + + (void) vips_argument_map(VIPS_OBJECT(entry->operation), + vips_object_unref_arg, NULL, NULL); + g_object_unref(entry->operation); + + g_free(entry); +} + void * vips__cache_once_init(void *data) { - vips_cache_table = g_hash_table_new( + vips_cache_table = g_hash_table_new_full( (GHashFunc) vips_operation_hash, - (GEqualFunc) vips_operation_equal); + (GEqualFunc) vips_operation_equal, + NULL, + (GDestroyNotify) vips_cache_free_cb); return NULL; } @@ -526,52 +581,6 @@ vips_cache_print(void) g_mutex_unlock(&vips_cache_lock); } -static void * -vips_object_unref_arg(VipsObject *object, - GParamSpec *pspec, - VipsArgumentClass *argument_class, - VipsArgumentInstance *argument_instance, - void *a, void *b) -{ - if ((argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && - (argument_class->flags & VIPS_ARGUMENT_OUTPUT) && - argument_instance->assigned && - G_IS_PARAM_SPEC_OBJECT(pspec)) { - GObject *value; - - /* This will up the ref count for us. - */ - g_object_get(G_OBJECT(object), - g_param_spec_get_name(pspec), &value, NULL); - - /* This operation is probably going, so we must wipe the operation - * pointer on the object. - */ - g_object_set_data(value, "libvips-operation", NULL); - - /* Drop the ref we just got, then drop the ref we make when we - * added to the cache. - */ - g_object_unref(value); - g_object_unref(value); - } - - return NULL; -} - -static void -vips_cache_unref(VipsOperation *operation) -{ -#ifdef DEBUG - printf("vips_cache_unref: "); - vips_object_print_summary(VIPS_OBJECT(operation)); -#endif /*DEBUG*/ - - (void) vips_argument_map(VIPS_OBJECT(operation), - vips_object_unref_arg, operation, NULL); - g_object_unref(operation); -} - static VipsOperationCacheEntry * vips_cache_operation_get(VipsOperation *operation) { @@ -583,24 +592,7 @@ vips_cache_operation_get(VipsOperation *operation) static void vips_cache_remove(VipsOperation *operation) { - VipsOperationCacheEntry *entry = vips_cache_operation_get(operation); - -#ifdef DEBUG - printf("vips_cache_remove: "); - vips_object_print_summary(VIPS_OBJECT(operation)); -#endif /*DEBUG*/ - - g_assert(entry); - - if (entry->invalidate_id) { - g_signal_handler_disconnect(operation, entry->invalidate_id); - entry->invalidate_id = 0; - } - g_hash_table_remove(vips_cache_table, operation); - vips_cache_unref(operation); - - g_free(entry); } static void * @@ -610,7 +602,7 @@ vips_object_ref_arg(VipsObject *object, VipsArgumentInstance *argument_instance, void *a, void *b) { - VipsOperation *operation = VIPS_OPERATION(a); + VipsOperationCacheEntry *entry = a; if ((argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) && (argument_class->flags & VIPS_ARGUMENT_OUTPUT) && @@ -623,19 +615,17 @@ vips_object_ref_arg(VipsObject *object, g_object_get(G_OBJECT(object), g_param_spec_get_name(pspec), &value, NULL); - /* This object has been made by this operation. + /* This object has been made by this cache entry. */ - g_object_set_data(value, "libvips-operation", operation); + g_object_set_data(value, "libvips-cache-entry", entry); } return NULL; } static void -vips_operation_touch_operation(VipsOperation *operation) +vips_entry_touch(VipsOperationCacheEntry *entry) { - VipsOperationCacheEntry *entry = vips_cache_operation_get(operation); - /* Don't up the time for invalid items -- we want them to fall out of * cache. */ @@ -646,11 +636,11 @@ vips_operation_touch_operation(VipsOperation *operation) static void * vips_image_touch_cb(VipsImage *image, void *a, void *b) { - VipsOperation *operation = - VIPS_OPERATION(g_object_get_data(G_OBJECT(image), "libvips-operation")); + VipsOperationCacheEntry *entry = + g_object_get_data(G_OBJECT(image), "libvips-cache-entry"); - if (operation) - vips_operation_touch_operation(operation); + if (entry) + vips_entry_touch(entry); return NULL; } @@ -680,37 +670,31 @@ vips_object_touch_arg(VipsObject *object, return NULL; } -static void -vips_operation_touch(VipsOperation *operation) -{ - vips_cache_time += 1; - - /* Touch the operations on the upstream trees on all input images. - */ - (void) vips_argument_map(VIPS_OBJECT(operation), - vips_object_touch_arg, NULL, NULL); - - /* And this operation. - */ - vips_operation_touch_operation(operation); -} - /* Ref an operation for the cache. The operation itself, plus all the output * objects it makes. */ static void -vips_cache_ref(VipsOperation *operation) +vips_entry_ref(VipsOperationCacheEntry *entry) { #ifdef DEBUG printf("vips_cache_ref: "); - vips_object_print_summary(VIPS_OBJECT(operation)); + vips_object_print_summary(VIPS_OBJECT(entry->operation)); #endif /*DEBUG*/ - g_object_ref(operation); - (void) vips_argument_map(VIPS_OBJECT(operation), - vips_object_ref_arg, operation, NULL); + g_object_ref(entry->operation); + (void) vips_argument_map(VIPS_OBJECT(entry->operation), + vips_object_ref_arg, entry, NULL); + + vips_cache_time += 1; + + /* Touch the cache entries on the upstream trees on all input images. + */ + (void) vips_argument_map(VIPS_OBJECT(entry->operation), + vips_object_touch_arg, NULL, NULL); - vips_operation_touch(operation); + /* And this entry. + */ + vips_entry_touch(entry); } static void @@ -741,7 +725,7 @@ vips_cache_insert(VipsOperation *operation) entry->invalid = FALSE; g_hash_table_insert(vips_cache_table, operation, entry); - vips_cache_ref(operation); + vips_entry_ref(entry); /* If the operation signals "invalidate", we must tag this cache entry * for removal. @@ -750,27 +734,6 @@ vips_cache_insert(VipsOperation *operation) G_CALLBACK(vips_cache_invalidate_cb), entry); } -static void * -vips_cache_get_first_fn(void *value, void *a, void *b) -{ - return value; -} - -/* Return the first item. - */ -static VipsOperation * -vips_cache_get_first(void) -{ - VipsOperationCacheEntry *entry; - - if (vips_cache_table && - (entry = vips_hash_table_map(vips_cache_table, - vips_cache_get_first_fn, NULL, NULL))) - return VIPS_OPERATION(entry->operation); - - return NULL; -} - /** * vips_cache_drop_all: * @@ -787,18 +750,10 @@ vips_cache_drop_all(void) g_mutex_lock(&vips_cache_lock); if (vips_cache_table) { - VipsOperation *operation; - if (vips__cache_dump) vips_cache_print_nolock(); - /* We can't modify the hash in the callback from - * g_hash_table_foreach() and friends. Repeatedly drop the - * first item instead. - */ - while ((operation = vips_cache_get_first())) - vips_cache_remove(operation); - + g_hash_table_remove_all(vips_cache_table); VIPS_FREEF(g_hash_table_unref, vips_cache_table); } @@ -919,7 +874,7 @@ vips_cache_operation_buildp(VipsOperation **operation) * passed. */ if (hit) { - vips_cache_ref(hit->operation); + vips_entry_ref(hit); g_object_unref(*operation); *operation = hit->operation; From d7f4b036a328d0faba54913320d0d83ed0a553fc Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 10 May 2025 16:02:12 +0100 Subject: [PATCH 173/174] another missed doc comment sigh --- libvips/iofuncs/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index bb3a9fa00d..d8bf6a57e2 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -775,7 +775,7 @@ vips_cache_get_first(void) * vips_cache_drop_all: * * Drop the whole operation cache, handy for leak tracking. Also called - * automatically on [func@shutdown]. + * automatically on vips_shutdown(). */ void vips_cache_drop_all(void) From 32401e933a6185874116647d72decb1f7dc84e8e Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 10 May 2025 16:33:06 +0100 Subject: [PATCH 174/174] Revert "another missed doc comment sigh" This reverts commit d7f4b036a328d0faba54913320d0d83ed0a553fc. --- libvips/iofuncs/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libvips/iofuncs/cache.c b/libvips/iofuncs/cache.c index f168e8579e..0a23084d8b 100644 --- a/libvips/iofuncs/cache.c +++ b/libvips/iofuncs/cache.c @@ -738,7 +738,7 @@ vips_cache_insert(VipsOperation *operation) * vips_cache_drop_all: * * Drop the whole operation cache, handy for leak tracking. Also called - * automatically on vips_shutdown(). + * automatically on [func@shutdown]. */ void vips_cache_drop_all(void)