[gimp/gimp-2-10] 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/gimp-2-10] plug-ins: fix #1146 DICOM with big endian transfer syntax fails to load.
- Date: Fri, 23 Jul 2021 19:38:19 +0000 (UTC)
commit e629e3e7d2dccd66853cc1b4b07eecd1ba5f47da
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.
(cherry picked from commit e0707af073e52003928d375859b72d5e413d5770)
# Conflicts:
# plug-ins/common/file-dicom.c
plug-ins/common/file-dicom.c | 65 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 53 insertions(+), 12 deletions(-)
---
diff --git a/plug-ins/common/file-dicom.c b/plug-ins/common/file-dicom.c
index 3314add95b..b3e9ec6334 100644
--- a/plug-ins/common/file-dicom.c
+++ b/plug-ins/common/file-dicom.c
@@ -331,6 +331,8 @@ load_image (const gchar *filename,
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_filename_to_utf8 (filename));
@@ -382,8 +384,6 @@ load_image (const gchar *filename,
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;
@@ -392,6 +392,12 @@ load_image (const gchar *filename,
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;
@@ -428,8 +434,12 @@ load_image (const gchar *filename,
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
@@ -437,17 +447,23 @@ load_image (const gchar *filename,
|| strncmp (value_rep, "SQ", 2) == 0
|| strncmp (value_rep, "UN", 2) == 0)
{
- 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));
+ fread (&element_length, 1, 2, dicom); /* skip two bytes */
+ fread (&element_length, 1, 4, dicom);
+ 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
{
guint16 el16;
- fread (&el16, 1, 2, DICOM);
- element_length = g_ntohs (GUINT16_SWAP_LE_BE (el16));
+ fread (&el16, 1, 2, dicom);
+ 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... */
@@ -490,7 +506,12 @@ load_image (const gchar *filename,
}
/* 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)
{
@@ -499,13 +520,33 @@ load_image (const gchar *filename,
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]