From 0ace6602486b04fa2e59f6fec6c03bc1b138f68a Mon Sep 17 00:00:00 2001 From: Alx Sa Date: Tue, 18 Jun 2024 12:32:04 +0000 Subject: [PATCH] plug-ins: Fix crash with OpenEXR chroma images The OpenEXR plugin was specifically set to throw an exception if a chroma image (Y/BY/RY) image was loaded. This patch removes the exception and loads the luminance channel only as a grayscale image, which is how Krita currently handles it. Future work is needed to properly convert the chroma channels to import as a RGB(A) image. --- plug-ins/file-exr/file-exr.c | 35 +++++++++++++++++----------- plug-ins/file-exr/openexr-wrapper.cc | 10 ++++---- plug-ins/file-exr/openexr-wrapper.h | 1 + 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/plug-ins/file-exr/file-exr.c b/plug-ins/file-exr/file-exr.c index 2fcc0b58d7..6d66cc1063 100644 --- a/plug-ins/file-exr/file-exr.c +++ b/plug-ins/file-exr/file-exr.c @@ -66,7 +66,7 @@ static GimpImage * load_image (GFile *file, gboolean interactive, GError **error); static void sanitize_comment (gchar *comment); -void load_dialog (void); +void load_dialog (EXRImageType image_type); G_DEFINE_TYPE (Exr, exr, GIMP_TYPE_PLUG_IN) @@ -244,6 +244,7 @@ load_image (GFile *file, image_type = GIMP_RGB; layer_type = has_alpha ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE; break; + case IMAGE_TYPE_YUV: case IMAGE_TYPE_GRAY: case IMAGE_TYPE_UNKNOWN_1_CHANNEL: image_type = GIMP_GRAY; @@ -267,9 +268,10 @@ load_image (GFile *file, goto out; } - if (exr_loader_get_image_type (loader) == IMAGE_TYPE_UNKNOWN_1_CHANNEL && - interactive) - load_dialog (); + if (interactive && + (exr_loader_get_image_type (loader) == IMAGE_TYPE_UNKNOWN_1_CHANNEL || + exr_loader_get_image_type (loader) == IMAGE_TYPE_YUV)) + load_dialog (exr_loader_get_image_type (loader)); /* try to load an icc profile, it will be generated on the fly if * chromaticities are given @@ -420,12 +422,12 @@ sanitize_comment (gchar *comment) } void -load_dialog (void) +load_dialog (EXRImageType image_type) { GtkWidget *dialog; GtkWidget *label; GtkWidget *vbox; - gchar *label_text; + gchar *label_text = NULL; gimp_ui_init (PLUG_IN_BINARY); @@ -441,11 +443,17 @@ load_dialog (void) gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), vbox, TRUE, TRUE, 0); - gtk_widget_show (vbox); + gtk_widget_set_visible (vbox, TRUE); + + if (image_type == IMAGE_TYPE_UNKNOWN_1_CHANNEL) + label_text = g_strdup_printf ("%s\n%s", _("Unknown Channel Name"), + _("The image contains a single unknown channel.\n" + "It has been converted to grayscale.")); + else if (image_type == IMAGE_TYPE_YUV) + label_text = g_strdup_printf ("%s\n%s", _("Chroma Channels"), + _("OpenEXR chroma channels are not yet supported.\n" + "They have been discarded.")); - label_text = g_strdup_printf ("%s\n%s", _("Unknown Channel Name"), - _("The image contains a single unknown channel.\n" - "It has been converted to grayscale.")); label = gtk_label_new (NULL); gtk_label_set_markup (GTK_LABEL (label), label_text); @@ -454,11 +462,12 @@ load_dialog (void) gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_label_set_yalign (GTK_LABEL (label), 0.0); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); + gtk_widget_set_visible (label, TRUE); - g_free (label_text); + if (label_text) + g_free (label_text); - gtk_widget_show (dialog); + gtk_widget_set_visible (dialog, TRUE); /* run the dialog */ gimp_dialog_run (GIMP_DIALOG (dialog)); diff --git a/plug-ins/file-exr/openexr-wrapper.cc b/plug-ins/file-exr/openexr-wrapper.cc index f4f7d477f7..700ee418fd 100644 --- a/plug-ins/file-exr/openexr-wrapper.cc +++ b/plug-ins/file-exr/openexr-wrapper.cc @@ -102,13 +102,12 @@ struct _EXRLoader (channels_.findChannel("RY") || channels_.findChannel("BY"))) { - format_string_ = "RGB"; - image_type_ = IMAGE_TYPE_RGB; + format_string_ = "Y'CbCr"; + image_type_ = IMAGE_TYPE_YUV; + /* TODO: Use RGBA interface to incorporate + * RY/BY chroma channels */ pt_ = channels_.findChannel("Y")->type; - - // FIXME: no chroma handling for now. - throw; } else if (channels_.findChannel("Y")) { @@ -194,6 +193,7 @@ struct _EXRLoader fb.insert(unknown_channel_name_, Slice(pt_, base, bpp, 0, 1, 1, 0.5)); break; + case IMAGE_TYPE_YUV: case IMAGE_TYPE_GRAY: fb.insert("Y", Slice(pt_, base, bpp, 0, 1, 1, 0.5)); if (hasAlpha()) diff --git a/plug-ins/file-exr/openexr-wrapper.h b/plug-ins/file-exr/openexr-wrapper.h index 22804ac8c5..0f42bcc229 100644 --- a/plug-ins/file-exr/openexr-wrapper.h +++ b/plug-ins/file-exr/openexr-wrapper.h @@ -35,6 +35,7 @@ typedef enum typedef enum { IMAGE_TYPE_RGB, + IMAGE_TYPE_YUV, IMAGE_TYPE_GRAY, IMAGE_TYPE_UNKNOWN_1_CHANNEL } EXRImageType;