From 6efc71df06b59a17bcc5d121e12b1f3bc608152e Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 10 Oct 2024 17:53:11 +0200 Subject: [PATCH 01/65] cplusplus: add `VImage::rawsave_fd` compat function (#4189) * cplusplus: add `VImage::rawsave_fd` compat function Add a C++ compat function for `vips_rawsave_fd()` after the GObject class removal in commit 067b9f5. * Remove redundant `this->` --- cplusplus/VImage.cpp | 8 ++++++++ cplusplus/include/vips/VImage8.h | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/cplusplus/VImage.cpp b/cplusplus/VImage.cpp index 8133e09c19..e2a060e998 100644 --- a/cplusplus/VImage.cpp +++ b/cplusplus/VImage.cpp @@ -1592,4 +1592,12 @@ operator>>=(VImage &a, const std::vector b) return a; } +// Compat operations + +void +VImage::rawsave_fd(int fd, VOption *options) const +{ + rawsave_target(VTarget::new_to_descriptor(fd), options); +} + VIPS_NAMESPACE_END diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h index bcc0ac4f18..f58f9278c3 100644 --- a/cplusplus/include/vips/VImage8.h +++ b/cplusplus/include/vips/VImage8.h @@ -2048,6 +2048,23 @@ class VImage : public VObject { friend VIPS_CPLUSPLUS_API VImage & operator>>=(VImage &a, const std::vector b); + // Compat operations + + /** + * Write raw image to file descriptor. + * + * **Optional parameters** + * - **keep** -- Which metadata to retain, VipsForeignKeep. + * - **background** -- Background value, std::vector. + * - **page_height** -- Set page height for multipage save, int. + * - **profile** -- Filename of ICC profile to embed, const char *. + * + * @param fd File descriptor to write to. + * @param options Set of options. + */ + G_DEPRECATED_FOR(rawsave_target) + void rawsave_fd(int fd, VOption *options = nullptr) const; + /* Automatically generated members. * * Rebuild with: From b1ed120e7fdcabdcd4d4c01ef8f40ead25684b3f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 10 Oct 2024 17:13:18 +0100 Subject: [PATCH 02/65] remove vips_cache() from the docs --- doc/function-list.old | 1662 +++++++++++++++++++++++++++++++++++++++++ doc/function-list.xml | 27 +- 2 files changed, 1673 insertions(+), 16 deletions(-) create mode 100644 doc/function-list.old diff --git a/doc/function-list.old b/doc/function-list.old new file mode 100644 index 0000000000..49db3bfd42 --- /dev/null +++ b/doc/function-list.old @@ -0,0 +1,1662 @@ + + + + + + VIPS function list + 3 + VIPS Library + + + + Using VIPS + List of VIPS functions and operators + + + + Function list + + 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. + + + + + VIPS functions and operators + + + + 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() + + + cache + Cache an image + vips_cache() + + + 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/function-list.xml b/doc/function-list.xml index 49db3bfd42..3699839199 100644 --- a/doc/function-list.xml +++ b/doc/function-list.xml @@ -1,5 +1,5 @@ - + @@ -18,13 +18,13 @@ Function list - 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. + 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 + From the command-line, C++ and most language bindings, you use the nickname to call the operator. For example in C++: @@ -38,7 +38,7 @@ fred = jim.gamma() - VIPS has a set of C wrapper functions for calling operators, in this + VIPS has a set of C wrapper functions for calling operators, in this case vips_gamma(): @@ -46,15 +46,15 @@ VipsImage *jim; if (vips_gamma(fred, &jim, NULL)) - ...error; + ...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 + 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. @@ -266,11 +266,6 @@ Byteswap an image vips_byteswap() - - cache - Cache an image - vips_cache() - canny Canny edge detector From 0ed4f89d0d92cdc0adaa483afcfa31765a54c61b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 10 Oct 2024 17:13:52 +0100 Subject: [PATCH 03/65] oops --- doc/function-list.old | 1662 ----------------------------------------- 1 file changed, 1662 deletions(-) delete mode 100644 doc/function-list.old diff --git a/doc/function-list.old b/doc/function-list.old deleted file mode 100644 index 49db3bfd42..0000000000 --- a/doc/function-list.old +++ /dev/null @@ -1,1662 +0,0 @@ - - - - - - VIPS function list - 3 - VIPS Library - - - - Using VIPS - List of VIPS functions and operators - - - - Function list - - 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. - - - - - VIPS functions and operators - - - - 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() - - - cache - Cache an image - vips_cache() - - - 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() - - - - -
-
- -
- -
From 8f03a101f57e76dd539b67b57d39df6a8b69666e Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 10 Oct 2024 17:29:14 +0100 Subject: [PATCH 04/65] regen dev checklist --- doc/Developer-checklist.xml | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/doc/Developer-checklist.xml b/doc/Developer-checklist.xml index c046f8a84f..c4227e7ecf 100644 --- a/doc/Developer-checklist.xml +++ b/doc/Developer-checklist.xml @@ -16,7 +16,7 @@ If you can, use <literal>thumbnail</literal>, not <literal>resize</literal> - 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 drop in memory use. + 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: @@ -40,7 +40,7 @@ $ /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: + 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 @@ -65,21 +65,30 @@ $ /usr/bin/time -f %M:%e vips > /dev/null 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. + See the How it opens files chapter for background on this feature. Use longer pipelines if you can - 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 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. + 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. + + Cache commonly reused images + + 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. + + Adjust the order of operations in pipelines @@ -120,7 +129,7 @@ $ /usr/bin/time -f %M:%e vips > /dev/null Check for interlaced (also called progressive) images. - These are the ones that appear at a low res first, then slowly fill in detail as they are downloaded. + 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: @@ -156,7 +165,7 @@ $ /usr/bin/time -f %M:%e vipsthumbnail x.jpg Disable the libvips operation cache if you don’t need it - 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);. + 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);. From 1a21cba39f68843bbe5548c1d1700a60607501d3 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 11 Oct 2024 15:59:48 +0200 Subject: [PATCH 05/65] cplusplus: add `VImage::new_from_memory_steal` compat function (#4195) --- cplusplus/VImage.cpp | 10 +++++++++- cplusplus/include/vips/VImage8.h | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cplusplus/VImage.cpp b/cplusplus/VImage.cpp index e2a060e998..b1961722a5 100644 --- a/cplusplus/VImage.cpp +++ b/cplusplus/VImage.cpp @@ -647,7 +647,7 @@ VImage::new_from_memory_steal(const void *data, size_t size, throw(VError()); g_signal_connect(image, "postclose", - G_CALLBACK(vips_image_free_buffer), (void *) data); + G_CALLBACK(vips_image_free_buffer), const_cast(data)); return VImage(image); } @@ -1594,6 +1594,14 @@ operator>>=(VImage &a, const std::vector b) // Compat operations +VImage +VImage::new_from_memory_steal(void *data, size_t size, + int width, int height, int bands, VipsBandFormat format) +{ + return new_from_memory_steal(static_cast(data), size, + width, height, bands, format); +} + void VImage::rawsave_fd(int fd, VOption *options) const { diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h index f58f9278c3..4d61d9b168 100644 --- a/cplusplus/include/vips/VImage8.h +++ b/cplusplus/include/vips/VImage8.h @@ -2050,6 +2050,10 @@ class VImage : public VObject { // Compat operations + static VImage + new_from_memory_steal(void *data, size_t size, + int width, int height, int bands, VipsBandFormat format); + /** * Write raw image to file descriptor. * From 19b499db490796b6ed7de195578ec87ece3eb050 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Fri, 11 Oct 2024 15:04:45 +0100 Subject: [PATCH 06/65] heifsave: check availability of heif_encoder_parameter_get_valid_integer_values (#4194) --- libvips/foreign/heifsave.c | 2 ++ meson.build | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index 017e50e4c1..722fb5c2fc 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -620,6 +620,7 @@ vips_foreign_save_heif_build(VipsObject *object) return -1; } +#ifdef HAVE_HEIF_ENCODER_PARAMETER_GET_VALID_INTEGER_VALUES for (param = heif_encoder_list_parameters(heif->encoder); *param; param++) { int have_minimum; @@ -645,6 +646,7 @@ vips_foreign_save_heif_build(VipsObject *object) return -1; } } +#endif /*HAVE_HEIF_ENCODER_PARAMETER_GET_VALID_INTEGER_VALUES*/ /* TODO .. support extra per-encoder params with * heif_encoder_list_parameters(). diff --git a/meson.build b/meson.build index e23357259e..8a7be996f0 100644 --- a/meson.build +++ b/meson.build @@ -548,6 +548,10 @@ if libheif_dep.found() if libheif_dep.version().version_compare('>=1.7.0') cfg_var.set('HAVE_HEIF_AVIF', '1') endif + # 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 # 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') From 199f024c0db0cf015a9e51e463457d9bbed03f57 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Fri, 11 Oct 2024 16:32:44 +0100 Subject: [PATCH 07/65] heifsave: expose libheif/aom auto_tiles feature (#4191) Allows the aom encoder to determine the optimum tile count based on the output dimensions and available threads. This can improve multi-core utilisation, reducing processing time and/or memory usage at the cost of slightly increased file sizes. --- cplusplus/include/vips/VImage8.h | 3 +++ libvips/foreign/foreign.c | 8 ++++++++ libvips/foreign/heifsave.c | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h index 4d61d9b168..56876c17fb 100644 --- a/cplusplus/include/vips/VImage8.h +++ b/cplusplus/include/vips/VImage8.h @@ -3446,6 +3446,7 @@ class VImage : public VObject { * - **effort** -- CPU effort, int. * - **subsample_mode** -- Select chroma subsample operation mode, VipsForeignSubsample. * - **encoder** -- Select encoder to use, VipsForeignHeifEncoder. + * - **auto_tiles** -- Determine optimum tile count, bool. * - **keep** -- Which metadata to retain, VipsForeignKeep. * - **background** -- Background value, std::vector. * - **page_height** -- Set page height for multipage save, int. @@ -3467,6 +3468,7 @@ class VImage : public VObject { * - **effort** -- CPU effort, int. * - **subsample_mode** -- Select chroma subsample operation mode, VipsForeignSubsample. * - **encoder** -- Select encoder to use, VipsForeignHeifEncoder. + * - **auto_tiles** -- Determine optimum tile count, bool. * - **keep** -- Which metadata to retain, VipsForeignKeep. * - **background** -- Background value, std::vector. * - **page_height** -- Set page height for multipage save, int. @@ -3488,6 +3490,7 @@ class VImage : public VObject { * - **effort** -- CPU effort, int. * - **subsample_mode** -- Select chroma subsample operation mode, VipsForeignSubsample. * - **encoder** -- Select encoder to use, VipsForeignHeifEncoder. + * - **auto_tiles** -- Determine optimum tile count, bool. * - **keep** -- Which metadata to retain, VipsForeignKeep. * - **background** -- Background value, std::vector. * - **page_height** -- Set page height for multipage save, int. diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index acc1a74097..5bcefdf81a 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -2366,6 +2366,7 @@ vips_heifload_source(VipsSource *source, VipsImage **out, ...) * * @effort: %gint, encoding effort * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode * * @encoder: #VipsForeignHeifEncoder, select encoder to use + * * @auto_tiles: %gboolean, determine optimum tile count * * Write a VIPS image to a file in HEIF format. * @@ -2389,6 +2390,11 @@ vips_heifload_source(VipsSource *source, VipsImage **out, ...) * * Use @encoder to set the encode library to use, e.g. aom, SVT-AV1, rav1e etc. * + * When using the aom encoder, set @auto_tiles to determine the optimum + * number of tiles based on dimensions and available threads. This can + * improve multi-core utilisation and/or reduce peak memory consumption + * at the expense of slightly increased file size. + * * See also: vips_image_write_to_file(), vips_heifload(). * * Returns: 0 on success, -1 on error. @@ -2422,6 +2428,7 @@ vips_heifsave(VipsImage *in, const char *filename, ...) * * @effort: %gint, encoding effort * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode * * @encoder: #VipsForeignHeifEncoder, select encoder to use + * * @auto_tiles: %gboolean, determine optimum tile count * * As vips_heifsave(), but save to a memory buffer. * @@ -2476,6 +2483,7 @@ vips_heifsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * * @effort: %gint, encoding effort * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode * * @encoder: #VipsForeignHeifEncoder, select encoder to use + * * @auto_tiles: %gboolean, determine optimum tile count * * As vips_heifsave(), but save to a target. * diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index 722fb5c2fc..9ba5bc96df 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -130,6 +130,10 @@ typedef struct _VipsForeignSaveHeif { */ int speed; + /* Auto tiles (currently aom only). + */ + gboolean auto_tiles; + } VipsForeignSaveHeif; typedef VipsForeignSaveClass VipsForeignSaveHeifClass; @@ -648,6 +652,14 @@ vips_foreign_save_heif_build(VipsObject *object) } #endif /*HAVE_HEIF_ENCODER_PARAMETER_GET_VALID_INTEGER_VALUES*/ + error = heif_encoder_set_parameter_boolean(heif->encoder, + "auto-tiles", heif->auto_tiles); + 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(). */ @@ -807,6 +819,13 @@ vips_foreign_save_heif_class_init(VipsForeignSaveHeifClass *class) G_STRUCT_OFFSET(VipsForeignSaveHeif, selected_encoder), VIPS_TYPE_FOREIGN_HEIF_ENCODER, VIPS_FOREIGN_HEIF_ENCODER_AUTO); + + VIPS_ARG_BOOL(class, "auto_tiles", 19, + _("Auto-tiles"), + _("Determine optimum tile count"), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET(VipsForeignSaveHeif, auto_tiles), + FALSE); } static void From 7b87d3d91184337d3beef73723d4a5ad922b2d3d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 11 Oct 2024 16:34:09 +0100 Subject: [PATCH 08/65] note auto_tiles for heifsave --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 3c97948cbf..38977c343e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,7 @@ master 8.16 - add "unpack_complex" option to vips_getpoint() - add deflate compression level setting to tiffsave [ruven] - add "smart_deblock" to webpsave [goodusername123] +- add "auto_files" to heifsave [lovell] 4/10/24 8.15.5 From 7ce8ded142e8e71a34026d5d9da63529142148e3 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Fri, 11 Oct 2024 20:23:58 +0200 Subject: [PATCH 09/65] avoid direct include of almostdeprecated.h (#4196) * avoid direct include of almostdeprecated.h * typo --- libvips/include/vips/almostdeprecated.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libvips/include/vips/almostdeprecated.h b/libvips/include/vips/almostdeprecated.h index 10400c7dce..e18cb26bde 100644 --- a/libvips/include/vips/almostdeprecated.h +++ b/libvips/include/vips/almostdeprecated.h @@ -35,6 +35,10 @@ #ifndef IM_ALMOSTDEPRECATED_H #define IM_ALMOSTDEPRECATED_H +#ifndef VIPS_VIPS7COMPAT_H +#error Should not be included directly use vips7compat.h instead +#endif + #ifdef __cplusplus extern "C" { #endif /*__cplusplus*/ From 71d356b259e7ba8a4efc2edf1d1200e823d81e82 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 12 Oct 2024 11:28:30 +0200 Subject: [PATCH 10/65] Make `vips7compat.h` part of `vips.h` (#4197) This automatically includes `vips7compat.h` unless building with `-Ddeprecated=false`, preventing unexpected API breaks. --- libvips/conversion/cache.c | 6 ---- libvips/deprecated/arith_dispatch.c | 1 - libvips/deprecated/cimg_dispatch.c | 1 - libvips/deprecated/colour_dispatch.c | 1 - libvips/deprecated/conver_dispatch.c | 1 - libvips/deprecated/convol_dispatch.c | 1 - libvips/deprecated/cooc_funcs.c | 1 - libvips/deprecated/deprecated_dispatch.c | 1 - libvips/deprecated/dispatch_types.c | 1 - libvips/deprecated/fits.c | 1 - libvips/deprecated/format.c | 1 - libvips/deprecated/format_dispatch.c | 1 - libvips/deprecated/freq_dispatch.c | 1 - libvips/deprecated/glds_funcs.c | 1 - libvips/deprecated/hist_dispatch.c | 1 - libvips/deprecated/im_align_bands.c | 1 - libvips/deprecated/im_analyze2vips.c | 1 - libvips/deprecated/im_benchmark.c | 1 - libvips/deprecated/im_bernd.c | 1 - libvips/deprecated/im_clamp.c | 1 - libvips/deprecated/im_cmulnorm.c | 1 - libvips/deprecated/im_convsub.c | 1 - libvips/deprecated/im_csv2vips.c | 1 - libvips/deprecated/im_debugim.c | 1 - libvips/deprecated/im_dif_std.c | 1 - libvips/deprecated/im_exr2vips.c | 1 - libvips/deprecated/im_fav4.c | 1 - libvips/deprecated/im_freq_mask.c | 1 - libvips/deprecated/im_gadd.c | 1 - libvips/deprecated/im_gaddim.c | 1 - libvips/deprecated/im_gfadd.c | 1 - libvips/deprecated/im_gradcor.c | 1 - libvips/deprecated/im_jpeg2vips.c | 1 - libvips/deprecated/im_lab_morph.c | 1 - libvips/deprecated/im_line.c | 1 - libvips/deprecated/im_linreg.c | 1 - libvips/deprecated/im_litecor.c | 1 - libvips/deprecated/im_magick2vips.c | 1 - libvips/deprecated/im_mask2vips.c | 1 - libvips/deprecated/im_matcat.c | 1 - libvips/deprecated/im_matinv.c | 1 - libvips/deprecated/im_matmul.c | 1 - libvips/deprecated/im_mattrn.c | 1 - libvips/deprecated/im_maxpos_avg.c | 1 - libvips/deprecated/im_maxpos_subpel.c | 1 - libvips/deprecated/im_measure.c | 1 - libvips/deprecated/im_nifti2vips.c | 1 - libvips/deprecated/im_openslide2vips.c | 1 - libvips/deprecated/im_png2vips.c | 1 - libvips/deprecated/im_point_bilinear.c | 1 - libvips/deprecated/im_ppm2vips.c | 1 - libvips/deprecated/im_print.c | 1 - libvips/deprecated/im_printlines.c | 1 - libvips/deprecated/im_resize_linear.c | 1 - libvips/deprecated/im_setbox.c | 1 - libvips/deprecated/im_simcontr.c | 1 - libvips/deprecated/im_slice.c | 1 - libvips/deprecated/im_spatres.c | 1 - libvips/deprecated/im_stretch3.c | 1 - libvips/deprecated/im_thresh.c | 1 - libvips/deprecated/im_tiff2vips.c | 1 - libvips/deprecated/im_video_test.c | 1 - libvips/deprecated/im_vips2csv.c | 1 - libvips/deprecated/im_vips2dz.c | 1 - libvips/deprecated/im_vips2jpeg.c | 1 - libvips/deprecated/im_vips2mask.c | 1 - libvips/deprecated/im_vips2png.c | 1 - libvips/deprecated/im_vips2ppm.c | 1 - libvips/deprecated/im_vips2tiff.c | 1 - libvips/deprecated/im_vips2webp.c | 1 - libvips/deprecated/im_webp2vips.c | 1 - libvips/deprecated/im_zerox.c | 1 - libvips/deprecated/inplace_dispatch.c | 1 - libvips/deprecated/lazy.c | 1 - libvips/deprecated/mask_dispatch.c | 1 - libvips/deprecated/matalloc.c | 1 - libvips/deprecated/matlab.c | 1 - libvips/deprecated/morph_dispatch.c | 1 - libvips/deprecated/mosaicing_dispatch.c | 1 - libvips/deprecated/other_dispatch.c | 1 - libvips/deprecated/package.c | 1 - libvips/deprecated/radiance.c | 1 - libvips/deprecated/raw.c | 1 - libvips/deprecated/rename.c | 1 - libvips/deprecated/resample_dispatch.c | 1 - libvips/deprecated/rotmask.c | 1 - libvips/deprecated/rw_mask.c | 1 - libvips/deprecated/tone.c | 1 - libvips/deprecated/video_dispatch.c | 1 - libvips/deprecated/vips7compat.c | 1 - libvips/foreign/vipsload.c | 3 ++ libvips/foreign/vipssave.c | 3 ++ libvips/include/vips/enumtypes.c.in | 4 --- libvips/include/vips/internal.h | 39 ++++++------------------ libvips/include/vips/vips.h | 5 +-- libvips/include/vips/vips7compat.h | 3 ++ libvips/iofuncs/header.c | 6 ---- libvips/iofuncs/image.c | 1 + libvips/iofuncs/init.c | 4 --- tools/vips.c | 4 --- 100 files changed, 20 insertions(+), 147 deletions(-) diff --git a/libvips/conversion/cache.c b/libvips/conversion/cache.c index 070046dfe4..f7e6b57012 100644 --- a/libvips/conversion/cache.c +++ b/libvips/conversion/cache.c @@ -48,12 +48,6 @@ #include #include -/* For the vips_cache() header decl. - */ -#if ENABLE_DEPRECATED -#include -#endif - #include "pconversion.h" typedef struct _VipsCache { diff --git a/libvips/deprecated/arith_dispatch.c b/libvips/deprecated/arith_dispatch.c index de35dee78c..1e3bc1ab76 100644 --- a/libvips/deprecated/arith_dispatch.c +++ b/libvips/deprecated/arith_dispatch.c @@ -38,7 +38,6 @@ #include #include -#include /* One image in, one out. */ diff --git a/libvips/deprecated/cimg_dispatch.c b/libvips/deprecated/cimg_dispatch.c index 72c4249a7e..d88a23cda2 100644 --- a/libvips/deprecated/cimg_dispatch.c +++ b/libvips/deprecated/cimg_dispatch.c @@ -36,7 +36,6 @@ #include #include -#include static int greyc_vec(im_object *argv) diff --git a/libvips/deprecated/colour_dispatch.c b/libvips/deprecated/colour_dispatch.c index 827bbcba8c..9da5edd3e5 100644 --- a/libvips/deprecated/colour_dispatch.c +++ b/libvips/deprecated/colour_dispatch.c @@ -38,7 +38,6 @@ #include #include -#include /* One image in, one out. */ diff --git a/libvips/deprecated/conver_dispatch.c b/libvips/deprecated/conver_dispatch.c index 8bdfb74be9..2a95ceb137 100644 --- a/libvips/deprecated/conver_dispatch.c +++ b/libvips/deprecated/conver_dispatch.c @@ -36,7 +36,6 @@ #include #include -#include static int system_vec(im_object *argv) diff --git a/libvips/deprecated/convol_dispatch.c b/libvips/deprecated/convol_dispatch.c index de772acd74..367c54264d 100644 --- a/libvips/deprecated/convol_dispatch.c +++ b/libvips/deprecated/convol_dispatch.c @@ -38,7 +38,6 @@ #include #include -#include /* One image in, one out. */ diff --git a/libvips/deprecated/cooc_funcs.c b/libvips/deprecated/cooc_funcs.c index 9ec5ffc0c7..13e3d245dd 100644 --- a/libvips/deprecated/cooc_funcs.c +++ b/libvips/deprecated/cooc_funcs.c @@ -75,7 +75,6 @@ #include #include -#include static int im_cooc_sym(IMAGE *im, IMAGE *m, int xpos, int ypos, int xsize, int ysize, int dx, int dy) diff --git a/libvips/deprecated/deprecated_dispatch.c b/libvips/deprecated/deprecated_dispatch.c index 061165e7c7..b7a046641d 100644 --- a/libvips/deprecated/deprecated_dispatch.c +++ b/libvips/deprecated/deprecated_dispatch.c @@ -36,7 +36,6 @@ #include #include -#include #include /* One image in, one out. diff --git a/libvips/deprecated/dispatch_types.c b/libvips/deprecated/dispatch_types.c index e5b108b6a3..ecbab9c67b 100644 --- a/libvips/deprecated/dispatch_types.c +++ b/libvips/deprecated/dispatch_types.c @@ -47,7 +47,6 @@ #include #include -#include #include /* String containing each of the characters which can be used within a diff --git a/libvips/deprecated/fits.c b/libvips/deprecated/fits.c index 56462de7ae..7038ac104a 100644 --- a/libvips/deprecated/fits.c +++ b/libvips/deprecated/fits.c @@ -41,7 +41,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/format.c b/libvips/deprecated/format.c index bf92aac9d5..877848672d 100644 --- a/libvips/deprecated/format.c +++ b/libvips/deprecated/format.c @@ -36,7 +36,6 @@ #include #include -#include #include /* To iterate over supported formats, we build a temp list of subclasses of diff --git a/libvips/deprecated/format_dispatch.c b/libvips/deprecated/format_dispatch.c index e7f726d582..a886c6f688 100644 --- a/libvips/deprecated/format_dispatch.c +++ b/libvips/deprecated/format_dispatch.c @@ -36,7 +36,6 @@ #include #include -#include static int jpeg2vips_vec(im_object *argv) diff --git a/libvips/deprecated/freq_dispatch.c b/libvips/deprecated/freq_dispatch.c index 9381150cac..2deb92c407 100644 --- a/libvips/deprecated/freq_dispatch.c +++ b/libvips/deprecated/freq_dispatch.c @@ -41,7 +41,6 @@ #include #include -#include /* One image in, one out. */ diff --git a/libvips/deprecated/glds_funcs.c b/libvips/deprecated/glds_funcs.c index 4358a56d7a..7f3b8af329 100644 --- a/libvips/deprecated/glds_funcs.c +++ b/libvips/deprecated/glds_funcs.c @@ -72,7 +72,6 @@ #include #include -#include /* Keep the greylevel difference matrix as a 256x1 double image */ diff --git a/libvips/deprecated/hist_dispatch.c b/libvips/deprecated/hist_dispatch.c index e22e6d6fc2..a08adb811e 100644 --- a/libvips/deprecated/hist_dispatch.c +++ b/libvips/deprecated/hist_dispatch.c @@ -38,7 +38,6 @@ #include #include -#include /* One image in, one out. */ diff --git a/libvips/deprecated/im_align_bands.c b/libvips/deprecated/im_align_bands.c index f3fd3dd47b..dd30a34c91 100644 --- a/libvips/deprecated/im_align_bands.c +++ b/libvips/deprecated/im_align_bands.c @@ -39,7 +39,6 @@ #include #include -#include /** * im_align_bands: diff --git a/libvips/deprecated/im_analyze2vips.c b/libvips/deprecated/im_analyze2vips.c index 3732a52e8f..7901d899ba 100644 --- a/libvips/deprecated/im_analyze2vips.c +++ b/libvips/deprecated/im_analyze2vips.c @@ -41,7 +41,6 @@ #include #include -#include static VipsFormatFlags analyze_flags(const char *filename) diff --git a/libvips/deprecated/im_benchmark.c b/libvips/deprecated/im_benchmark.c index f4c5136ce8..a1d9bd9575 100644 --- a/libvips/deprecated/im_benchmark.c +++ b/libvips/deprecated/im_benchmark.c @@ -45,7 +45,6 @@ #include #include -#include /* diff --git a/libvips/deprecated/im_bernd.c b/libvips/deprecated/im_bernd.c index 7eeb6b4504..ae679cfd99 100644 --- a/libvips/deprecated/im_bernd.c +++ b/libvips/deprecated/im_bernd.c @@ -52,7 +52,6 @@ #include #include -#include static int extract(IMAGE *in, int x, int y, int w, int h) diff --git a/libvips/deprecated/im_clamp.c b/libvips/deprecated/im_clamp.c index aba7ae8053..25fddd1ab6 100644 --- a/libvips/deprecated/im_clamp.c +++ b/libvips/deprecated/im_clamp.c @@ -48,7 +48,6 @@ #include #include -#include #include int diff --git a/libvips/deprecated/im_cmulnorm.c b/libvips/deprecated/im_cmulnorm.c index 30af0273cd..731230c92b 100644 --- a/libvips/deprecated/im_cmulnorm.c +++ b/libvips/deprecated/im_cmulnorm.c @@ -47,7 +47,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/im_convsub.c b/libvips/deprecated/im_convsub.c index 708311e8fc..08e0de5f3e 100644 --- a/libvips/deprecated/im_convsub.c +++ b/libvips/deprecated/im_convsub.c @@ -55,7 +55,6 @@ #include #include -#include #include /* Create multiplication luts for all non zero elements of the original mask; diff --git a/libvips/deprecated/im_csv2vips.c b/libvips/deprecated/im_csv2vips.c index 039db2248d..2ac046470f 100644 --- a/libvips/deprecated/im_csv2vips.c +++ b/libvips/deprecated/im_csv2vips.c @@ -43,7 +43,6 @@ #include #include -#include #include "../foreign/pforeign.h" diff --git a/libvips/deprecated/im_debugim.c b/libvips/deprecated/im_debugim.c index a5fd968ae0..1122b7cff2 100644 --- a/libvips/deprecated/im_debugim.c +++ b/libvips/deprecated/im_debugim.c @@ -57,7 +57,6 @@ #include #include -#include int im_debugim(IMAGE *in) diff --git a/libvips/deprecated/im_dif_std.c b/libvips/deprecated/im_dif_std.c index 0375ba8323..eb84808d31 100644 --- a/libvips/deprecated/im_dif_std.c +++ b/libvips/deprecated/im_dif_std.c @@ -45,7 +45,6 @@ #include #include -#include #include static int diff --git a/libvips/deprecated/im_exr2vips.c b/libvips/deprecated/im_exr2vips.c index 08b230a2b4..5b8e0298f1 100644 --- a/libvips/deprecated/im_exr2vips.c +++ b/libvips/deprecated/im_exr2vips.c @@ -46,7 +46,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/im_fav4.c b/libvips/deprecated/im_fav4.c index 945d66f46d..8ce7b86361 100644 --- a/libvips/deprecated/im_fav4.c +++ b/libvips/deprecated/im_fav4.c @@ -38,7 +38,6 @@ Copyright (C) 1992, Kirk Martinez, History of Art Dept, Birkbeck College #include #include -#include #define ARGS "fav4: frame average 4 frames\nARGS: im1 im2 im3 im4 outfile" #define NFRAMES 4 diff --git a/libvips/deprecated/im_freq_mask.c b/libvips/deprecated/im_freq_mask.c index ec703d96ed..f142f1043a 100644 --- a/libvips/deprecated/im_freq_mask.c +++ b/libvips/deprecated/im_freq_mask.c @@ -46,7 +46,6 @@ #include #include -#include #include /* Make a mask image. diff --git a/libvips/deprecated/im_gadd.c b/libvips/deprecated/im_gadd.c index 0bcf8a98f9..cb1095224e 100644 --- a/libvips/deprecated/im_gadd.c +++ b/libvips/deprecated/im_gadd.c @@ -57,7 +57,6 @@ #include #include -#include int im_gfadd(double a, IMAGE *in1, double b, IMAGE *in2, double c, IMAGE *out); int im_gaddim(double a, IMAGE *in1, double b, IMAGE *in2, double c, IMAGE *out); diff --git a/libvips/deprecated/im_gaddim.c b/libvips/deprecated/im_gaddim.c index 5c0d5ccd35..df59667bfd 100644 --- a/libvips/deprecated/im_gaddim.c +++ b/libvips/deprecated/im_gaddim.c @@ -58,7 +58,6 @@ #include #include -#include /* This function works on either mmaped files or on images in buffer */ diff --git a/libvips/deprecated/im_gfadd.c b/libvips/deprecated/im_gfadd.c index 6df9529546..6f1d6a2f62 100644 --- a/libvips/deprecated/im_gfadd.c +++ b/libvips/deprecated/im_gfadd.c @@ -61,7 +61,6 @@ #include #include -#include /* uchar char ushort short uint int float double */ static int array[8][8] = { diff --git a/libvips/deprecated/im_gradcor.c b/libvips/deprecated/im_gradcor.c index 13eaec43bd..de5a38319f 100644 --- a/libvips/deprecated/im_gradcor.c +++ b/libvips/deprecated/im_gradcor.c @@ -44,7 +44,6 @@ #include #include -#include typedef struct { REGION *reg; diff --git a/libvips/deprecated/im_jpeg2vips.c b/libvips/deprecated/im_jpeg2vips.c index 658a9a21a6..6c9f3583fb 100644 --- a/libvips/deprecated/im_jpeg2vips.c +++ b/libvips/deprecated/im_jpeg2vips.c @@ -47,7 +47,6 @@ #include #include -#include #include "../foreign/pforeign.h" diff --git a/libvips/deprecated/im_lab_morph.c b/libvips/deprecated/im_lab_morph.c index a8b186f3a4..987c9918d6 100644 --- a/libvips/deprecated/im_lab_morph.c +++ b/libvips/deprecated/im_lab_morph.c @@ -45,7 +45,6 @@ #include #include -#include #include int diff --git a/libvips/deprecated/im_line.c b/libvips/deprecated/im_line.c index f08cef389f..b218326c86 100644 --- a/libvips/deprecated/im_line.c +++ b/libvips/deprecated/im_line.c @@ -52,7 +52,6 @@ #include #include -#include int im_line(IMAGE *image, int x1, int y1, int x2, int y2, int pelval) diff --git a/libvips/deprecated/im_linreg.c b/libvips/deprecated/im_linreg.c index b159818058..87ee7063fd 100644 --- a/libvips/deprecated/im_linreg.c +++ b/libvips/deprecated/im_linreg.c @@ -47,7 +47,6 @@ #include #include #include -#include typedef struct { diff --git a/libvips/deprecated/im_litecor.c b/libvips/deprecated/im_litecor.c index f901c3ebf9..cac70a7f9d 100644 --- a/libvips/deprecated/im_litecor.c +++ b/libvips/deprecated/im_litecor.c @@ -66,7 +66,6 @@ #include #include -#include /* If maximum output is > 255 scale output between minout and maxout, * by normalising maxout to 255. diff --git a/libvips/deprecated/im_magick2vips.c b/libvips/deprecated/im_magick2vips.c index 8480d03b9b..803d247044 100644 --- a/libvips/deprecated/im_magick2vips.c +++ b/libvips/deprecated/im_magick2vips.c @@ -41,7 +41,6 @@ #include #include -#include #include "../foreign/pforeign.h" diff --git a/libvips/deprecated/im_mask2vips.c b/libvips/deprecated/im_mask2vips.c index ffdc3b447d..51f5595d6f 100644 --- a/libvips/deprecated/im_mask2vips.c +++ b/libvips/deprecated/im_mask2vips.c @@ -45,7 +45,6 @@ #include #include -#include /** * im_mask2vips: diff --git a/libvips/deprecated/im_matcat.c b/libvips/deprecated/im_matcat.c index b09b6e6d9a..cfa141883f 100644 --- a/libvips/deprecated/im_matcat.c +++ b/libvips/deprecated/im_matcat.c @@ -42,7 +42,6 @@ #include #include -#include /** * im_matcat: diff --git a/libvips/deprecated/im_matinv.c b/libvips/deprecated/im_matinv.c index e05f890ef0..599c69daed 100644 --- a/libvips/deprecated/im_matinv.c +++ b/libvips/deprecated/im_matinv.c @@ -52,7 +52,6 @@ #include #include #include -#include #define TOO_SMALL (2.0 * DBL_MIN) /* DBL_MIN is smallest *normalized* double precision float */ diff --git a/libvips/deprecated/im_matmul.c b/libvips/deprecated/im_matmul.c index 4ac199a69a..951950cc09 100644 --- a/libvips/deprecated/im_matmul.c +++ b/libvips/deprecated/im_matmul.c @@ -41,7 +41,6 @@ #include #include -#include /** * im_matmul: diff --git a/libvips/deprecated/im_mattrn.c b/libvips/deprecated/im_mattrn.c index cd3d2976f1..e51b55e793 100644 --- a/libvips/deprecated/im_mattrn.c +++ b/libvips/deprecated/im_mattrn.c @@ -39,7 +39,6 @@ #include #include -#include /** * im_mattrn: diff --git a/libvips/deprecated/im_maxpos_avg.c b/libvips/deprecated/im_maxpos_avg.c index 600cc68482..8ea9fca786 100644 --- a/libvips/deprecated/im_maxpos_avg.c +++ b/libvips/deprecated/im_maxpos_avg.c @@ -62,7 +62,6 @@ #include #include -#include #include /* A position and maximum. diff --git a/libvips/deprecated/im_maxpos_subpel.c b/libvips/deprecated/im_maxpos_subpel.c index 402e03d48f..eaffc337bc 100644 --- a/libvips/deprecated/im_maxpos_subpel.c +++ b/libvips/deprecated/im_maxpos_subpel.c @@ -42,7 +42,6 @@ #include #include -#include #define MOST_OF(A, B) ((A) > 0.9 * (B)) #define LITTLE_OF(A, B) ((B) < 0.1 * (B)) diff --git a/libvips/deprecated/im_measure.c b/libvips/deprecated/im_measure.c index d429c869cb..635d5a1d33 100644 --- a/libvips/deprecated/im_measure.c +++ b/libvips/deprecated/im_measure.c @@ -60,7 +60,6 @@ #include #include -#include /* Measure into array. */ diff --git a/libvips/deprecated/im_nifti2vips.c b/libvips/deprecated/im_nifti2vips.c index fc2c55a5ab..c16146cf7f 100644 --- a/libvips/deprecated/im_nifti2vips.c +++ b/libvips/deprecated/im_nifti2vips.c @@ -46,7 +46,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/im_openslide2vips.c b/libvips/deprecated/im_openslide2vips.c index dcbed1fec7..2e582e3a32 100644 --- a/libvips/deprecated/im_openslide2vips.c +++ b/libvips/deprecated/im_openslide2vips.c @@ -50,7 +50,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/im_png2vips.c b/libvips/deprecated/im_png2vips.c index fa9f5a4c38..d2b3285d3a 100644 --- a/libvips/deprecated/im_png2vips.c +++ b/libvips/deprecated/im_png2vips.c @@ -43,7 +43,6 @@ #include #include -#include #include #include "../foreign/pforeign.h" diff --git a/libvips/deprecated/im_point_bilinear.c b/libvips/deprecated/im_point_bilinear.c index 54f1fba00c..857297136d 100644 --- a/libvips/deprecated/im_point_bilinear.c +++ b/libvips/deprecated/im_point_bilinear.c @@ -45,7 +45,6 @@ #include #include -#include /** * im_point: diff --git a/libvips/deprecated/im_ppm2vips.c b/libvips/deprecated/im_ppm2vips.c index 410d009519..22c91466c5 100644 --- a/libvips/deprecated/im_ppm2vips.c +++ b/libvips/deprecated/im_ppm2vips.c @@ -37,7 +37,6 @@ #include #include -#include int im_ppm2vips(const char *filename, IMAGE *out) diff --git a/libvips/deprecated/im_print.c b/libvips/deprecated/im_print.c index 7919827a48..c3dca99e03 100644 --- a/libvips/deprecated/im_print.c +++ b/libvips/deprecated/im_print.c @@ -36,7 +36,6 @@ #include #include -#include /* Print a string to stdout, with a "\n". Sometimes useful for debugging * language bindings. diff --git a/libvips/deprecated/im_printlines.c b/libvips/deprecated/im_printlines.c index 10e5beb451..2292b4c062 100644 --- a/libvips/deprecated/im_printlines.c +++ b/libvips/deprecated/im_printlines.c @@ -54,7 +54,6 @@ #include #include -#include /* Useful: Call a macro with the name, type pairs for all VIPS functions. */ diff --git a/libvips/deprecated/im_resize_linear.c b/libvips/deprecated/im_resize_linear.c index 506586a874..5a51160bcb 100644 --- a/libvips/deprecated/im_resize_linear.c +++ b/libvips/deprecated/im_resize_linear.c @@ -48,7 +48,6 @@ #include #include -#include /* What we do for each pel. */ diff --git a/libvips/deprecated/im_setbox.c b/libvips/deprecated/im_setbox.c index ac403f1d52..afadf7d088 100644 --- a/libvips/deprecated/im_setbox.c +++ b/libvips/deprecated/im_setbox.c @@ -48,7 +48,6 @@ #include #include -#include void im_setbox(IMAGE_BOX *pbox, int xst, int yst, int xsiz, int ysiz, int ch_select) diff --git a/libvips/deprecated/im_simcontr.c b/libvips/deprecated/im_simcontr.c index 9776244aa2..90bce679c3 100644 --- a/libvips/deprecated/im_simcontr.c +++ b/libvips/deprecated/im_simcontr.c @@ -49,7 +49,6 @@ #include #include -#include /** * im_simcontr: diff --git a/libvips/deprecated/im_slice.c b/libvips/deprecated/im_slice.c index b676eab426..d075b899df 100644 --- a/libvips/deprecated/im_slice.c +++ b/libvips/deprecated/im_slice.c @@ -55,7 +55,6 @@ #include #include -#include #define BRIGHT 255 #define GREY 128 diff --git a/libvips/deprecated/im_spatres.c b/libvips/deprecated/im_spatres.c index 85dcc58a71..17caa3d6b3 100644 --- a/libvips/deprecated/im_spatres.c +++ b/libvips/deprecated/im_spatres.c @@ -52,7 +52,6 @@ #include #include -#include int im_spatres(IMAGE *in, IMAGE *out, int step) diff --git a/libvips/deprecated/im_stretch3.c b/libvips/deprecated/im_stretch3.c index 1fba9e6495..31e0633abe 100644 --- a/libvips/deprecated/im_stretch3.c +++ b/libvips/deprecated/im_stretch3.c @@ -62,7 +62,6 @@ #include #include -#include /* Data for the cubic interpolation function. */ diff --git a/libvips/deprecated/im_thresh.c b/libvips/deprecated/im_thresh.c index e2f3522eb6..1338e1ae43 100644 --- a/libvips/deprecated/im_thresh.c +++ b/libvips/deprecated/im_thresh.c @@ -51,7 +51,6 @@ #include #include -#include /* Useful: Call a macro with the name, type pairs for all VIPS functions. */ #define BRIGHT 255 diff --git a/libvips/deprecated/im_tiff2vips.c b/libvips/deprecated/im_tiff2vips.c index 4d50eb9a50..e43b34646e 100644 --- a/libvips/deprecated/im_tiff2vips.c +++ b/libvips/deprecated/im_tiff2vips.c @@ -46,7 +46,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/im_video_test.c b/libvips/deprecated/im_video_test.c index 139a89a8d0..9fe05828fc 100644 --- a/libvips/deprecated/im_video_test.c +++ b/libvips/deprecated/im_video_test.c @@ -34,7 +34,6 @@ #include #include -#include /** * im_video_test: diff --git a/libvips/deprecated/im_vips2csv.c b/libvips/deprecated/im_vips2csv.c index b1739a70e8..399a19074d 100644 --- a/libvips/deprecated/im_vips2csv.c +++ b/libvips/deprecated/im_vips2csv.c @@ -37,7 +37,6 @@ #include #include -#include int im_vips2csv(IMAGE *in, const char *filename) diff --git a/libvips/deprecated/im_vips2dz.c b/libvips/deprecated/im_vips2dz.c index 9c20e6d5b8..c4c0c648e1 100644 --- a/libvips/deprecated/im_vips2dz.c +++ b/libvips/deprecated/im_vips2dz.c @@ -45,7 +45,6 @@ #include #include -#include int im_vips2dz(IMAGE *in, const char *filename) diff --git a/libvips/deprecated/im_vips2jpeg.c b/libvips/deprecated/im_vips2jpeg.c index 4d3c1e74bf..bd61772211 100644 --- a/libvips/deprecated/im_vips2jpeg.c +++ b/libvips/deprecated/im_vips2jpeg.c @@ -46,7 +46,6 @@ #include #include -#include #include int diff --git a/libvips/deprecated/im_vips2mask.c b/libvips/deprecated/im_vips2mask.c index 1f4d5c4055..a7f4406838 100644 --- a/libvips/deprecated/im_vips2mask.c +++ b/libvips/deprecated/im_vips2mask.c @@ -48,7 +48,6 @@ #include #include -#include /** * im_vips2mask: diff --git a/libvips/deprecated/im_vips2png.c b/libvips/deprecated/im_vips2png.c index 7d141b21d1..80809abf91 100644 --- a/libvips/deprecated/im_vips2png.c +++ b/libvips/deprecated/im_vips2png.c @@ -45,7 +45,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/im_vips2ppm.c b/libvips/deprecated/im_vips2ppm.c index ce4c796964..ce94515ddb 100644 --- a/libvips/deprecated/im_vips2ppm.c +++ b/libvips/deprecated/im_vips2ppm.c @@ -39,7 +39,6 @@ #include #include -#include int im_vips2ppm(IMAGE *in, const char *filename) diff --git a/libvips/deprecated/im_vips2tiff.c b/libvips/deprecated/im_vips2tiff.c index 5f326ca2cd..21c7ea4103 100644 --- a/libvips/deprecated/im_vips2tiff.c +++ b/libvips/deprecated/im_vips2tiff.c @@ -45,7 +45,6 @@ #include #include -#include int im_vips2tiff(IMAGE *in, const char *filename) diff --git a/libvips/deprecated/im_vips2webp.c b/libvips/deprecated/im_vips2webp.c index 5bd4efe82e..8a9a0a3f7a 100644 --- a/libvips/deprecated/im_vips2webp.c +++ b/libvips/deprecated/im_vips2webp.c @@ -39,7 +39,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/im_webp2vips.c b/libvips/deprecated/im_webp2vips.c index f9fd18e97e..dc1ebd9a12 100644 --- a/libvips/deprecated/im_webp2vips.c +++ b/libvips/deprecated/im_webp2vips.c @@ -37,7 +37,6 @@ #include #include -#include #include #include "../foreign/pforeign.h" diff --git a/libvips/deprecated/im_zerox.c b/libvips/deprecated/im_zerox.c index d551f728ba..90fd1aa5bf 100644 --- a/libvips/deprecated/im_zerox.c +++ b/libvips/deprecated/im_zerox.c @@ -51,7 +51,6 @@ #include #include -#include #define LOOP(TYPE) \ { \ diff --git a/libvips/deprecated/inplace_dispatch.c b/libvips/deprecated/inplace_dispatch.c index 2c0c7861dc..17a383d172 100644 --- a/libvips/deprecated/inplace_dispatch.c +++ b/libvips/deprecated/inplace_dispatch.c @@ -38,7 +38,6 @@ #include #include -#include /* Calculate a pixel for an image from a vec of double. Valid while im is * valid. diff --git a/libvips/deprecated/lazy.c b/libvips/deprecated/lazy.c index d92ce49168..2e480e49e4 100644 --- a/libvips/deprecated/lazy.c +++ b/libvips/deprecated/lazy.c @@ -46,7 +46,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/mask_dispatch.c b/libvips/deprecated/mask_dispatch.c index 3784f8d24f..fa1e996b85 100644 --- a/libvips/deprecated/mask_dispatch.c +++ b/libvips/deprecated/mask_dispatch.c @@ -38,7 +38,6 @@ #include #include -#include /* One matrix in, one out. */ diff --git a/libvips/deprecated/matalloc.c b/libvips/deprecated/matalloc.c index 95f85821bf..eefa370446 100644 --- a/libvips/deprecated/matalloc.c +++ b/libvips/deprecated/matalloc.c @@ -13,7 +13,6 @@ #include #include -#include #define TINY 1.0e-200 diff --git a/libvips/deprecated/matlab.c b/libvips/deprecated/matlab.c index 004b32d29a..1f7d7b13bc 100644 --- a/libvips/deprecated/matlab.c +++ b/libvips/deprecated/matlab.c @@ -37,7 +37,6 @@ #include #include -#include int im_mat2vips(const char *filename, IMAGE *out) diff --git a/libvips/deprecated/morph_dispatch.c b/libvips/deprecated/morph_dispatch.c index 3a2f526bec..5a32aa3cb7 100644 --- a/libvips/deprecated/morph_dispatch.c +++ b/libvips/deprecated/morph_dispatch.c @@ -38,7 +38,6 @@ #include #include -#include /* Args to im_profile. */ diff --git a/libvips/deprecated/mosaicing_dispatch.c b/libvips/deprecated/mosaicing_dispatch.c index 263d29fe57..d049464861 100644 --- a/libvips/deprecated/mosaicing_dispatch.c +++ b/libvips/deprecated/mosaicing_dispatch.c @@ -38,7 +38,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/other_dispatch.c b/libvips/deprecated/other_dispatch.c index 34a67b69f0..f4d4886855 100644 --- a/libvips/deprecated/other_dispatch.c +++ b/libvips/deprecated/other_dispatch.c @@ -38,7 +38,6 @@ #include #include -#include /* Args for im_sines. */ diff --git a/libvips/deprecated/package.c b/libvips/deprecated/package.c index 860b7afa8f..9544779d06 100644 --- a/libvips/deprecated/package.c +++ b/libvips/deprecated/package.c @@ -58,7 +58,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/radiance.c b/libvips/deprecated/radiance.c index 2e0b63ebc5..0244e6ef94 100644 --- a/libvips/deprecated/radiance.c +++ b/libvips/deprecated/radiance.c @@ -37,7 +37,6 @@ #include #include -#include int im_rad2vips(const char *filename, IMAGE *out) diff --git a/libvips/deprecated/raw.c b/libvips/deprecated/raw.c index c2c7073ce9..df3df64724 100644 --- a/libvips/deprecated/raw.c +++ b/libvips/deprecated/raw.c @@ -41,7 +41,6 @@ #include #include -#include int im_raw2vips(const char *filename, IMAGE *out, diff --git a/libvips/deprecated/rename.c b/libvips/deprecated/rename.c index 33aea5ba83..4ac3209b38 100644 --- a/libvips/deprecated/rename.c +++ b/libvips/deprecated/rename.c @@ -38,7 +38,6 @@ #include #include -#include #include int diff --git a/libvips/deprecated/resample_dispatch.c b/libvips/deprecated/resample_dispatch.c index 6974839a0f..2bf883dd7a 100644 --- a/libvips/deprecated/resample_dispatch.c +++ b/libvips/deprecated/resample_dispatch.c @@ -38,7 +38,6 @@ #include #include -#include #include #include diff --git a/libvips/deprecated/rotmask.c b/libvips/deprecated/rotmask.c index 7a41ffb1e2..b27f535228 100644 --- a/libvips/deprecated/rotmask.c +++ b/libvips/deprecated/rotmask.c @@ -55,7 +55,6 @@ #include #include -#include /* The type of the vips operations we support. */ diff --git a/libvips/deprecated/rw_mask.c b/libvips/deprecated/rw_mask.c index 6811aa411a..4c6cf444d4 100644 --- a/libvips/deprecated/rw_mask.c +++ b/libvips/deprecated/rw_mask.c @@ -95,7 +95,6 @@ #include #include -#include /** * INTMASK: diff --git a/libvips/deprecated/tone.c b/libvips/deprecated/tone.c index aac7e7a20e..d8f6b5ec42 100644 --- a/libvips/deprecated/tone.c +++ b/libvips/deprecated/tone.c @@ -52,7 +52,6 @@ #include #include -#include /** * im_tone_map: diff --git a/libvips/deprecated/video_dispatch.c b/libvips/deprecated/video_dispatch.c index b33df257ec..18dd57af42 100644 --- a/libvips/deprecated/video_dispatch.c +++ b/libvips/deprecated/video_dispatch.c @@ -36,7 +36,6 @@ #include #include -#include /** * SECTION: video diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 4d596d4e2e..e9c6a7212b 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -46,7 +46,6 @@ #include #include -#include #include #include #include diff --git a/libvips/foreign/vipsload.c b/libvips/foreign/vipsload.c index 0617c62805..5678a6cb3a 100644 --- a/libvips/foreign/vipsload.c +++ b/libvips/foreign/vipsload.c @@ -42,6 +42,9 @@ #include #include +/* For vips_image_new_mode() + */ +#define VIPS_DISABLE_DEPRECATION_WARNINGS #include #include diff --git a/libvips/foreign/vipssave.c b/libvips/foreign/vipssave.c index f5b45205b0..9fbf7edade 100644 --- a/libvips/foreign/vipssave.c +++ b/libvips/foreign/vipssave.c @@ -45,6 +45,9 @@ #include #include +/* For vips_image_new_mode() + */ +#define VIPS_DISABLE_DEPRECATION_WARNINGS #include #include diff --git a/libvips/include/vips/enumtypes.c.in b/libvips/include/vips/enumtypes.c.in index 60a2a13f47..f57755dd57 100644 --- a/libvips/include/vips/enumtypes.c.in +++ b/libvips/include/vips/enumtypes.c.in @@ -5,10 +5,6 @@ #include #endif /*HAVE_CONFIG_H*/ #include - -#if ENABLE_DEPRECATED -#include -#endif /*** END file-header ***/ /*** BEGIN file-production ***/ diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index ea6d56fc26..edde31a272 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -165,19 +165,12 @@ int vips__object_leak(void); int vips__open_image_read(const char *filename); int vips__open_image_write(const char *filename, gboolean temp); -/* im_image_open_input() needs to have this visible. +/* Defined in `vips.h`, unless building with `-Ddeprecated=false` */ -#if VIPS_ENABLE_DEPRECATED -VIPS_API -#endif +#if !VIPS_ENABLE_DEPRECATED int vips_image_open_input(VipsImage *image); - -/* im_image_open_output() needs to have this visible. - */ -#if VIPS_ENABLE_DEPRECATED -VIPS_API -#endif int vips_image_open_output(VipsImage *image); +#endif void vips__link_break_all(VipsImage *im); void *vips__link_map(VipsImage *image, gboolean upstream, @@ -187,26 +180,13 @@ gboolean vips__mmap_supported(int fd); void *vips__mmap(int fd, int writeable, size_t length, gint64 offset); int vips__munmap(const void *start, size_t length); -/* im_mapfile() needs to have this visible. +/* Defined in `vips.h`, unless building with `-Ddeprecated=false` */ -#if VIPS_ENABLE_DEPRECATED -VIPS_API -#endif +#if !VIPS_ENABLE_DEPRECATED int vips_mapfile(VipsImage *image); - -/* im_mapfilerw() needs to have this visible. - */ -#if VIPS_ENABLE_DEPRECATED -VIPS_API -#endif int vips_mapfilerw(VipsImage *image); - -/* im_remapfilerw() needs to have this visible. - */ -#if VIPS_ENABLE_DEPRECATED -VIPS_API -#endif int vips_remapfilerw(VipsImage *image); +#endif void vips__buffer_init(void); void vips__buffer_shutdown(void); @@ -245,12 +225,11 @@ void vips_image_preeval(VipsImage *image); void vips_image_eval(VipsImage *image, guint64 processed); void vips_image_posteval(VipsImage *image); -/* im_openout() needs to have this visible. +/* Defined in `vips.h`, unless building with `-Ddeprecated=false` */ -#if VIPS_ENABLE_DEPRECATED -VIPS_API -#endif +#if !VIPS_ENABLE_DEPRECATED VipsImage *vips_image_new_mode(const char *filename, const char *mode); +#endif int vips__formatalike_vec(VipsImage **in, VipsImage **out, int n); int vips__sizealike_vec(VipsImage **in, VipsImage **out, int n); diff --git a/libvips/include/vips/vips.h b/libvips/include/vips/vips.h index 9565ec0b11..45960c66e7 100644 --- a/libvips/include/vips/vips.h +++ b/libvips/include/vips/vips.h @@ -109,9 +109,6 @@ extern "C" { #include -#if VIPS_ENABLE_DEPRECATED -#include -#endif #include #include #include @@ -139,7 +136,7 @@ extern "C" { #include #include #if VIPS_ENABLE_DEPRECATED -#include +#include #endif /* We can't use _ here since this will be compiled by our clients and they may diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 25e2fdd9a1..64da94ca82 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -34,6 +34,8 @@ #ifndef VIPS_VIPS7COMPAT_H #define VIPS_VIPS7COMPAT_H +#include + #ifdef __cplusplus extern "C" { #endif /*__cplusplus*/ @@ -1760,6 +1762,7 @@ void vips_vector_to_fixed_point(double *in, int *out, int n, int scale); #include #include +#include #ifdef __cplusplus } diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 889e9914f4..8aca9821eb 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -86,12 +86,6 @@ #include #include -/* For the vips__image_sizeof_bandformat declaration. - */ -#if ENABLE_DEPRECATED -#include -#endif - /** * SECTION: header * @short_description: get, set and walk image headers diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 16a8bb632a..7794a0bf1c 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -66,6 +66,7 @@ #endif /*HAVE_UNISTD_H*/ #include +#define VIPS_DISABLE_DEPRECATION_WARNINGS #include #include #include diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 87f1cd0b5d..5df713b8c6 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -100,10 +100,6 @@ #include #include -#if ENABLE_DEPRECATED -#include -#endif - /* abort() on the first warning or error. */ int vips__fatal = 0; diff --git a/tools/vips.c b/tools/vips.c index 91707b9c84..5abc6193a1 100644 --- a/tools/vips.c +++ b/tools/vips.c @@ -103,10 +103,6 @@ #include #include -#if ENABLE_DEPRECATED -#include -#endif - static char *main_option_plugin = NULL; static gboolean main_option_targets; static gboolean main_option_version; From ad4f7d38d8132cd39c0578cd7a51973e98624080 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 12 Oct 2024 13:34:17 +0200 Subject: [PATCH 11/65] Revise ChangeLog (#4199) Simplify, fix typos and avoid use of `@`. --- ChangeLog | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 38977c343e..ba26803998 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,13 +12,11 @@ master 8.16 - add configurable max coordinate and vips_max_coord_get() - improve kill handling - PFM save and load now uses scRGB (ie. linear 0-1) [NiHoel] -- turn `vips_addalpha` into a VipsOperation [RiskoZoSlovenska] +- turn vips_addalpha() into a VipsOperation [RiskoZoSlovenska] - add vips_rawsave_target(), vips_rawsave_buffer() [akash-akya] - vipsheader supports multiple "-f field" arguments [sergeevabc] -- webpsave has @target_size parameter to set desired size - in bytes [john-parton] -- webpsave has @passes parameter to set number of passes to achieve - desired target_size [john-parton] +- add "target_size" to webpsave [john-parton] +- add "passes" to webpsave [john-parton] - revise sRGB -> B_W coefficients [daniellovera] - add vips_sdf(), vips_clamp(), vips_maxpair(), vips_minpair() - more const for the C++ API [Julianiolo] @@ -27,7 +25,7 @@ master 8.16 - add "unpack_complex" option to vips_getpoint() - add deflate compression level setting to tiffsave [ruven] - add "smart_deblock" to webpsave [goodusername123] -- add "auto_files" to heifsave [lovell] +- add "auto_tiles" to heifsave [lovell] 4/10/24 8.15.5 From d1ae327c9310361a8e4a50112553db730bdec930 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 12 Oct 2024 13:35:31 +0200 Subject: [PATCH 12/65] Improve `README.md` (#4200) - "JPEG2000" = "JPEG 2000" - "JPEG-XL" = "JPEG XL" - "eg." = "e.g." - Revise build dir sentence. --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b27387caee..f95ac71af5 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ operations, frequency filtering, colour, resampling, statistics and others. It supports a large range of [numeric types](https://libvips.github.io/libvips/API/current/VipsImage.html#VipsBandFormat), from 8-bit int to 128-bit complex. Images can have any number of bands. -It supports a good range of image formats, including JPEG, JPEG2000, JPEG-XL, +It supports a good range of image formats, including JPEG, JPEG 2000, JPEG XL, TIFF, PNG, WebP, HEIC, AVIF, FITS, Matlab, OpenEXR, PDF, SVG, HDR, PPM / PGM / PFM, CSV, GIF, Analyze, NIfTI, DeepZoom, and OpenSlide. It can also load images via ImageMagick or GraphicsMagick, letting it work with formats @@ -115,10 +115,10 @@ configuration. - Add `--default-library static` for a static build. -- Use eg. `CC=clang CXX=clang++ meson setup ...` to change compiler. +- Use e.g. `CC=clang CXX=clang++ meson setup ...` to change compiler. -- You can have many `build-dir`, pick whatever names you like, for example - one for release and one for debug. +- You can have an alternative build directory, pick whatever names you like, + for example one for release and one for debug. There's a more comprehensive test suite you can run once libvips has been installed. Use `pytest` in the libvips base directory. From 59ac0f091f3cab6321556a1c45faa0a7391c3365 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 12 Oct 2024 13:36:41 +0200 Subject: [PATCH 13/65] Fix build with orc (#4198) Regressed since 71d356b. --- libvips/include/vips/vips7compat.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 64da94ca82..9abf047d21 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -1658,13 +1658,17 @@ size_t vips__get_sizeof_vipsobject(void); /* This is deprecated to make room for highway. */ +#ifndef OrcProgram typedef struct _OrcProgram { /* Opaque */ } OrcProgram; +#endif +#ifndef OrcExecutor typedef struct _OrcExecutor { char data[808]; } OrcExecutor; +#endif #define VIPS_VECTOR_SOURCE_MAX (10) From 2de901868f044fd996ea883dd2c469b27aaffc79 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 12 Oct 2024 13:30:38 +0100 Subject: [PATCH 14/65] remove auto_tiles option just turn it on by default see https://github.com/libvips/libvips/pull/4191#issuecomment-2408536160 --- ChangeLog | 1 - libvips/foreign/foreign.c | 8 -------- libvips/foreign/heifsave.c | 16 ++++------------ 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 29728e4a41..a604cfec50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,7 +25,6 @@ - add "unpack_complex" option to vips_getpoint() - add deflate compression level setting to tiffsave [ruven] - add "smart_deblock" to webpsave [goodusername123] -- add "auto_tiles" to heifsave [lovell] 4/10/24 8.15.5 diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 5bcefdf81a..acc1a74097 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -2366,7 +2366,6 @@ vips_heifload_source(VipsSource *source, VipsImage **out, ...) * * @effort: %gint, encoding effort * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode * * @encoder: #VipsForeignHeifEncoder, select encoder to use - * * @auto_tiles: %gboolean, determine optimum tile count * * Write a VIPS image to a file in HEIF format. * @@ -2390,11 +2389,6 @@ vips_heifload_source(VipsSource *source, VipsImage **out, ...) * * Use @encoder to set the encode library to use, e.g. aom, SVT-AV1, rav1e etc. * - * When using the aom encoder, set @auto_tiles to determine the optimum - * number of tiles based on dimensions and available threads. This can - * improve multi-core utilisation and/or reduce peak memory consumption - * at the expense of slightly increased file size. - * * See also: vips_image_write_to_file(), vips_heifload(). * * Returns: 0 on success, -1 on error. @@ -2428,7 +2422,6 @@ vips_heifsave(VipsImage *in, const char *filename, ...) * * @effort: %gint, encoding effort * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode * * @encoder: #VipsForeignHeifEncoder, select encoder to use - * * @auto_tiles: %gboolean, determine optimum tile count * * As vips_heifsave(), but save to a memory buffer. * @@ -2483,7 +2476,6 @@ vips_heifsave_buffer(VipsImage *in, void **buf, size_t *len, ...) * * @effort: %gint, encoding effort * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode * * @encoder: #VipsForeignHeifEncoder, select encoder to use - * * @auto_tiles: %gboolean, determine optimum tile count * * As vips_heifsave(), but save to a target. * diff --git a/libvips/foreign/heifsave.c b/libvips/foreign/heifsave.c index 9ba5bc96df..e1040650ac 100644 --- a/libvips/foreign/heifsave.c +++ b/libvips/foreign/heifsave.c @@ -130,10 +130,6 @@ typedef struct _VipsForeignSaveHeif { */ int speed; - /* Auto tiles (currently aom only). - */ - gboolean auto_tiles; - } VipsForeignSaveHeif; typedef VipsForeignSaveClass VipsForeignSaveHeifClass; @@ -652,8 +648,11 @@ vips_foreign_save_heif_build(VipsObject *object) } #endif /*HAVE_HEIF_ENCODER_PARAMETER_GET_VALID_INTEGER_VALUES*/ + /* Try to enable auto_tiles. This can make AVIF encoding a lot faster, + * with only a very small increase in file size. + */ error = heif_encoder_set_parameter_boolean(heif->encoder, - "auto-tiles", heif->auto_tiles); + "auto-tiles", TRUE); if (error.code && error.subcode != heif_suberror_Unsupported_parameter) { vips__heif_error(&error); @@ -819,13 +818,6 @@ vips_foreign_save_heif_class_init(VipsForeignSaveHeifClass *class) G_STRUCT_OFFSET(VipsForeignSaveHeif, selected_encoder), VIPS_TYPE_FOREIGN_HEIF_ENCODER, VIPS_FOREIGN_HEIF_ENCODER_AUTO); - - VIPS_ARG_BOOL(class, "auto_tiles", 19, - _("Auto-tiles"), - _("Determine optimum tile count"), - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET(VipsForeignSaveHeif, auto_tiles), - FALSE); } static void From a6741382d0f04f78d018b5819a3c9401406f16a1 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 12 Oct 2024 13:35:24 +0100 Subject: [PATCH 15/65] remove auto_tiles --- cplusplus/include/vips/VImage8.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h index 56876c17fb..4d61d9b168 100644 --- a/cplusplus/include/vips/VImage8.h +++ b/cplusplus/include/vips/VImage8.h @@ -3446,7 +3446,6 @@ class VImage : public VObject { * - **effort** -- CPU effort, int. * - **subsample_mode** -- Select chroma subsample operation mode, VipsForeignSubsample. * - **encoder** -- Select encoder to use, VipsForeignHeifEncoder. - * - **auto_tiles** -- Determine optimum tile count, bool. * - **keep** -- Which metadata to retain, VipsForeignKeep. * - **background** -- Background value, std::vector. * - **page_height** -- Set page height for multipage save, int. @@ -3468,7 +3467,6 @@ class VImage : public VObject { * - **effort** -- CPU effort, int. * - **subsample_mode** -- Select chroma subsample operation mode, VipsForeignSubsample. * - **encoder** -- Select encoder to use, VipsForeignHeifEncoder. - * - **auto_tiles** -- Determine optimum tile count, bool. * - **keep** -- Which metadata to retain, VipsForeignKeep. * - **background** -- Background value, std::vector. * - **page_height** -- Set page height for multipage save, int. @@ -3490,7 +3488,6 @@ class VImage : public VObject { * - **effort** -- CPU effort, int. * - **subsample_mode** -- Select chroma subsample operation mode, VipsForeignSubsample. * - **encoder** -- Select encoder to use, VipsForeignHeifEncoder. - * - **auto_tiles** -- Determine optimum tile count, bool. * - **keep** -- Which metadata to retain, VipsForeignKeep. * - **background** -- Background value, std::vector. * - **page_height** -- Set page height for multipage save, int. From a697fe71dd8c6eb3e07fc52709fa0ff663f49da7 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 12 Oct 2024 15:18:10 +0200 Subject: [PATCH 16/65] fixup! Fix build with orc (#4198) (#4203) --- libvips/include/vips/vips7compat.h | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 9abf047d21..9a31a1723f 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -36,6 +36,21 @@ #include +/* The old deprecated VipsVector/VipsExecutor API required orc. + * Avoid a possible ABI/API break with the adoption of highway. + */ +#ifdef HAVE_ORC +#include +#else +typedef struct _OrcProgram { + /* Opaque */ +} OrcProgram; + +typedef struct _OrcExecutor { + char data[808]; +} OrcExecutor; +#endif + #ifdef __cplusplus extern "C" { #endif /*__cplusplus*/ @@ -1658,18 +1673,6 @@ size_t vips__get_sizeof_vipsobject(void); /* This is deprecated to make room for highway. */ -#ifndef OrcProgram -typedef struct _OrcProgram { - /* Opaque */ -} OrcProgram; -#endif - -#ifndef OrcExecutor -typedef struct _OrcExecutor { - char data[808]; -} OrcExecutor; -#endif - #define VIPS_VECTOR_SOURCE_MAX (10) typedef struct { From 0a9736bddf6c3b608935a39c7eeff37d3dd47993 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 18 Oct 2024 15:15:10 +0200 Subject: [PATCH 17/65] jpeg: implement custom message codes and table (#4208) Use the "add-on" message table to ensure compatibility with jpegli, which lacks its own message codes and table. Resolves: #4206. --- libvips/foreign/jpeg.h | 8 ++++++++ libvips/foreign/jpeg2vips.c | 11 +++++++---- libvips/foreign/tiff2vips.c | 5 ++++- libvips/foreign/vips2jpeg.c | 13 +++++++++++-- libvips/foreign/vips2tiff.c | 8 +++++++- 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/libvips/foreign/jpeg.h b/libvips/foreign/jpeg.h index a36725bad3..3eb654c237 100644 --- a/libvips/foreign/jpeg.h +++ b/libvips/foreign/jpeg.h @@ -62,6 +62,12 @@ extern "C" { #include #include +/* Our custom error message codes. + */ +#define JERR_VIPS_IMAGE_EOF (1000) +#define JWRN_VIPS_IMAGE_EOF JERR_VIPS_IMAGE_EOF +#define JERR_VIPS_TARGET_WRITE (1001) + /* Define a new error handler for when we bomb out. */ typedef struct { @@ -75,6 +81,8 @@ typedef struct { FILE *fp; /* fclose() if non-NULL */ } ErrorManager; +extern const char *vips__jpeg_message_table[]; + void vips__new_output_message(j_common_ptr cinfo); void vips__new_error_exit(j_common_ptr cinfo); diff --git a/libvips/foreign/jpeg2vips.c b/libvips/foreign/jpeg2vips.c index 17b3a70328..2a4c28d60d 100644 --- a/libvips/foreign/jpeg2vips.c +++ b/libvips/foreign/jpeg2vips.c @@ -245,10 +245,10 @@ source_fill_input_buffer(j_decompress_ptr cinfo) /* Knock the output out of cache. */ vips_foreign_load_invalidate(src->jpeg->out); - ERREXIT(cinfo, JERR_INPUT_EOF); + ERREXIT(cinfo, JERR_VIPS_IMAGE_EOF); } else - WARNMS(cinfo, JWRN_JPEG_EOF); + WARNMS(cinfo, JWRN_VIPS_IMAGE_EOF); /* Insert a fake EOI marker. */ @@ -272,10 +272,10 @@ source_fill_input_buffer_mappable(j_decompress_ptr cinfo) /* Knock the output out of cache. */ vips_foreign_load_invalidate(src->jpeg->out); - ERREXIT(cinfo, JERR_INPUT_EOF); + ERREXIT(cinfo, JERR_VIPS_IMAGE_EOF); } else - WARNMS(cinfo, JWRN_JPEG_EOF); + WARNMS(cinfo, JWRN_VIPS_IMAGE_EOF); /* Insert a fake EOI marker. */ @@ -463,6 +463,9 @@ readjpeg_new(VipsSource *source, VipsImage *out, jpeg->shrink = shrink; jpeg->fail_on = fail_on; jpeg->cinfo.err = jpeg_std_error(&jpeg->eman.pub); + jpeg->cinfo.err->addon_message_table = vips__jpeg_message_table; + jpeg->cinfo.err->first_addon_message = 1000; + jpeg->cinfo.err->last_addon_message = 1001; jpeg->eman.pub.error_exit = vips__new_error_exit; jpeg->eman.pub.emit_message = readjpeg_emit_message; jpeg->eman.pub.output_message = vips__new_output_message; diff --git a/libvips/foreign/tiff2vips.c b/libvips/foreign/tiff2vips.c index 9b553d9d80..3977031811 100644 --- a/libvips/foreign/tiff2vips.c +++ b/libvips/foreign/tiff2vips.c @@ -1973,7 +1973,7 @@ rtiff_decompress_jpeg_fill_input_buffer(j_decompress_ptr cinfo) * buffer, so any request for more data beyond the given buffer size * is treated as an error. */ - WARNMS(cinfo, JWRN_JPEG_EOF); + WARNMS(cinfo, JWRN_VIPS_IMAGE_EOF); /* Insert a fake EOI marker */ @@ -2163,6 +2163,9 @@ rtiff_decompress_jpeg(Rtiff *rtiff, void *data, size_t data_len, void *out) if (setjmp(eman.jmp) == 0) { cinfo.err = jpeg_std_error(&eman.pub); + cinfo.err->addon_message_table = vips__jpeg_message_table; + cinfo.err->first_addon_message = 1000; + cinfo.err->last_addon_message = 1001; eman.pub.error_exit = vips__new_error_exit; eman.pub.emit_message = rtiff_decompress_jpeg_emit_message; eman.pub.output_message = vips__new_output_message; diff --git a/libvips/foreign/vips2jpeg.c b/libvips/foreign/vips2jpeg.c index 7757e368a0..abeb2e537d 100644 --- a/libvips/foreign/vips2jpeg.c +++ b/libvips/foreign/vips2jpeg.c @@ -159,6 +159,12 @@ #define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */ #define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN) +const char *vips__jpeg_message_table[] = { + "premature end of JPEG image", + "unable to write to target", + NULL +}; + /* New output message method - send to VIPS. */ void @@ -229,6 +235,9 @@ write_new(void) write->row_pointer = NULL; write->cinfo.err = jpeg_std_error(&write->eman.pub); + write->cinfo.err->addon_message_table = vips__jpeg_message_table; + write->cinfo.err->first_addon_message = 1000; + write->cinfo.err->last_addon_message = 1001; write->cinfo.dest = NULL; write->eman.pub.error_exit = vips__new_error_exit; write->eman.pub.output_message = vips__new_output_message; @@ -811,7 +820,7 @@ empty_output_buffer(j_compress_ptr cinfo) if (vips_target_write(dest->target, dest->buf, TARGET_BUFFER_SIZE)) - ERREXIT(cinfo, JERR_FILE_WRITE); + ERREXIT(cinfo, JERR_VIPS_TARGET_WRITE); dest->pub.next_output_byte = dest->buf; dest->pub.free_in_buffer = TARGET_BUFFER_SIZE; @@ -839,7 +848,7 @@ term_destination(j_compress_ptr cinfo) if (vips_target_write(dest->target, dest->buf, TARGET_BUFFER_SIZE - dest->pub.free_in_buffer)) - ERREXIT(cinfo, JERR_FILE_WRITE); + ERREXIT(cinfo, JERR_VIPS_TARGET_WRITE); } /* Set dest to one of our objects. diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index e80fc3db6d..7a93d0f3d2 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -732,6 +732,9 @@ wtiff_compress_jpeg(Wtiff *wtiff, // we could have one of these per thread and reuse it for a small speedup cinfo.err = jpeg_std_error(&eman.pub); + cinfo.err->addon_message_table = vips__jpeg_message_table; + cinfo.err->first_addon_message = 1000; + cinfo.err->last_addon_message = 1001; cinfo.dest = NULL; eman.pub.error_exit = vips__new_error_exit; eman.pub.output_message = vips__new_output_message; @@ -740,7 +743,7 @@ wtiff_compress_jpeg(Wtiff *wtiff, // we need a line buffer to pad edge tiles line = VIPS_MALLOC(NULL, wtiff->tilew * sizeof_pel); - /* Error handling. The error message will have ben set by our handlers. + /* Error handling. The error message will have been set by our handlers. */ if (setjmp(eman.jmp)) { jpeg_destroy_compress(&cinfo); @@ -805,6 +808,9 @@ wtiff_compress_jpeg_tables(Wtiff *wtiff, struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); + cinfo.err->addon_message_table = vips__jpeg_message_table; + cinfo.err->first_addon_message = 1000; + cinfo.err->last_addon_message = 1001; jpeg_create_compress(&cinfo); /* Attach output. From 5d20bf7d4e3c613e3f25c92d1df5e46ce260b5eb Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 18 Oct 2024 14:17:48 +0100 Subject: [PATCH 18/65] fix Vips-8.0.gir generation The empty struct for OrcProgram seems to confuse introspection, I see a lot of message like: ``` $ ninja [4/551] Generating glib marshaller header libvips/iofuncs/vipsmarshal_h INFO: Reading ../libvips/iofuncs/vipsmarshal.list... [7/551] Generating glib marshaller source libvips/iofuncs/vipsmarshal_c INFO: Reading ../libvips/iofuncs/vipsmarshal.list... [550/551] Generating libvips/Vips-8.0.... command (wrapped by meson to set env) /home/john/GIT/libvips/libvips/include/vips/vips7compat.h:47: syntax error, unexpected '}' in '} OrcProgram;' at '}' ``` Using a typdef to an anon struct seems to fix this. --- libvips/include/vips/vips7compat.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 9a31a1723f..5799125fc1 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -42,9 +42,7 @@ #ifdef HAVE_ORC #include #else -typedef struct _OrcProgram { - /* Opaque */ -} OrcProgram; +typedef struct _OrcProgram OrcProgram; typedef struct _OrcExecutor { char data[808]; From 0166b518ac6258ef1deddb9fa9a446a16db49028 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 19 Oct 2024 15:23:32 +0200 Subject: [PATCH 19/65] vips7compat.h: remove `OrcProgram` and `OrcExecutor` stubs (#4207) Remove the confusing `OrcProgram` and `OrcExecutor` stubs to avoid conflicts with `orc.h`. Should be safe, the deprecated `VipsVector` and `VipsExecutor` APIs was tightly coupled to liborc and became no-op after the adoption of Highway. While this is a potential ABI break, this API was likely not used outside libvips. The same ABI break could also occur in versions prior to 8.15 when a binary was built with `-Dorc=disabled` instead of `-Dorc=enabled`. --- libvips/include/vips/vips7compat.h | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 9a31a1723f..4bc21a92f9 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -36,20 +36,9 @@ #include -/* The old deprecated VipsVector/VipsExecutor API required orc. - * Avoid a possible ABI/API break with the adoption of highway. - */ #ifdef HAVE_ORC #include -#else -typedef struct _OrcProgram { - /* Opaque */ -} OrcProgram; - -typedef struct _OrcExecutor { - char data[808]; -} OrcExecutor; -#endif +#endif /* HAVE_ORC */ #ifdef __cplusplus extern "C" { @@ -1694,13 +1683,17 @@ typedef struct { int d1; +#ifdef HAVE_ORC OrcProgram *program; +#endif /*HAVE_ORC*/ gboolean compiled; } VipsVector; typedef struct { +#ifdef HAVE_ORC OrcExecutor executor; +#endif /*HAVE_ORC*/ VipsVector *vector; } VipsExecutor; From 6c397fb7eea08f2f34af6745d65d9f5bc15dbf4f Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 19 Oct 2024 15:25:01 +0200 Subject: [PATCH 20/65] Add option to opt-out of `vips7compat.h` inclusion (#4210) Via the `VIPS_DISABLE_COMPAT` definition. --- libvips/include/vips/vips.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libvips/include/vips/vips.h b/libvips/include/vips/vips.h index 45960c66e7..9e74ef5579 100644 --- a/libvips/include/vips/vips.h +++ b/libvips/include/vips/vips.h @@ -135,7 +135,14 @@ extern "C" { #include #include #include -#if VIPS_ENABLE_DEPRECATED + +/* VIPS_DISABLE_COMPAT: + * + * Disable automatically inclusion of `vips7compat.h`. + * + * This has no effect when building with `-Ddeprecated=false`. + */ +#if VIPS_ENABLE_DEPRECATED && !defined(VIPS_DISABLE_COMPAT) #include #endif From 6819735183118e0a3fda166ad4d0cbb41a6d14da Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 27 Oct 2024 01:18:42 +0000 Subject: [PATCH 21/65] fix a stray line in histogram plotting --- libvips/histogram/hist_plot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libvips/histogram/hist_plot.c b/libvips/histogram/hist_plot.c index ed849b7cdc..779557d7ef 100644 --- a/libvips/histogram/hist_plot.c +++ b/libvips/histogram/hist_plot.c @@ -87,7 +87,7 @@ G_DEFINE_TYPE(VipsHistPlot, vips_hist_plot, VIPS_TYPE_OPERATION); \ for (x = le; x < ri; x++) { \ for (z = 0; z < nb; z++) \ - q[z] = p1[z] < ((TYPE) x) ? 0 : 255; \ + q[z] = p1[z] < x ? 0 : 255; \ \ q += nb; \ } \ @@ -153,7 +153,7 @@ vips_hist_plot_vert_gen(VipsRegion *out_region, \ for (y = to; y < bo; y++) { \ for (z = 0; z < nb; z++) \ - q[z] = p1[z] < ((TYPE) (ht - y)) ? 0 : 255; \ + q[z] = p1[z] < ht - y ? 0 : 255; \ \ q += lsk; \ } \ From 8dd05105843830110cad2338e0af145a682d4708 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 27 Oct 2024 17:45:36 +0100 Subject: [PATCH 22/65] Fix `vips_isprefix()` argument order (#4225) The arguments were reversed, likely due to confusion with `g_str_has_prefix()`. Ensures all metadata is removed when saving with `keep=none`. See: #4224. --- libvips/foreign/foreign.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index acc1a74097..7e72610a1d 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1722,8 +1722,8 @@ vips_foreign_save_remove_metadata(VipsImage *image, VipsForeignKeep keep = *((VipsForeignKeep *) user_data); // we are only interested in metadata - if (!vips_isprefix(field, "png-comment-") && - !vips_isprefix(field, "magickprofile-") && + if (!vips_isprefix("png-comment-", field) && + !vips_isprefix("magickprofile-", field) && strcmp(field, VIPS_META_IMAGEDESCRIPTION) != 0 && !g_str_has_suffix(field, "-data")) return NULL; From 94502d8928f6838d0af57f2fa63bb54d51a85fc9 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 31 Oct 2024 15:17:45 +0000 Subject: [PATCH 23/65] add support for multipage jxl (#4231) * add support for multipage jxl Multipage JXL images are just animations with the duration param set to 0xffffffff. This PR detects animations with this magick value for all frames and represents them as libvips multipage images (no duration metadata). A matching change in jxlsave sets duration to 0xffffffff for multipage images. * Update libvips/foreign/jxlsave.c Co-authored-by: Kleis Auke Wolthuizen --------- Co-authored-by: Kleis Auke Wolthuizen --- ChangeLog | 4 ++ libvips/foreign/jxlload.c | 131 +++++++++++++++++--------------------- libvips/foreign/jxlsave.c | 24 +++++-- meson.build | 4 +- 4 files changed, 82 insertions(+), 81 deletions(-) diff --git a/ChangeLog b/ChangeLog index a604cfec50..bc230b2ef7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +8.16.1 + +- support multipage JXL + 10/10/24 8.16.0 - allow small offsets for the PDF magic string [project0] diff --git a/libvips/foreign/jxlload.c b/libvips/foreign/jxlload.c index 8e4bd0b538..59c09f189c 100644 --- a/libvips/foreign/jxlload.c +++ b/libvips/foreign/jxlload.c @@ -104,8 +104,12 @@ typedef struct _VipsForeignLoadJxl { uint8_t *xmp_data; int frame_count; - int *delay; - int delay_count; + GArray *delay; + + /* JXL multipage and animated images are the same, but multipage has + * all the frame delays set to -1 (duration 0xffffffff). + */ + gboolean is_animated; /* The current accumulated frame as a VipsImage. These are the pixels * we send to the output. It's a info->xsize * info->ysize memory @@ -166,7 +170,7 @@ vips_foreign_load_jxl_dispose(GObject *gobject) VIPS_FREE(jxl->icc_data); VIPS_FREE(jxl->exif_data); VIPS_FREE(jxl->xmp_data); - VIPS_FREE(jxl->delay); + VIPS_FREEF(g_array_unref, jxl->delay); VIPS_UNREF(jxl->frame); VIPS_UNREF(jxl->source); @@ -492,8 +496,7 @@ vips_foreign_load_jxl_read_frame(VipsForeignLoadJxl *jxl, VipsImage *frame, int skip = frame_no - jxl->frame_no - 1; if (skip > 0) { #ifdef DEBUG_VERBOSE - printf("vips_foreign_load_jxl_read_frame: skipping %d frames\n", - skip); + printf("vips_foreign_load_jxl_read_frame: skipping %d frames\n", skip); #endif /*DEBUG_VERBOSE*/ JxlDecoderSkipFrames(jxl->decoder, skip); jxl->frame_no += skip; @@ -504,8 +507,7 @@ vips_foreign_load_jxl_read_frame(VipsForeignLoadJxl *jxl, VipsImage *frame, do { switch ((status = vips_foreign_load_jxl_process(jxl))) { case JXL_DEC_ERROR: - vips_foreign_load_jxl_error(jxl, - "JxlDecoderProcessInput"); + vips_foreign_load_jxl_error(jxl, "JxlDecoderProcessInput"); return -1; case JXL_DEC_FRAME: @@ -514,24 +516,19 @@ vips_foreign_load_jxl_read_frame(VipsForeignLoadJxl *jxl, VipsImage *frame, case JXL_DEC_NEED_IMAGE_OUT_BUFFER: if (JxlDecoderImageOutBufferSize(jxl->decoder, - &jxl->format, - &buffer_size)) { + &jxl->format, &buffer_size)) { vips_foreign_load_jxl_error(jxl, "JxlDecoderImageOutBufferSize"); return -1; } - if (buffer_size != - VIPS_IMAGE_SIZEOF_IMAGE(frame)) { - vips_error(class->nickname, - "%s", _("bad buffer size")); + if (buffer_size != VIPS_IMAGE_SIZEOF_IMAGE(frame)) { + vips_error(class->nickname, "%s", _("bad buffer size")); return -1; } - if (JxlDecoderSetImageOutBuffer(jxl->decoder, - &jxl->format, + if (JxlDecoderSetImageOutBuffer(jxl->decoder, &jxl->format, VIPS_IMAGE_ADDR(frame, 0, 0), VIPS_IMAGE_SIZEOF_IMAGE(frame))) { - vips_foreign_load_jxl_error(jxl, - "JxlDecoderSetImageOutBuffer"); + vips_foreign_load_jxl_error(jxl, "JxlDecoderSetImageOutBuffer"); return -1; } break; @@ -551,8 +548,7 @@ vips_foreign_load_jxl_read_frame(VipsForeignLoadJxl *jxl, VipsImage *frame, /* We didn't find the required frame */ - vips_error(class->nickname, - "%s", _("not enough frames")); + vips_error(class->nickname, "%s", _("not enough frames")); return -1; } @@ -633,8 +629,7 @@ vips_foreign_load_jxl_set_header(VipsForeignLoadJxl *jxl, VipsImage *out) if (jxl->info.xsize >= VIPS_MAX_COORD || jxl->info.ysize >= VIPS_MAX_COORD) { - vips_error(class->nickname, - "%s", _("image size out of bounds")); + vips_error(class->nickname, "%s", _("image size out of bounds")); return -1; } @@ -704,27 +699,26 @@ vips_foreign_load_jxl_set_header(VipsForeignLoadJxl *jxl, VipsImage *out) if (jxl->page < 0 || jxl->n <= 0 || jxl->page + jxl->n > jxl->frame_count) { - vips_error(class->nickname, - "%s", _("bad page number")); + vips_error(class->nickname, "%s", _("bad page number")); return -1; } vips_image_set_int(out, VIPS_META_N_PAGES, jxl->frame_count); if (jxl->n > 1) - vips_image_set_int(out, - VIPS_META_PAGE_HEIGHT, jxl->info.ysize); + vips_image_set_int(out, VIPS_META_PAGE_HEIGHT, jxl->info.ysize); - g_assert(jxl->delay_count >= jxl->frame_count); - vips_image_set_array_int(out, - "delay", jxl->delay, jxl->frame_count); + if (jxl->is_animated) { + int *delay = (int *) jxl->delay->data; - /* gif uses centiseconds for delays - */ - vips_image_set_int(out, "gif-delay", - VIPS_RINT(jxl->delay[0] / 10.0)); + vips_image_set_array_int(out, "delay", delay, jxl->frame_count); + + /* gif uses centiseconds for delays + */ + vips_image_set_int(out, "gif-delay", VIPS_RINT(delay[0] / 10.0)); - vips_image_set_int(out, "loop", jxl->info.animation.num_loops); + vips_image_set_int(out, "loop", jxl->info.animation.num_loops); + } } else { jxl->n = 1; @@ -759,8 +753,7 @@ vips_foreign_load_jxl_set_header(VipsForeignLoadJxl *jxl, VipsImage *out) if (jxl->icc_data && jxl->icc_size > 0) { vips_image_set_blob(out, VIPS_META_ICC_NAME, - (VipsCallbackFn) vips_area_free_cb, - jxl->icc_data, jxl->icc_size); + (VipsCallbackFn) vips_area_free_cb, jxl->icc_data, jxl->icc_size); jxl->icc_data = NULL; jxl->icc_size = 0; } @@ -768,8 +761,7 @@ vips_foreign_load_jxl_set_header(VipsForeignLoadJxl *jxl, VipsImage *out) if (jxl->exif_data && jxl->exif_size > 0) { vips_image_set_blob(out, VIPS_META_EXIF_NAME, - (VipsCallbackFn) vips_area_free_cb, - jxl->exif_data, jxl->exif_size); + (VipsCallbackFn) vips_area_free_cb, jxl->exif_data, jxl->exif_size); jxl->exif_data = NULL; jxl->exif_size = 0; } @@ -777,14 +769,12 @@ vips_foreign_load_jxl_set_header(VipsForeignLoadJxl *jxl, VipsImage *out) if (jxl->xmp_data && jxl->xmp_size > 0) { vips_image_set_blob(out, VIPS_META_XMP_NAME, - (VipsCallbackFn) vips_area_free_cb, - jxl->xmp_data, jxl->xmp_size); + (VipsCallbackFn) vips_area_free_cb, jxl->xmp_data, jxl->xmp_size); jxl->xmp_data = NULL; jxl->xmp_size = 0; } - vips_image_set_int(out, - VIPS_META_ORIENTATION, jxl->info.orientation); + vips_image_set_int(out, VIPS_META_ORIENTATION, jxl->info.orientation); vips_image_set_int(out, VIPS_META_BITS_PER_SAMPLE, jxl->info.bits_per_sample); @@ -795,7 +785,6 @@ vips_foreign_load_jxl_set_header(VipsForeignLoadJxl *jxl, VipsImage *out) static int vips_foreign_load_jxl_header(VipsForeignLoad *load) { - VipsObjectClass *class = VIPS_OBJECT_GET_CLASS(load); VipsForeignLoadJxl *jxl = (VipsForeignLoadJxl *) load; JxlDecoderStatus status; @@ -815,8 +804,7 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) JXL_DEC_BASIC_INFO | JXL_DEC_BOX | JXL_DEC_FRAME)) { - vips_foreign_load_jxl_error(jxl, - "JxlDecoderSubscribeEvents"); + vips_foreign_load_jxl_error(jxl, "JxlDecoderSubscribeEvents"); return -1; } @@ -825,8 +813,7 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) if (vips_foreign_load_jxl_fill_input(jxl, 0) < 0) return -1; - JxlDecoderSetInput(jxl->decoder, - jxl->input_buffer, jxl->bytes_in_buffer); + JxlDecoderSetInput(jxl->decoder, jxl->input_buffer, jxl->bytes_in_buffer); jxl->frame_count = 0; @@ -919,21 +906,17 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) #ifndef HAVE_LIBJXL_0_9 &jxl->format, #endif - JXL_COLOR_PROFILE_TARGET_DATA, - &jxl->icc_size)) { + JXL_COLOR_PROFILE_TARGET_DATA, &jxl->icc_size)) { vips_foreign_load_jxl_error(jxl, "JxlDecoderGetICCProfileSize"); return -1; } #ifdef DEBUG - printf( - "vips_foreign_load_jxl_header: " - "%zd byte profile\n", + printf("vips_foreign_load_jxl_header: %zd byte profile\n", jxl->icc_size); #endif /*DEBUG*/ - if (!(jxl->icc_data = vips_malloc(NULL, - jxl->icc_size))) + if (!(jxl->icc_data = vips_malloc(NULL, jxl->icc_size))) return -1; if (JxlDecoderGetColorAsICCProfile(jxl->decoder, @@ -950,35 +933,25 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) case JXL_DEC_FRAME: if (JxlDecoderGetFrameHeader(jxl->decoder, &h) != JXL_DEC_SUCCESS) { - vips_foreign_load_jxl_error(jxl, - "JxlDecoderGetFrameHeader"); + vips_foreign_load_jxl_error(jxl, "JxlDecoderGetFrameHeader"); return -1; } if (jxl->info.have_animation) { - if (jxl->delay_count <= jxl->frame_count) { - jxl->delay_count += 128; - int *new_delay = g_try_realloc(jxl->delay, - jxl->delay_count * sizeof(int)); - if (!new_delay) { - vips_error(class->nickname, "%s", _("out of memory")); - return -1; - } - jxl->delay = new_delay; - } - - jxl->delay[jxl->frame_count] = VIPS_RINT(1000.0 * h.duration * - jxl->info.animation.tps_denominator / - jxl->info.animation.tps_numerator); + // tick duration in seconds + 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); + // h.duration of 0xffffffff is used for multipage JXL ... map + // this to -1 in delay + int duration = h.duration == 0xffffffff ? -1 : ms; + + jxl->delay = g_array_append_vals(jxl->delay, &duration, 1); } jxl->frame_count++; - /* This is the last frame, we can stop right here - */ - if (h.is_last || !jxl->info.have_animation) - status = JXL_DEC_SUCCESS; - break; default: @@ -986,6 +959,15 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) } } while (status != JXL_DEC_SUCCESS); + /* Detect JXL multipage (rather than animated). + */ + int *delay = (int *) jxl->delay->data; + for (int i = 0; i < jxl->delay->len; i++) + if (delay[i] != -1) { + jxl->is_animated = TRUE; + break; + } + /* Flush box data if any */ if (vips_foreign_load_jxl_release_box_buffer(jxl)) @@ -1113,6 +1095,7 @@ static void vips_foreign_load_jxl_init(VipsForeignLoadJxl *jxl) { jxl->n = 1; + jxl->delay = g_array_new(FALSE, FALSE, sizeof(int)); } typedef struct _VipsForeignLoadJxlFile { diff --git a/libvips/foreign/jxlsave.c b/libvips/foreign/jxlsave.c index de32dc40b5..83011cbd67 100644 --- a/libvips/foreign/jxlsave.c +++ b/libvips/foreign/jxlsave.c @@ -87,6 +87,11 @@ typedef struct _VipsForeignSaveJxl { gboolean lossless; int Q; + /* JXL multipage and animated images are the same, but multipage has + * all the frame delays set to -1 (duration 0xffffffff). + */ + gboolean is_animated; + /* Animated jxl options. */ int gif_delay; @@ -319,7 +324,9 @@ vips_foreign_save_jxl_add_frame(VipsForeignSaveJxl *jxl) JxlFrameHeader header; memset(&header, 0, sizeof(JxlFrameHeader)); - if (jxl->delay && jxl->page_number < jxl->delay_length) + 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; @@ -593,6 +600,8 @@ vips_foreign_save_jxl_build(VipsObject *object) 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; @@ -670,10 +679,8 @@ vips_foreign_save_jxl_build(VipsObject *object) jxl->format.num_channels < 3); } - if (JxlEncoderSetColorEncoding(jxl->encoder, - &jxl->color_encoding)) { - vips_foreign_save_jxl_error(jxl, - "JxlEncoderSetColorEncoding"); + if (JxlEncoderSetColorEncoding(jxl->encoder, &jxl->color_encoding)) { + vips_foreign_save_jxl_error(jxl, "JxlEncoderSetColorEncoding"); return -1; } } @@ -703,6 +710,13 @@ vips_foreign_save_jxl_build(VipsObject *object) &jxl->delay, &jxl->delay_length)) return -1; + /* If there's delay metadata, this is an animated image (as opposed to + * a multipage one). + */ + 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. diff --git a/meson.build b/meson.build index 8a7be996f0..21797c1b6f 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('vips', 'c', 'cpp', - version: '8.16.0', + version: '8.16.1', meson_version: '>=0.55', default_options: [ # this is what glib uses (one of our required deps), so we use it too @@ -23,7 +23,7 @@ version_patch = version_parts[2] # binary interface changed: increment current, reset revision to 0 # binary interface changes backwards compatible?: increment age # binary interface changes not backwards compatible?: reset age to 0 -library_revision = 0 +library_revision = 1 library_current = 60 library_age = 18 library_version = '@0@.@1@.@2@'.format(library_current - library_age, library_age, library_revision) From 2ad79077b74f6f0a5801ad23a9b8ddfb7fc6f12a Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 2 Nov 2024 11:06:17 +0100 Subject: [PATCH 24/65] Improve `--vips-config` for internal dependencies (#4236) Dependencies created using `declare_dependency()` does not have a version number or name. Mirrors commit ec432a5. --- libvips/include/vips/meson.build | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libvips/include/vips/meson.build b/libvips/include/vips/meson.build index 31dd7adf7e..17bf777c79 100644 --- a/libvips/include/vips/meson.build +++ b/libvips/include/vips/meson.build @@ -106,8 +106,11 @@ foreach _, section : build_summary endforeach foreach _, section : build_features foreach key, arr : section + dep_name = arr[0] found = arr[1].found() - dep_name = found ? arr[1].name() : arr[0] + if found and arr[1].type_name() != 'internal' + dep_name = arr[1].name() + endif dynamic_module = arr.length() > 2 ? ' (dynamic module: @0@)'.format(arr[2]) : '' vips_verbose_config += '@0@ with @1@: @2@@3@'.format(key, dep_name, found, dynamic_module) endforeach From 2aca66dbccb0cf5cecd8272b6065fc0f4691ce2b Mon Sep 17 00:00:00 2001 From: Adam Goode Date: Sun, 3 Nov 2024 07:08:02 -0500 Subject: [PATCH 25/65] Never set the PFM header to little endian (#4242) Never set the PFM header to little endian PFM files are always written in big endian: https://github.com/libvips/libvips/blob/master/libvips/foreign/ppmsave.c#L459 But the header is set to little endian if on a big endian machine (!) https://github.com/libvips/libvips/blob/master/libvips/foreign/ppmsave.c#L414-L415 Fixes #4241. --- ChangeLog | 4 ++ libvips/foreign/jxlload.c | 68 ++++++++++++++++++++++++++++---- libvips/foreign/ppmsave.c | 3 -- libvips/include/vips/resample.h | 2 + libvips/resample/reduce.c | 2 + libvips/resample/reduceh.cpp | 6 +++ libvips/resample/templates.h | 52 ++++++++++++++++++++++++ meson.build | 8 ++-- test/test-suite/test_resample.py | 6 ++- 9 files changed, 134 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc230b2ef7..05927e3190 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +8.17.0 + +- add Magic Kernel support [akimon658] + 8.16.1 - support multipage JXL diff --git a/libvips/foreign/jxlload.c b/libvips/foreign/jxlload.c index 59c09f189c..c53e8f5ab2 100644 --- a/libvips/foreign/jxlload.c +++ b/libvips/foreign/jxlload.c @@ -439,6 +439,56 @@ vips_foreign_load_jxl_print_format(JxlPixelFormat *format) printf(" endianness = %d\n", format->endianness); printf(" align = %zd\n", format->align); } + +static const char * +vips_foreign_load_jxl_blend_mode(JxlBlendMode blendmode) +{ + switch (blendmode) { + case JXL_BLEND_REPLACE: + return "JXL_BLEND_REPLACE"; + + case JXL_BLEND_ADD: + return "JXL_BLEND_ADD"; + + case JXL_BLEND_BLEND: + return "JXL_BLEND_BLEND"; + + case JXL_BLEND_MULADD: + return "JXL_BLEND_MULADD"; + + case JXL_BLEND_MUL: + return "JXL_BLEND_MUL"; + + default: + return "duration); + printf(" timecode = %u\n", h->timecode); + printf(" name_length = %u\n", h->name_length); + printf(" is_last = %s\n", h->is_last ? "TRUE" : "FALSE"); + printf(" layer_info.have_crop = %s\n", + h->layer_info.have_crop ? "TRUE" : "FALSE"); + printf(" layer_info.crop_x0 = %d\n", h->layer_info.crop_x0); + printf(" layer_info.crop_y0 = %d\n", h->layer_info.crop_y0); + printf(" layer_info.xsize = %u\n", h->layer_info.xsize); + printf(" layer_info.ysize = %u\n", h->layer_info.ysize); + printf(" layer_info.blend_info.blendmode = %s\n", + vips_foreign_load_jxl_blend_mode(h->layer_info.blend_info.blendmode)); + printf(" layer_info.blend_info.source = %u\n", + h->layer_info.blend_info.source); + printf(" layer_info.blend_info.alpha = %u\n", + h->layer_info.blend_info.alpha); + printf(" layer_info.blend_info.clamp = %s\n", + h->layer_info.blend_info.clamp ? "TRUE" : "FALSE"); + printf(" layer_info.save_as_reference = %u\n", + h->layer_info.save_as_reference); +} #endif /*DEBUG*/ static JxlDecoderStatus @@ -455,9 +505,9 @@ vips_foreign_load_jxl_process(VipsForeignLoadJxl *jxl) size_t bytes_remaining; int bytes_read; -#ifdef DEBUG +#ifdef DEBUG_VERBOSE printf("vips_foreign_load_jxl_process: reading ...\n"); -#endif /*DEBUG*/ +#endif /*DEBUG_VERBOSE*/ bytes_remaining = JxlDecoderReleaseInput(jxl->decoder); bytes_read = vips_foreign_load_jxl_fill_input(jxl, bytes_remaining); @@ -498,6 +548,7 @@ vips_foreign_load_jxl_read_frame(VipsForeignLoadJxl *jxl, VipsImage *frame, #ifdef DEBUG_VERBOSE printf("vips_foreign_load_jxl_read_frame: skipping %d frames\n", skip); #endif /*DEBUG_VERBOSE*/ + JxlDecoderSkipFrames(jxl->decoder, skip); jxl->frame_no += skip; } @@ -822,8 +873,7 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) do { switch ((status = vips_foreign_load_jxl_process(jxl))) { case JXL_DEC_ERROR: - vips_foreign_load_jxl_error(jxl, - "JxlDecoderProcessInput"); + vips_foreign_load_jxl_error(jxl, "JxlDecoderProcessInput"); return -1; case JXL_DEC_BOX: @@ -907,8 +957,7 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) &jxl->format, #endif JXL_COLOR_PROFILE_TARGET_DATA, &jxl->icc_size)) { - vips_foreign_load_jxl_error(jxl, - "JxlDecoderGetICCProfileSize"); + vips_foreign_load_jxl_error(jxl, "JxlDecoderGetICCProfileSize"); return -1; } @@ -937,6 +986,10 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) return -1; } +#ifdef DEBUG + vips_foreign_load_jxl_print_frame_header(&h); +#endif /*DEBUG*/ + if (jxl->info.have_animation) { // tick duration in seconds double tick = (double) jxl->info.animation.tps_denominator / @@ -1010,8 +1063,7 @@ vips_foreign_load_jxl_load(VipsForeignLoad *load) JxlDecoderRewind(jxl->decoder); if (JxlDecoderSubscribeEvents(jxl->decoder, - JXL_DEC_FRAME | - JXL_DEC_FULL_IMAGE)) { + JXL_DEC_FRAME | JXL_DEC_FULL_IMAGE)) { vips_foreign_load_jxl_error(jxl, "JxlDecoderSubscribeEvents"); return -1; diff --git a/libvips/foreign/ppmsave.c b/libvips/foreign/ppmsave.c index da3f4dff99..3461a1bc45 100644 --- a/libvips/foreign/ppmsave.c +++ b/libvips/foreign/ppmsave.c @@ -411,9 +411,6 @@ vips_foreign_save_ppm_build(VipsObject *object) !vips_image_get_double(image, "pfm-scale", &scale)) ; - if (vips_amiMSBfirst()) - scale *= -1; - /* Need to be locale independent. */ g_ascii_dtostr(buf, G_ASCII_DTOSTR_BUF_SIZE, scale); diff --git a/libvips/include/vips/resample.h b/libvips/include/vips/resample.h index 7a87972f95..d71a8de509 100644 --- a/libvips/include/vips/resample.h +++ b/libvips/include/vips/resample.h @@ -45,6 +45,8 @@ typedef enum { VIPS_KERNEL_MITCHELL, VIPS_KERNEL_LANCZOS2, VIPS_KERNEL_LANCZOS3, + VIPS_KERNEL_MKS2013, + VIPS_KERNEL_MKS2021, VIPS_KERNEL_LAST } VipsKernel; diff --git a/libvips/resample/reduce.c b/libvips/resample/reduce.c index dd3c1566dd..94fb8088b6 100644 --- a/libvips/resample/reduce.c +++ b/libvips/resample/reduce.c @@ -66,6 +66,8 @@ * @VIPS_KERNEL_MITCHELL: Convolve with a Mitchell kernel. * @VIPS_KERNEL_LANCZOS2: Convolve with a two-lobe Lanczos kernel. * @VIPS_KERNEL_LANCZOS3: Convolve with a three-lobe Lanczos kernel. + * @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. */ diff --git a/libvips/resample/reduceh.cpp b/libvips/resample/reduceh.cpp index 3258eea708..4e369c92e9 100644 --- a/libvips/resample/reduceh.cpp +++ b/libvips/resample/reduceh.cpp @@ -125,6 +125,12 @@ vips_reduce_get_points(VipsKernel kernel, double shrink) case VIPS_KERNEL_LANCZOS3: return 2 * rint(3 * shrink) + 1; + case VIPS_KERNEL_MKS2013: + return 2 * rint(3 * shrink) + 1; + + case VIPS_KERNEL_MKS2021: + return 2 * rint(5 * shrink) + 1; + default: g_assert_not_reached(); return 0; diff --git a/libvips/resample/templates.h b/libvips/resample/templates.h index 49a56b5ae5..30e28af739 100644 --- a/libvips/resample/templates.h +++ b/libvips/resample/templates.h @@ -402,6 +402,48 @@ double inline filter(double x) return 0.0; } +template <> +double inline filter(double x) +{ + if (x < 0.0) + x = -x; + + if (x >= 2.5) + return 0.0; + + if (x >= 1.5) + return (x - 5.0 / 2.0) * (x - 5.0 / 2.0) / -8.0; + + if (x >= 0.5) + return (4.0 * x * x - 11.0 * x + 7.0) / 4.0; + + return 17.0 / 16.0 - 7.0 * x * x / 4.0; +} + +template <> +double inline filter(double x) +{ + if (x < 0.0) + x = -x; + + if (x >= 4.5) + return 0.0; + + if (x >= 3.5) + return (4.0 * x * x - 36.0 * x + 81.0) / -1152.0; + + if (x >= 2.5) + return (4.0 * x * x - 27.0 * x + 45.0) / 144.0; + + if (x >= 1.5) + return (24.0 * x * x - 113.0 * x + 130.0) / -144.0; + + if (x >= 0.5) + return (140.0 * x * x - 379.0 * x + 239.0) / 144.0; + + return 577.0 / 576.0 - 239.0 * x * x / 144.0; +} + /* Given an x in [0,1] (we can have x == 1 when building tables), * calculate c0 .. c(@n_points), the coefficients. This is called * from the interpolator as well as from the table builder. @@ -469,6 +511,16 @@ vips_reduce_make_mask(T *c, VipsKernel kernel, const int n_points, filter, shrink, x); break; + case VIPS_KERNEL_MKS2013: + calculate_coefficients(c, n_points, + filter, shrink, x); + break; + + case VIPS_KERNEL_MKS2021: + calculate_coefficients(c, n_points, + filter, shrink, x); + break; + default: g_assert_not_reached(); break; diff --git a/meson.build b/meson.build index 21797c1b6f..7f9a94d30d 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('vips', 'c', 'cpp', - version: '8.16.1', + version: '8.17.0', meson_version: '>=0.55', default_options: [ # this is what glib uses (one of our required deps), so we use it too @@ -23,9 +23,9 @@ version_patch = version_parts[2] # binary interface changed: increment current, reset revision to 0 # binary interface changes backwards compatible?: increment age # binary interface changes not backwards compatible?: reset age to 0 -library_revision = 1 -library_current = 60 -library_age = 18 +library_revision = 0 +library_current = 61 +library_age = 19 library_version = '@0@.@1@.@2@'.format(library_current - library_age, library_age, library_revision) darwin_versions = [library_current + 1, '@0@.@1@'.format(library_current + 1, library_revision)] diff --git a/test/test-suite/test_resample.py b/test/test-suite/test_resample.py index 7bb65b2fc5..55c92eb53c 100644 --- a/test/test-suite/test_resample.py +++ b/test/test-suite/test_resample.py @@ -83,7 +83,8 @@ def test_reduce(self): for fac in [1, 1.1, 1.5, 1.999]: for fmt in all_formats: for kernel in ["nearest", "linear", - "cubic", "lanczos2", "lanczos3"]: + "cubic", "lanczos2", + "lanczos3", "mks2013", "mks2021"]: x = im.cast(fmt) r = x.reduce(fac, fac, kernel=kernel) d = abs(r.avg() - im.avg()) @@ -93,7 +94,8 @@ def test_reduce(self): for const in [0, 1, 2, 254, 255]: im = (pyvips.Image.black(10, 10) + const).cast("uchar") for kernel in ["nearest", "linear", - "cubic", "lanczos2", "lanczos3"]: + "cubic", "lanczos2", + "lanczos3", "mks2013", "mks2021"]: # print "testing kernel =", kernel # print "testing const =", const shr = im.reduce(2, 2, kernel=kernel) From 9e82dc63df95f80fe64e5f31d91e4e07914c19ed Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 3 Nov 2024 12:11:59 +0000 Subject: [PATCH 26/65] Revert "Never set the PFM header to little endian (#4242)" This reverts commit 2aca66dbccb0cf5cecd8272b6065fc0f4691ce2b. --- ChangeLog | 4 -- libvips/foreign/jxlload.c | 68 ++++---------------------------- libvips/foreign/ppmsave.c | 3 ++ libvips/include/vips/resample.h | 2 - libvips/resample/reduce.c | 2 - libvips/resample/reduceh.cpp | 6 --- libvips/resample/templates.h | 52 ------------------------ meson.build | 8 ++-- test/test-suite/test_resample.py | 6 +-- 9 files changed, 17 insertions(+), 134 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05927e3190..bc230b2ef7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,3 @@ -8.17.0 - -- add Magic Kernel support [akimon658] - 8.16.1 - support multipage JXL diff --git a/libvips/foreign/jxlload.c b/libvips/foreign/jxlload.c index c53e8f5ab2..59c09f189c 100644 --- a/libvips/foreign/jxlload.c +++ b/libvips/foreign/jxlload.c @@ -439,56 +439,6 @@ vips_foreign_load_jxl_print_format(JxlPixelFormat *format) printf(" endianness = %d\n", format->endianness); printf(" align = %zd\n", format->align); } - -static const char * -vips_foreign_load_jxl_blend_mode(JxlBlendMode blendmode) -{ - switch (blendmode) { - case JXL_BLEND_REPLACE: - return "JXL_BLEND_REPLACE"; - - case JXL_BLEND_ADD: - return "JXL_BLEND_ADD"; - - case JXL_BLEND_BLEND: - return "JXL_BLEND_BLEND"; - - case JXL_BLEND_MULADD: - return "JXL_BLEND_MULADD"; - - case JXL_BLEND_MUL: - return "JXL_BLEND_MUL"; - - default: - return "duration); - printf(" timecode = %u\n", h->timecode); - printf(" name_length = %u\n", h->name_length); - printf(" is_last = %s\n", h->is_last ? "TRUE" : "FALSE"); - printf(" layer_info.have_crop = %s\n", - h->layer_info.have_crop ? "TRUE" : "FALSE"); - printf(" layer_info.crop_x0 = %d\n", h->layer_info.crop_x0); - printf(" layer_info.crop_y0 = %d\n", h->layer_info.crop_y0); - printf(" layer_info.xsize = %u\n", h->layer_info.xsize); - printf(" layer_info.ysize = %u\n", h->layer_info.ysize); - printf(" layer_info.blend_info.blendmode = %s\n", - vips_foreign_load_jxl_blend_mode(h->layer_info.blend_info.blendmode)); - printf(" layer_info.blend_info.source = %u\n", - h->layer_info.blend_info.source); - printf(" layer_info.blend_info.alpha = %u\n", - h->layer_info.blend_info.alpha); - printf(" layer_info.blend_info.clamp = %s\n", - h->layer_info.blend_info.clamp ? "TRUE" : "FALSE"); - printf(" layer_info.save_as_reference = %u\n", - h->layer_info.save_as_reference); -} #endif /*DEBUG*/ static JxlDecoderStatus @@ -505,9 +455,9 @@ vips_foreign_load_jxl_process(VipsForeignLoadJxl *jxl) size_t bytes_remaining; int bytes_read; -#ifdef DEBUG_VERBOSE +#ifdef DEBUG printf("vips_foreign_load_jxl_process: reading ...\n"); -#endif /*DEBUG_VERBOSE*/ +#endif /*DEBUG*/ bytes_remaining = JxlDecoderReleaseInput(jxl->decoder); bytes_read = vips_foreign_load_jxl_fill_input(jxl, bytes_remaining); @@ -548,7 +498,6 @@ vips_foreign_load_jxl_read_frame(VipsForeignLoadJxl *jxl, VipsImage *frame, #ifdef DEBUG_VERBOSE printf("vips_foreign_load_jxl_read_frame: skipping %d frames\n", skip); #endif /*DEBUG_VERBOSE*/ - JxlDecoderSkipFrames(jxl->decoder, skip); jxl->frame_no += skip; } @@ -873,7 +822,8 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) do { switch ((status = vips_foreign_load_jxl_process(jxl))) { case JXL_DEC_ERROR: - vips_foreign_load_jxl_error(jxl, "JxlDecoderProcessInput"); + vips_foreign_load_jxl_error(jxl, + "JxlDecoderProcessInput"); return -1; case JXL_DEC_BOX: @@ -957,7 +907,8 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) &jxl->format, #endif JXL_COLOR_PROFILE_TARGET_DATA, &jxl->icc_size)) { - vips_foreign_load_jxl_error(jxl, "JxlDecoderGetICCProfileSize"); + vips_foreign_load_jxl_error(jxl, + "JxlDecoderGetICCProfileSize"); return -1; } @@ -986,10 +937,6 @@ vips_foreign_load_jxl_header(VipsForeignLoad *load) return -1; } -#ifdef DEBUG - vips_foreign_load_jxl_print_frame_header(&h); -#endif /*DEBUG*/ - if (jxl->info.have_animation) { // tick duration in seconds double tick = (double) jxl->info.animation.tps_denominator / @@ -1063,7 +1010,8 @@ vips_foreign_load_jxl_load(VipsForeignLoad *load) JxlDecoderRewind(jxl->decoder); if (JxlDecoderSubscribeEvents(jxl->decoder, - JXL_DEC_FRAME | JXL_DEC_FULL_IMAGE)) { + JXL_DEC_FRAME | + JXL_DEC_FULL_IMAGE)) { vips_foreign_load_jxl_error(jxl, "JxlDecoderSubscribeEvents"); return -1; diff --git a/libvips/foreign/ppmsave.c b/libvips/foreign/ppmsave.c index 3461a1bc45..da3f4dff99 100644 --- a/libvips/foreign/ppmsave.c +++ b/libvips/foreign/ppmsave.c @@ -411,6 +411,9 @@ vips_foreign_save_ppm_build(VipsObject *object) !vips_image_get_double(image, "pfm-scale", &scale)) ; + if (vips_amiMSBfirst()) + scale *= -1; + /* Need to be locale independent. */ g_ascii_dtostr(buf, G_ASCII_DTOSTR_BUF_SIZE, scale); diff --git a/libvips/include/vips/resample.h b/libvips/include/vips/resample.h index d71a8de509..7a87972f95 100644 --- a/libvips/include/vips/resample.h +++ b/libvips/include/vips/resample.h @@ -45,8 +45,6 @@ typedef enum { VIPS_KERNEL_MITCHELL, VIPS_KERNEL_LANCZOS2, VIPS_KERNEL_LANCZOS3, - VIPS_KERNEL_MKS2013, - VIPS_KERNEL_MKS2021, VIPS_KERNEL_LAST } VipsKernel; diff --git a/libvips/resample/reduce.c b/libvips/resample/reduce.c index 94fb8088b6..dd3c1566dd 100644 --- a/libvips/resample/reduce.c +++ b/libvips/resample/reduce.c @@ -66,8 +66,6 @@ * @VIPS_KERNEL_MITCHELL: Convolve with a Mitchell kernel. * @VIPS_KERNEL_LANCZOS2: Convolve with a two-lobe Lanczos kernel. * @VIPS_KERNEL_LANCZOS3: Convolve with a three-lobe Lanczos kernel. - * @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. */ diff --git a/libvips/resample/reduceh.cpp b/libvips/resample/reduceh.cpp index 4e369c92e9..3258eea708 100644 --- a/libvips/resample/reduceh.cpp +++ b/libvips/resample/reduceh.cpp @@ -125,12 +125,6 @@ vips_reduce_get_points(VipsKernel kernel, double shrink) case VIPS_KERNEL_LANCZOS3: return 2 * rint(3 * shrink) + 1; - case VIPS_KERNEL_MKS2013: - return 2 * rint(3 * shrink) + 1; - - case VIPS_KERNEL_MKS2021: - return 2 * rint(5 * shrink) + 1; - default: g_assert_not_reached(); return 0; diff --git a/libvips/resample/templates.h b/libvips/resample/templates.h index 30e28af739..49a56b5ae5 100644 --- a/libvips/resample/templates.h +++ b/libvips/resample/templates.h @@ -402,48 +402,6 @@ double inline filter(double x) return 0.0; } -template <> -double inline filter(double x) -{ - if (x < 0.0) - x = -x; - - if (x >= 2.5) - return 0.0; - - if (x >= 1.5) - return (x - 5.0 / 2.0) * (x - 5.0 / 2.0) / -8.0; - - if (x >= 0.5) - return (4.0 * x * x - 11.0 * x + 7.0) / 4.0; - - return 17.0 / 16.0 - 7.0 * x * x / 4.0; -} - -template <> -double inline filter(double x) -{ - if (x < 0.0) - x = -x; - - if (x >= 4.5) - return 0.0; - - if (x >= 3.5) - return (4.0 * x * x - 36.0 * x + 81.0) / -1152.0; - - if (x >= 2.5) - return (4.0 * x * x - 27.0 * x + 45.0) / 144.0; - - if (x >= 1.5) - return (24.0 * x * x - 113.0 * x + 130.0) / -144.0; - - if (x >= 0.5) - return (140.0 * x * x - 379.0 * x + 239.0) / 144.0; - - return 577.0 / 576.0 - 239.0 * x * x / 144.0; -} - /* Given an x in [0,1] (we can have x == 1 when building tables), * calculate c0 .. c(@n_points), the coefficients. This is called * from the interpolator as well as from the table builder. @@ -511,16 +469,6 @@ vips_reduce_make_mask(T *c, VipsKernel kernel, const int n_points, filter, shrink, x); break; - case VIPS_KERNEL_MKS2013: - calculate_coefficients(c, n_points, - filter, shrink, x); - break; - - case VIPS_KERNEL_MKS2021: - calculate_coefficients(c, n_points, - filter, shrink, x); - break; - default: g_assert_not_reached(); break; diff --git a/meson.build b/meson.build index 7f9a94d30d..21797c1b6f 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('vips', 'c', 'cpp', - version: '8.17.0', + version: '8.16.1', meson_version: '>=0.55', default_options: [ # this is what glib uses (one of our required deps), so we use it too @@ -23,9 +23,9 @@ version_patch = version_parts[2] # binary interface changed: increment current, reset revision to 0 # binary interface changes backwards compatible?: increment age # binary interface changes not backwards compatible?: reset age to 0 -library_revision = 0 -library_current = 61 -library_age = 19 +library_revision = 1 +library_current = 60 +library_age = 18 library_version = '@0@.@1@.@2@'.format(library_current - library_age, library_age, library_revision) darwin_versions = [library_current + 1, '@0@.@1@'.format(library_current + 1, library_revision)] diff --git a/test/test-suite/test_resample.py b/test/test-suite/test_resample.py index 55c92eb53c..7bb65b2fc5 100644 --- a/test/test-suite/test_resample.py +++ b/test/test-suite/test_resample.py @@ -83,8 +83,7 @@ def test_reduce(self): for fac in [1, 1.1, 1.5, 1.999]: for fmt in all_formats: for kernel in ["nearest", "linear", - "cubic", "lanczos2", - "lanczos3", "mks2013", "mks2021"]: + "cubic", "lanczos2", "lanczos3"]: x = im.cast(fmt) r = x.reduce(fac, fac, kernel=kernel) d = abs(r.avg() - im.avg()) @@ -94,8 +93,7 @@ def test_reduce(self): for const in [0, 1, 2, 254, 255]: im = (pyvips.Image.black(10, 10) + const).cast("uchar") for kernel in ["nearest", "linear", - "cubic", "lanczos2", - "lanczos3", "mks2013", "mks2021"]: + "cubic", "lanczos2", "lanczos3"]: # print "testing kernel =", kernel # print "testing const =", const shr = im.reduce(2, 2, kernel=kernel) From f06db0f9161aa98a026dc7705eef3e33874316d6 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 3 Nov 2024 12:13:53 +0000 Subject: [PATCH 27/65] oop, fix the bad merge --- ChangeLog | 1 + libvips/foreign/ppmsave.c | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc230b2ef7..fad4829179 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 8.16.1 - support multipage JXL +- fix PFM byte order on little-endian machines [agoode] 10/10/24 8.16.0 diff --git a/libvips/foreign/ppmsave.c b/libvips/foreign/ppmsave.c index da3f4dff99..3461a1bc45 100644 --- a/libvips/foreign/ppmsave.c +++ b/libvips/foreign/ppmsave.c @@ -411,9 +411,6 @@ vips_foreign_save_ppm_build(VipsObject *object) !vips_image_get_double(image, "pfm-scale", &scale)) ; - if (vips_amiMSBfirst()) - scale *= -1; - /* Need to be locale independent. */ g_ascii_dtostr(buf, G_ASCII_DTOSTR_BUF_SIZE, scale); From b0e8d2a1a051f91230efa5e748bf653580554edb Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 3 Nov 2024 15:58:43 +0000 Subject: [PATCH 28/65] use VIPS_FMAX()/FMIN() in maxpair/minpair (#4244) These macros are faster and more accurate than VIPS_MAX() and VIPS_MIN for float values. See https://github.com/libvips/libvips/pull/4243 --- libvips/arithmetic/maxpair.c | 14 ++++++++++++-- libvips/arithmetic/minpair.c | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/libvips/arithmetic/maxpair.c b/libvips/arithmetic/maxpair.c index 8668bdfb59..85112cdb14 100644 --- a/libvips/arithmetic/maxpair.c +++ b/libvips/arithmetic/maxpair.c @@ -63,6 +63,16 @@ G_DEFINE_TYPE(VipsMaxpair, vips_maxpair, VIPS_TYPE_BINARY); q[x] = VIPS_MAX(left[x], right[x]); \ } +#define FLOOP(TYPE) \ + { \ + TYPE *restrict left = (TYPE *) in[0]; \ + TYPE *restrict right = (TYPE *) in[1]; \ + TYPE *restrict q = (TYPE *) out; \ +\ + for (int x = 0; x < sz; x++) \ + q[x] = VIPS_FMAX(left[x], right[x]); \ + } + static void maxpair_buffer(VipsArithmetic *arithmetic, VipsPel *out, VipsPel **in, int width) @@ -102,12 +112,12 @@ maxpair_buffer(VipsArithmetic *arithmetic, case VIPS_FORMAT_FLOAT: case VIPS_FORMAT_COMPLEX: - LOOP(float); + FLOOP(float); break; case VIPS_FORMAT_DOUBLE: case VIPS_FORMAT_DPCOMPLEX: - LOOP(double); + FLOOP(double); break; default: diff --git a/libvips/arithmetic/minpair.c b/libvips/arithmetic/minpair.c index 168fc942ca..6b4c653f20 100644 --- a/libvips/arithmetic/minpair.c +++ b/libvips/arithmetic/minpair.c @@ -63,6 +63,16 @@ G_DEFINE_TYPE(VipsMinpair, vips_minpair, VIPS_TYPE_BINARY); q[x] = VIPS_MIN(left[x], right[x]); \ } +#define FLOOP(TYPE) \ + { \ + TYPE *restrict left = (TYPE *) in[0]; \ + TYPE *restrict right = (TYPE *) in[1]; \ + TYPE *restrict q = (TYPE *) out; \ +\ + for (int x = 0; x < sz; x++) \ + q[x] = VIPS_FMIN(left[x], right[x]); \ + } + static void minpair_buffer(VipsArithmetic *arithmetic, VipsPel *out, VipsPel **in, int width) @@ -102,12 +112,12 @@ minpair_buffer(VipsArithmetic *arithmetic, case VIPS_FORMAT_FLOAT: case VIPS_FORMAT_COMPLEX: - LOOP(float); + FLOOP(float); break; case VIPS_FORMAT_DOUBLE: case VIPS_FORMAT_DPCOMPLEX: - LOOP(double); + FLOOP(double); break; default: From 9fe7ac3c07ff0dd64b3c4c4ef74dac361814bed1 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 4 Nov 2024 13:32:24 +0100 Subject: [PATCH 29/65] 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 30/65] 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 31/65] 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 32/65] 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 33/65] 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 34/65] 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 35/65] 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 36/65] 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 37/65] 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 38/65] 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 c0c6546a6544b3cc6e4ec6a4a73db7e6c929a6c7 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 26 Nov 2024 12:56:49 +0000 Subject: [PATCH 39/65] 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 40/65] 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 41/65] 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 c9d16c873501ea78eb3353f5a5af7a4302b96eec Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 30 Nov 2024 16:38:54 +0100 Subject: [PATCH 42/65] 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 3ba36cedcbec93283c88d2458ef030dea6becd9a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 4 Dec 2024 14:44:08 +0000 Subject: [PATCH 43/65] 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 33ab2ccfaa81e999bd7e2bf0375d461cef895279 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Mon, 16 Dec 2024 21:27:19 +0000 Subject: [PATCH 44/65] 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 10d28ce95ea55a391be8eb8fa55806d24bc53238 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 26 Dec 2024 13:46:28 +0000 Subject: [PATCH 45/65] 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 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 46/65] 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 47/65] 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 71602f24bf555c59f1fe3efcf99d69e1acc28698 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 11 Jan 2025 15:42:15 +0000 Subject: [PATCH 48/65] 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 dbe46d13db44a0e2baa703cd560d3f5661ab5c01 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Mon, 13 Jan 2025 11:41:21 +0000 Subject: [PATCH 49/65] 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 d7cc7b98fed1ded6222e617341a6c95417e2045d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 23 Jan 2025 13:51:43 +0000 Subject: [PATCH 50/65] 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 51/65] 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 52/65] 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 35cc76e9eb364725827499ba79171f27f9c9e61a Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 23 Jan 2025 16:28:52 +0100 Subject: [PATCH 53/65] 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 3848af5c96fb82bd748fd089e1cddf23e93f97ce Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 24 Jan 2025 19:22:56 +0100 Subject: [PATCH 54/65] 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 516fee518ef310af7c1d28e979f1f4db0d20e3e9 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 28 Jan 2025 11:50:29 +0100 Subject: [PATCH 55/65] 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 0bf64e9b123da13eee4c81e19d5f1b9c7bce8277 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 31 Jan 2025 18:59:55 +0000 Subject: [PATCH 56/65] 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 57/65] 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 beddac12972a0dbd9664995d51a7910e38dd10e2 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 7 Feb 2025 08:44:30 +0100 Subject: [PATCH 58/65] 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 ae14d974fe15fb788850db28cb28c318244e9763 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Tue, 11 Feb 2025 11:52:49 +0000 Subject: [PATCH 59/65] 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 9ab6784f693de50b00fa535b9efbbe9d2cbf71f2 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Wed, 19 Feb 2025 08:06:38 +0000 Subject: [PATCH 60/65] 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 1beb5dd241b27f8fb2608a220db5e51b4e4776cb Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 25 Feb 2025 18:27:06 +0100 Subject: [PATCH 61/65] 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 cce727b4abdb1dca7e6f0ed00989de78255787dc Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 28 Feb 2025 19:51:07 +0100 Subject: [PATCH 62/65] 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 abcb97c0e5c483f8dd8b07d1124e3548c4bb6bfb Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 5 Mar 2025 14:49:51 +0100 Subject: [PATCH 63/65] 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 64/65] 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 65/65] 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;