From 0b301f2fd073a32e16117a00158bed53644e46ad Mon Sep 17 00:00:00 2001 From: Alx Sa Date: Sun, 9 Feb 2025 00:38:43 +0000 Subject: [PATCH] plug-ins: Support loading ARGB ICNS icons --- plug-ins/file-icns/file-icns-data.c | 1 + plug-ins/file-icns/file-icns-load.c | 43 ++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/plug-ins/file-icns/file-icns-data.c b/plug-ins/file-icns/file-icns-data.c index febb56ed4b..0ee2990690 100644 --- a/plug-ins/file-icns/file-icns-data.c +++ b/plug-ins/file-icns/file-icns-data.c @@ -76,6 +76,7 @@ IconType iconTypes[] = /* ARGB, PNG, or JPEG 2000 */ {"ic04", 16, 16, 0, "N/A", TRUE}, + {"ic05", 32, 32, 0, "N/A", TRUE}, {"icsb", 18, 18, 0, "N/A", TRUE}, {0, 0, 0, 0, 0} diff --git a/plug-ins/file-icns/file-icns-load.c b/plug-ins/file-icns/file-icns-load.c index e71a9acf2c..8a06e7ecff 100644 --- a/plug-ins/file-icns/file-icns-load.c +++ b/plug-ins/file-icns/file-icns-load.c @@ -54,6 +54,7 @@ void icns_slurp (guchar *dest, gboolean icns_decompress (guchar *dest, IconType *icontype, + gint n_channels, IcnsResource *image, IcnsResource *mask); @@ -283,6 +284,7 @@ icns_slurp (guchar *dest, gboolean icns_decompress (guchar *dest, IconType *icontype, + gint n_channels, IcnsResource *image, IcnsResource *mask) { @@ -291,7 +293,6 @@ icns_decompress (guchar *dest, guint out; guchar run; guchar val; - gint n_channels = 3; max = icontype->width * icontype->height; memset (dest, 255, max * 4); @@ -349,15 +350,31 @@ icns_decompress (guchar *dest, } } - if (mask) - { - gchar typestring[5]; - fourcc_get_string (mask->type, typestring); + /* If we have four channels, this is compressed ARGB data and + we need to rotate the channels */ + if (n_channels == 4) + { + gint pixel_max = max * 4; - for (out = 0; out < max; out++) - dest[out * 4 + 3] = mask->data[mask->cursor++]; - } - return TRUE; + for (gint i = 0; i < pixel_max; i += 4) + { + guchar alpha = dest[i]; + + for (gint j = 0; j < 3; j++) + dest[i + j] = dest[i + j + 1]; + + dest[i + 3] = alpha; + } + } + else if (mask) + { + gchar typestring[5]; + fourcc_get_string (mask->type, typestring); + + for (out = 0; out < max; out++) + dest[out * 4 + 3] = mask->data[mask->cursor++]; + } + return TRUE; } void @@ -419,6 +436,12 @@ icns_attach_image (GimpImage *image, temp_file_type = "jp2"; procedure_name = "file-jp2-load"; } + /* ARGB (compressed */ + else if (! strncmp (image_type, "ARGB", 4)) + { + icns->cursor += 4; + icns_decompress (dest, icontype, 4, icns, FALSE); + } if (temp_file_type && procedure_name) { @@ -469,7 +492,7 @@ icns_attach_image (GimpImage *image, if (icontype->bits != 32 || expected_size == icns->size) icns_slurp (dest, icontype, icns, mask); else - icns_decompress (dest, icontype, icns, mask); + icns_decompress (dest, icontype, 3, icns, mask); } if (! layer_loaded)