Commit af96d1487 for imagemagick.org
commit af96d14875a68f76c4057c03e879ad6d2d1d9ff4
Author: Greg B <64932474+gregbenz@users.noreply.github.com>
Date: Sun Sep 6 09:33:18 2026 -0500
fix: preserve UHDR resize filters (#8942)
diff --git a/MagickCore/resize.c b/MagickCore/resize.c
index e1d1149d3..b3825f63a 100644
--- a/MagickCore/resize.c
+++ b/MagickCore/resize.c
@@ -3825,7 +3825,7 @@ MagickExport Image *ResizeImage(const Image *image,const size_t columns,
if (resize_image != (Image *) NULL)
{
resize_filter=DestroyResizeFilter(resize_filter);
- return(resize_image);
+ goto record_resize_transform;
}
#endif
resize_image=CloneImage(image,columns,rows,MagickTrue,exception);
@@ -3874,14 +3874,17 @@ MagickExport Image *ResizeImage(const Image *image,const size_t columns,
return((Image *) NULL);
}
resize_image->type=image->type;
+#if defined(MAGICKCORE_OPENCL_SUPPORT)
+record_resize_transform:
+#endif
{
char
transform[MagickPathExtent];
(void) FormatLocaleString(transform,MagickPathExtent,
- "resize %.17gx%.17g %.17gx%.17g",(double) image->columns,
+ "resize %.17gx%.17g %.17gx%.17g %d",(double) image->columns,
(double) image->rows,(double) resize_image->columns,
- (double) resize_image->rows);
+ (double) resize_image->rows,(int) filter_type);
AppendImageProfileProperty(resize_image,"hdrgm","hdrgm:Transform",
transform,exception);
}
diff --git a/Makefile.in b/Makefile.in
index ddfde75e2..04fb2f3ad 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -6277,6 +6277,7 @@ TESTS_TESTS = \
tests/cli-svg.tap \
tests/cli-uhdr.tap \
tests/cli-uhdr-encoder.tap \
+ tests/cli-uhdr-resize-filter.tap \
tests/validate-colorspace.tap \
tests/validate-compare.tap \
tests/validate-composite.tap \
diff --git a/coders/uhdr.c b/coders/uhdr.c
index ad7e71aa2..552050d65 100644
--- a/coders/uhdr.c
+++ b/coders/uhdr.c
@@ -794,7 +794,7 @@ static MagickBooleanType CropGainMapImage(Image **gainmap_image,
static MagickBooleanType ResizeGainMapImage(Image **gainmap_image,
size_t *base_columns,size_t *base_rows,const size_t columns,
- const size_t rows,const Image *image,ExceptionInfo *exception)
+ const size_t rows,const FilterType filter_type,ExceptionInfo *exception)
{
Image
*resize_image;
@@ -812,7 +812,7 @@ static MagickBooleanType ResizeGainMapImage(Image **gainmap_image,
(target_rows != (*gainmap_image)->rows))
{
resize_image=ResizeImage(*gainmap_image,target_columns,target_rows,
- image->filter,exception);
+ filter_type,exception);
if (ReplaceGainMapImage(gainmap_image,resize_image) == MagickFalse)
return(MagickFalse);
}
@@ -839,6 +839,13 @@ static MagickBooleanType ApplyGainMapTransform(Image **gainmap_image,
size_t
rotations;
+ FilterType
+ filter_type;
+
+ int
+ fields,
+ filter_value;
+
if (LocaleNCompare(transform,"crop ",5) == 0)
{
if (sscanf(transform+5,"%lfx%lf %lfx%lf%lf%lf",&source_columns,
@@ -856,14 +863,26 @@ static MagickBooleanType ApplyGainMapTransform(Image **gainmap_image,
}
if (LocaleNCompare(transform,"resize ",7) == 0)
{
- if (sscanf(transform+7,"%lfx%lf %lfx%lf",&source_columns,
- &source_rows,&columns,&rows) != 4)
+ fields=sscanf(transform+7,"%lfx%lf %lfx%lf %d",&source_columns,
+ &source_rows,&columns,&rows,&filter_value);
+ if ((fields != 4) && (fields != 5))
return(MagickFalse);
+ filter_type=UndefinedFilter;
+ if (fields == 5)
+ {
+ if ((filter_value <= (int) UndefinedFilter) ||
+ (filter_value >= (int) SentinelFilter))
+ return(MagickFalse);
+ filter_type=(FilterType) filter_value;
+ }
+ else
+ filter_type=image->filter;
if (IsGainMapBaseGeometry(*base_columns,*base_rows,source_columns,
source_rows) == MagickFalse)
return(MagickFalse);
return(ResizeGainMapImage(gainmap_image,base_columns,base_rows,
- CastDoubleToSizeT(columns),CastDoubleToSizeT(rows),image,exception));
+ CastDoubleToSizeT(columns),CastDoubleToSizeT(rows),filter_type,
+ exception));
}
if (LocaleNCompare(transform,"flip ",5) == 0)
{
diff --git a/tests/Makefile.am b/tests/Makefile.am
index bf1ee4131..c1c61e32d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -46,6 +46,7 @@ TESTS_TESTS = \
tests/cli-svg.tap \
tests/cli-uhdr.tap \
tests/cli-uhdr-encoder.tap \
+ tests/cli-uhdr-resize-filter.tap \
tests/validate-colorspace.tap \
tests/validate-compare.tap \
tests/validate-composite.tap \
diff --git a/tests/cli-uhdr-resize-filter.tap b/tests/cli-uhdr-resize-filter.tap
new file mode 100755
index 000000000..e1ca0a3fb
--- /dev/null
+++ b/tests/cli-uhdr-resize-filter.tap
@@ -0,0 +1,126 @@
+#!/bin/sh
+# Regression tests for Ultra HDR gain-map resize filter replay.
+. ./common.shi
+. ${srcdir}/tests/common.shi
+
+resize_sdr=cli-uhdr-resize-filter-sdr.miff
+resize_hdr=cli-uhdr-resize-filter-hdr.miff
+resize_source=cli-uhdr-resize-filter-source.jpg
+resize_point=cli-uhdr-resize-filter-point.jpg
+resize_lanczos=cli-uhdr-resize-filter-lanczos.jpg
+resize_point_linear=cli-uhdr-resize-filter-point-linear.miff
+resize_lanczos_linear=cli-uhdr-resize-filter-lanczos-linear.miff
+legacy_output=cli-uhdr-resize-filter-legacy.jpg
+modern_output=cli-uhdr-resize-filter-modern.jpg
+legacy_linear=cli-uhdr-resize-filter-legacy-linear.miff
+modern_linear=cli-uhdr-resize-filter-modern-linear.miff
+default_point=cli-uhdr-resize-filter-default-point.jpg
+default_lanczos=cli-uhdr-resize-filter-default-lanczos.jpg
+default_point_linear=cli-uhdr-resize-filter-default-point-linear.miff
+default_lanczos_linear=cli-uhdr-resize-filter-default-lanczos-linear.miff
+
+cleanup()
+{
+ rm -f "$resize_sdr" "$resize_hdr" "$resize_source" "$resize_point" \
+ "$resize_lanczos" "$resize_point_linear" "$resize_lanczos_linear" \
+ "$legacy_output" "$modern_output" "$legacy_linear" "$modern_linear" \
+ "$default_point" "$default_lanczos" "$default_point_linear" \
+ "$default_lanczos_linear"
+}
+
+check_metric()
+{
+ description=$1
+ first=$2
+ second=$3
+ actual=`${MAGICK} compare -metric AE "$first" "$second" null: 2>&1`
+ status=$?
+ metric=`echo "$actual" | awk '{print $1}'`
+ if [ "$status" = "0" ] && [ "X$metric" = "X0" ]; then
+ echo "ok - $description"
+ else
+ echo "not ok - $description"
+ echo "# expected zero absolute error, got '$actual'"
+ fi
+}
+
+cleanup
+if ! ${MAGICK} -list configure 2>/dev/null | awk '
+ $1 == "DELEGATES" {
+ for (i=2; i <= NF; i++)
+ {
+ if ($i == "jpeg")
+ jpeg=1
+ if ($i == "uhdr")
+ uhdr=1
+ }
+ }
+ END { exit(jpeg && uhdr ? 0 : 1) }
+ '; then
+ echo "1..0 # SKIP JPEG or UHDR coder unavailable"
+ exit 0
+fi
+
+echo "1..3"
+if ! ${MAGICK} "${SRCDIR}/rose.pnm" -depth 8 "$resize_sdr" \
+ >/dev/null 2>&1 ||
+ ! ${MAGICK} "${SRCDIR}/rose.pnm" -depth 16 -evaluate multiply 1.4 \
+ "$resize_hdr" >/dev/null 2>&1 ||
+ ! ${MAGICK} "$resize_sdr" "$resize_hdr" \
+ -define uhdr:hdr-color-transfer=linear "UHDR:$resize_source" \
+ >/dev/null 2>&1; then
+ echo "Bail out! unable to create spatial gain-map fixture"
+ cleanup
+ exit 0
+fi
+
+if ${MAGICK} "UHDR:$resize_source" \
+ -filter point -resize 35x23 -filter box -resize 18x12 -filter point \
+ "UHDR:$resize_point" >/dev/null 2>&1 &&
+ ${MAGICK} "UHDR:$resize_source" \
+ -filter point -resize 35x23 -filter box -resize 18x12 -filter lanczos \
+ "UHDR:$resize_lanczos" >/dev/null 2>&1 &&
+ ${MAGICK} -define uhdr:output-color-transfer=linear \
+ "UHDR:$resize_point" "$resize_point_linear" >/dev/null 2>&1 &&
+ ${MAGICK} -define uhdr:output-color-transfer=linear \
+ "UHDR:$resize_lanczos" "$resize_lanczos_linear" >/dev/null 2>&1; then
+ check_metric "historical resize filters are independent of final filter" \
+ "$resize_point_linear" "$resize_lanczos_linear"
+else
+ echo "not ok - historical resize filters are independent of final filter"
+ echo "# unable to create or decode resize outputs"
+fi
+
+if ${MAGICK} "UHDR:$resize_source" -filter point -resize 35x23 \
+ -set hdrgm:Transform 'resize 70x46 35x23' -filter point \
+ "UHDR:$legacy_output" >/dev/null 2>&1 &&
+ ${MAGICK} "UHDR:$resize_source" -filter point -resize 35x23 \
+ -filter point "UHDR:$modern_output" >/dev/null 2>&1 &&
+ ${MAGICK} -define uhdr:output-color-transfer=linear \
+ "UHDR:$legacy_output" "$legacy_linear" >/dev/null 2>&1 &&
+ ${MAGICK} -define uhdr:output-color-transfer=linear \
+ "UHDR:$modern_output" "$modern_linear" >/dev/null 2>&1; then
+ check_metric "legacy four-field resize records remain compatible" \
+ "$legacy_linear" "$modern_linear"
+else
+ echo "not ok - legacy four-field resize records remain compatible"
+ echo "# unable to create or decode legacy outputs"
+fi
+
+if ${MAGICK} "UHDR:$resize_source" -resize 35x23 -filter point \
+ "UHDR:$default_point" >/dev/null 2>&1 &&
+ ${MAGICK} "UHDR:$resize_source" -resize 35x23 -filter lanczos \
+ "UHDR:$default_lanczos" >/dev/null 2>&1 &&
+ ${MAGICK} -define uhdr:output-color-transfer=linear \
+ "UHDR:$default_point" "$default_point_linear" >/dev/null 2>&1 &&
+ ${MAGICK} -define uhdr:output-color-transfer=linear \
+ "UHDR:$default_lanczos" "$default_lanczos_linear" >/dev/null 2>&1; then
+ check_metric "resolved default resize filter is recorded" \
+ "$default_point_linear" "$default_lanczos_linear"
+else
+ echo "not ok - resolved default resize filter is recorded"
+ echo "# unable to create or decode default-filter outputs"
+fi
+
+cleanup
+: