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.
This commit is contained in:
Alx Sa 2024-06-18 12:32:04 +00:00
parent bb9716d609
commit 0ace660248
3 changed files with 28 additions and 18 deletions

View File

@ -66,7 +66,7 @@ static GimpImage * load_image (GFile *file,
gboolean interactive, gboolean interactive,
GError **error); GError **error);
static void sanitize_comment (gchar *comment); 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) G_DEFINE_TYPE (Exr, exr, GIMP_TYPE_PLUG_IN)
@ -244,6 +244,7 @@ load_image (GFile *file,
image_type = GIMP_RGB; image_type = GIMP_RGB;
layer_type = has_alpha ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE; layer_type = has_alpha ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE;
break; break;
case IMAGE_TYPE_YUV:
case IMAGE_TYPE_GRAY: case IMAGE_TYPE_GRAY:
case IMAGE_TYPE_UNKNOWN_1_CHANNEL: case IMAGE_TYPE_UNKNOWN_1_CHANNEL:
image_type = GIMP_GRAY; image_type = GIMP_GRAY;
@ -267,9 +268,10 @@ load_image (GFile *file,
goto out; goto out;
} }
if (exr_loader_get_image_type (loader) == IMAGE_TYPE_UNKNOWN_1_CHANNEL && if (interactive &&
interactive) (exr_loader_get_image_type (loader) == IMAGE_TYPE_UNKNOWN_1_CHANNEL ||
load_dialog (); 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 /* try to load an icc profile, it will be generated on the fly if
* chromaticities are given * chromaticities are given
@ -420,12 +422,12 @@ sanitize_comment (gchar *comment)
} }
void void
load_dialog (void) load_dialog (EXRImageType image_type)
{ {
GtkWidget *dialog; GtkWidget *dialog;
GtkWidget *label; GtkWidget *label;
GtkWidget *vbox; GtkWidget *vbox;
gchar *label_text; gchar *label_text = NULL;
gimp_ui_init (PLUG_IN_BINARY); gimp_ui_init (PLUG_IN_BINARY);
@ -441,11 +443,17 @@ load_dialog (void)
gtk_container_set_border_width (GTK_CONTAINER (vbox), 12); gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
vbox, TRUE, TRUE, 0); 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 ("<b>%s</b>\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 ("<b>%s</b>\n%s", _("Chroma Channels"),
_("OpenEXR chroma channels are not yet supported.\n"
"They have been discarded."));
label_text = g_strdup_printf ("<b>%s</b>\n%s", _("Unknown Channel Name"),
_("The image contains a single unknown channel.\n"
"It has been converted to grayscale."));
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), label_text); 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_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_yalign (GTK_LABEL (label), 0.0); gtk_label_set_yalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 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 */ /* run the dialog */
gimp_dialog_run (GIMP_DIALOG (dialog)); gimp_dialog_run (GIMP_DIALOG (dialog));

View File

@ -102,13 +102,12 @@ struct _EXRLoader
(channels_.findChannel("RY") || (channels_.findChannel("RY") ||
channels_.findChannel("BY"))) channels_.findChannel("BY")))
{ {
format_string_ = "RGB"; format_string_ = "Y'CbCr";
image_type_ = IMAGE_TYPE_RGB; image_type_ = IMAGE_TYPE_YUV;
/* TODO: Use RGBA interface to incorporate
* RY/BY chroma channels */
pt_ = channels_.findChannel("Y")->type; pt_ = channels_.findChannel("Y")->type;
// FIXME: no chroma handling for now.
throw;
} }
else if (channels_.findChannel("Y")) 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)); fb.insert(unknown_channel_name_, Slice(pt_, base, bpp, 0, 1, 1, 0.5));
break; break;
case IMAGE_TYPE_YUV:
case IMAGE_TYPE_GRAY: case IMAGE_TYPE_GRAY:
fb.insert("Y", Slice(pt_, base, bpp, 0, 1, 1, 0.5)); fb.insert("Y", Slice(pt_, base, bpp, 0, 1, 1, 0.5));
if (hasAlpha()) if (hasAlpha())

View File

@ -35,6 +35,7 @@ typedef enum
typedef enum typedef enum
{ {
IMAGE_TYPE_RGB, IMAGE_TYPE_RGB,
IMAGE_TYPE_YUV,
IMAGE_TYPE_GRAY, IMAGE_TYPE_GRAY,
IMAGE_TYPE_UNKNOWN_1_CHANNEL IMAGE_TYPE_UNKNOWN_1_CHANNEL
} EXRImageType; } EXRImageType;