From 6a3f1964b96de884ca97a28750a0260551c85bb1 Mon Sep 17 00:00:00 2001 From: Solar Smith Date: Thu, 4 Dec 2025 16:23:21 -0500 Subject: [PATCH 1/2] Fix -I invert option for 2-color palette images (#8795) - Detect 2-color (1-bit) images and swap colormap entries when -I is used - Apply -G color replacements to colormap before expansion to RGB - Ensures -I option works correctly for 1-bit PNG images Fixes #8795 --- src/psimage.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/psimage.c b/src/psimage.c index 927b2872639..2b7d0c8bd4b 100644 --- a/src/psimage.c +++ b/src/psimage.c @@ -500,16 +500,28 @@ EXTERN_MSC int GMT_psimage (void *V_API, int mode, void *args) { if (I->colormap != NULL) { /* Image has a color map */ /* Convert colormap from integer to unsigned char and count colors */ n = gmt_unpack_rgbcolors (GMT, I, colormap); /* colormap will be RGBARGBA... */ - if (n == 2 && Ctrl->G.active) { /* Replace back or fore-ground color with color given in -G, or catch selection for transparency */ - if (Ctrl->G.rgb[PSIMAGE_TRA][0] != -2) { - GMT_Report (API, GMT_MSG_WARNING, "Your -G+t is ignored for 1-bit images; see +b/+f modifiers instead\n"); + if (n == 2) { /* 2-color palette image */ + /* Handle -I (invert) by swapping colormap entries */ + if (Ctrl->I.active) { + unsigned char tmp[4]; + for (size_t m = 0; m < 4; m++) { + tmp[m] = colormap[m]; + colormap[m] = colormap[4+m]; + colormap[4+m] = tmp[m]; + } } - for (unsigned int k = PSIMAGE_BGD; k <= PSIMAGE_FGD; k++) { - if (Ctrl->G.rgb[k][0] == -1) { /* Want this color to be transparent */ - has_trans = 1; r = colormap[4*k]; g = colormap[1+4*k]; b = colormap[2+4*k]; + /* Replace back or fore-ground color with color given in -G, or catch selection for transparency */ + if (Ctrl->G.active) { + if (Ctrl->G.rgb[PSIMAGE_TRA][0] != -2) { + GMT_Report (API, GMT_MSG_WARNING, "Your -G+t is ignored for 1-bit images; see +b/+f modifiers instead\n"); + } + for (unsigned int k = PSIMAGE_BGD; k <= PSIMAGE_FGD; k++) { + if (Ctrl->G.rgb[k][0] == -1) { /* Want this color to be transparent */ + has_trans = 1; r = colormap[4*k]; g = colormap[1+4*k]; b = colormap[2+4*k]; + } + else if (Ctrl->G.rgb[k][0] >= 0) /* If we changed this color, update it, else use what was given in the colormap */ + for (size_t m = 0; m < 3; m++) colormap[m+4*k] = gmt_M_u255(Ctrl->G.rgb[k][m]); /* Do not override the A entry, just R/G/B */ } - else if (Ctrl->G.rgb[k][0] >= 0) /* If we changed this color, update it, else use what was given in the colormap */ - for (n = 0; n < 3; n++) colormap[n+4*k] = gmt_M_u255(Ctrl->G.rgb[k][n]); /* Do not override the A entry, just R/G/B */ } } if (!Ctrl->G.active) has_trans = psimage_find_unique_color (GMT, colormap, n, &r, &g, &b); From bbc090f35fd7967eccce725dc61b6e75003b9fa8 Mon Sep 17 00:00:00 2001 From: Solar Smith Date: Tue, 9 Dec 2025 13:51:25 -0500 Subject: [PATCH 2/2] Add test for -I invert option on 2-color iages (#8795) - Tests normal image, inverted image, and inverted with color changes - Verifies fix for issue #8795 --- test/psimage/bitimage_invert.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100755 test/psimage/bitimage_invert.sh diff --git a/test/psimage/bitimage_invert.sh b/test/psimage/bitimage_invert.sh new file mode 100755 index 00000000000..35b678bc0e3 --- /dev/null +++ b/test/psimage/bitimage_invert.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Test -I option for inverting 2-color (1-bit) images +# This tests the fix for issue #8795 + +ps=bitimage_invert.ps + +# Normal image (black Vader on white background) +gmt psimage @vader1.png -P -Dx0/0+w2i -F+pfaint -K > $ps + +# Inverted image (white Vader on black background) using -I +gmt psimage @vader1.png -I -Dx2.5i/0+w2i -F+pfaint -O -K >> $ps + +# Inverted with color change: red background, yellow foreground +gmt psimage @vader1.png -I -Gred+b -Gyellow+f -Dx5i/0+w2i -F+pfaint -O >> $ps