[gimp] plug-ins: fix #1146 DICOM with big endian transfer syntax fails to load.
- From: Jacob Boerema <jboerema src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plug-ins: fix #1146 DICOM with big endian transfer syntax fails to load.
- Date: Fri, 23 Jul 2021 19:26:07 +0000 (UTC)
commit e0707af073e52003928d375859b72d5e413d5770
Author: Jacob Boerema <jgboerema gmail com>
Date: Wed Jul 21 16:09:12 2021 -0400
plug-ins: fix #1146 DICOM with big endian transfer syntax fails to load.
Our plug-in was not correctly handling DICOM images that use big endian
transfer syntax, which is deprecated.
We add support for that here, add a few g_debug statements to make future
debugging easier, and also return an error when we encounter a transfer
syntax that we can't handle instead of blindly continuing.
plug-ins/common/file-dicom.c | 59 +++++++++++++++++++++++++++++++++++++-------
1 file changed, 50 insertions(+), 9 deletions(-)
---
diff --git a/plug-ins/common/file-dicom.c b/plug-ins/common/file-dicom.c
index ac37fe6afa..bc7a551fad 100644
--- a/plug-ins/common/file-dicom.c
+++ b/plug-ins/common/file-dicom.c
@@ -363,6 +363,8 @@ load_image (GFile *file,
guint8 *pix_buf = NULL;
gboolean is_signed = FALSE;
guint8 in_sequence = 0;
+ gboolean implicit_encoding = FALSE;
+ gboolean big_endian = FALSE;
gimp_progress_init_printf (_("Opening '%s'"),
gimp_file_get_utf8_name (file));
@@ -416,8 +418,6 @@ load_image (GFile *file,
guint16 ctx_us;
guint8 *value;
guint32 tag;
- gboolean __attribute__((unused))do_toggle_endian = FALSE;
- gboolean implicit_encoding = FALSE;
if (fread (&group_word, 1, 2, dicom) == 0)
break;
@@ -426,6 +426,12 @@ load_image (GFile *file,
fread (&element_word, 1, 2, dicom);
element_word = g_ntohs (GUINT16_SWAP_LE_BE (element_word));
+ if (group_word != 0x0002 && big_endian)
+ {
+ group_word = GUINT16_SWAP_LE_BE (group_word);
+ element_word = GUINT16_SWAP_LE_BE (element_word);
+ }
+
tag = (group_word << 16) | element_word;
fread(value_rep, 2, 1, dicom);
value_rep[2] = 0;
@@ -462,8 +468,12 @@ load_image (GFile *file,
fread (&element_length_chars[2], 1, 2, dicom);
/* Now cast to integer and insert into element_length */
- element_length =
- g_ntohl (GUINT32_SWAP_LE_BE (*((gint *) element_length_chars)));
+ if (big_endian && group_word != 0x0002)
+ element_length =
+ g_ntohl (*((gint *) element_length_chars));
+ else
+ element_length =
+ g_ntohl (GUINT32_SWAP_LE_BE (*((gint *) element_length_chars)));
}
/* Binary value reps are OB, OW, SQ or UN */
else if (strncmp (value_rep, "OB", 2) == 0
@@ -473,7 +483,10 @@ load_image (GFile *file,
{
fread (&element_length, 1, 2, dicom); /* skip two bytes */
fread (&element_length, 1, 4, dicom);
- element_length = g_ntohl (GUINT32_SWAP_LE_BE (element_length));
+ if (big_endian && group_word != 0x0002)
+ element_length = g_ntohl (element_length);
+ else
+ element_length = g_ntohl (GUINT32_SWAP_LE_BE (element_length));
}
/* Short length */
else
@@ -481,7 +494,10 @@ load_image (GFile *file,
guint16 el16;
fread (&el16, 1, 2, dicom);
- element_length = g_ntohs (GUINT16_SWAP_LE_BE (el16));
+ if (big_endian && group_word != 0x0002)
+ element_length = g_ntohs (el16);
+ else
+ element_length = g_ntohs (GUINT16_SWAP_LE_BE (el16));
}
/* Sequence of items - just ignore the delimiters... */
@@ -524,7 +540,12 @@ load_image (GFile *file,
}
/* Some special casts that are used below */
ctx_us = *(guint16 *) value;
+ if (big_endian && group_word != 0x0002)
+ ctx_us = GUINT16_SWAP_LE_BE (ctx_us);
+ g_debug ("group: %04x, element: %04x, length: %d",
+ group_word, element_word, element_length);
+ g_debug ("Value: %s", (char*)value);
/* Recognize some critical tags */
if (group_word == 0x0002)
{
@@ -533,13 +554,33 @@ load_image (GFile *file,
case 0x0010: /* transfer syntax id */
if (strcmp("1.2.840.10008.1.2", (char*)value) == 0)
{
- do_toggle_endian = FALSE;
implicit_encoding = TRUE;
+ g_debug ("Transfer syntax: Implicit VR Endian: Default Transfer Syntax for DICOM.");
}
else if (strcmp("1.2.840.10008.1.2.1", (char*)value) == 0)
- do_toggle_endian = FALSE;
+ {
+ g_debug ("Transfer syntax: Explicit VR Little Endian.");
+ }
+ else if (strcmp("1.2.840.10008.1.2.1.99", (char*)value) == 0)
+ {
+ g_debug ("Transfer syntax: Deflated Explicit VR Little Endian.");
+ }
else if (strcmp("1.2.840.10008.1.2.2", (char*)value) == 0)
- do_toggle_endian = TRUE;
+ {
+ /* This Transfer Syntax was retired in 2006. For the most recent description of it, see
PS3.5 2016b */
+ big_endian = TRUE;
+ g_debug ("Transfer syntax: Deprecated Explicit VR Big Endian.");
+ }
+ else
+ {
+ g_debug ("Transfer syntax %s is not supported by GIMP.", (gchar *) value);
+ g_set_error (error, GIMP_PLUG_IN_ERROR, 0,
+ _("Transfer syntax %s is not supported by GIMP."),
+ (gchar *) value);
+ g_free (dicominfo);
+ fclose (dicom);
+ return NULL;
+ }
break;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]