1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-02-12 11:46:10 +02:00

Fix importing ICC profiles for 16-bit images with an alpha channel

This commit is contained in:
DarthSim 2024-12-15 22:02:45 +03:00
parent 88af37f48d
commit 301ca08236
2 changed files with 47 additions and 4 deletions

View File

@ -22,6 +22,7 @@
- Fix detecting of width and height of HEIF images that include `irot` boxes.
- Set `Error` status for errorred traces in OpenTelemetry.
- Fix URL parsing error when a non-http(s) URL contains a `%` symbol outside of the percent-encoded sequence.
- Fix importing ICC profiles for 16-bit images with an alpha channel.
- (pro) Fix opject detection accuracy when using YOLOv8 or YOLOv10 models.
- (pro) Fix usage of the `obj` and `objw` gravity types inside the `crop` processing option.
- (pro) Fix detecting of width and height when orientation is specified in EXIF but EXIF info is not requested.

View File

@ -433,10 +433,52 @@ vips_has_embedded_icc(VipsImage *in)
int
vips_icc_import_go(VipsImage *in, VipsImage **out)
{
const int res = vips_icc_import(in, out, "embedded", TRUE, "pcs", vips_icc_get_pcs(in), NULL);
if (!res && *out)
vips_image_set_int(*out, "imgproxy-icc-imported", 1);
return res;
VipsImage *base = vips_image_new();
VipsImage **t = (VipsImage **) vips_object_local_array(VIPS_OBJECT(base), 5);
int has_alpha_16 = FALSE;
/* RGB16 and GREY16 images have max alpha 65535, but this is not handled by
* vips_icc_import. We need to extract the alpha channel and convert it to 0-255
*/
if ((in->Type == VIPS_INTERPRETATION_RGB16 && in->Bands > 3) ||
(in->Type == VIPS_INTERPRETATION_GREY16 && in->Bands > 1)) {
int bands = in->Type == VIPS_INTERPRETATION_RGB16 ? 3 : 1;
if (vips_extract_band(in, &t[0], 0, "n", bands, NULL) ||
vips_extract_band(in, &t[1], bands, "n", 1, NULL)) {
clear_image(&base);
return 1;
}
in = t[0];
has_alpha_16 = TRUE;
}
if (vips_icc_import(in, out, "embedded", TRUE, "pcs", vips_icc_get_pcs(in), NULL)) {
clear_image(&base);
return 1;
}
/* Convert 16-bit alpha channel to 0-255 range and join it back to the image
*/
if (has_alpha_16) {
t[2] = *out;
*out = NULL;
if (vips_cast(t[1], &t[3], t[2]->BandFmt, NULL) ||
vips_linear1(t[3], &t[4], 1.0 / 255.0, 0, NULL) ||
vips_bandjoin2(t[2], t[4], out, NULL)) {
clear_image(&base);
return 1;
}
}
vips_image_set_int(*out, "imgproxy-icc-imported", 1);
clear_image(&base);
return 0;
}
int