[gimp/gimp-2-10] plug-ins: fix #7524 DICOM File is broken



commit b44e7daf4cd750dfbbfb5fa287bd83a0fdeff96c
Author: Jacob Boerema <jgboerema gmail com>
Date:   Tue Jan 18 16:30:28 2022 -0500

    plug-ins: fix #7524 DICOM File is broken
    
    This is the same issue as with IM000001.dcm mentioned in issue #313.
    
    There are two problems: incorrect endian conversion for 16 bits per pixel,
    and not handling photometric interpretation "MONOCHROME1", which means
    minimum value is white instead of black.
    
    The endian conversion was fixed as suggested in issue #313.
    For "MONOCHROME1" we added a variable bw_inverted and we invert the pixel
    value if that variable is true.
    
    (cherry picked from commit e51ca66ee5397f527da309deea5f40d5e7cfef3f)

 plug-ins/common/file-dicom.c | 58 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 2 deletions(-)
---
diff --git a/plug-ins/common/file-dicom.c b/plug-ins/common/file-dicom.c
index 9807d97bc3..8bbebd5368 100644
--- a/plug-ins/common/file-dicom.c
+++ b/plug-ins/common/file-dicom.c
@@ -58,6 +58,7 @@ typedef struct _DicomInfo
   gint       high_bit;
   gboolean   is_signed;
   gboolean   planar;
+  gboolean   bw_inverted;
 } DicomInfo;
 
 /* Local function prototypes */
@@ -552,6 +553,8 @@ load_image (const gchar  *filename,
         }
       else if (group_word == 0x0028)
         {
+          gboolean supported = TRUE;
+
           switch (element_word)
             {
             case 0x0002:  /* samples per pixel */
@@ -559,7 +562,49 @@ load_image (const gchar  *filename,
               g_debug ("spp: %d", samples_per_pixel);
               break;
             case 0x0004:  /* photometric interpretation */
-              g_debug ("photometric interpretation: %s", (char*) value);
+              g_debug ("photometric interpretation: %s", (gchar *) value);
+
+              if (samples_per_pixel == 1)
+                {
+                  if (strncmp ((gchar *) value, "MONOCHROME1", 11) == 0)
+                    {
+                      /* The minimum sample value is intended to be displayed
+                       * as white after any VOI gray scale transformations
+                       * have been performed. */
+                      dicominfo->bw_inverted = TRUE;
+                    }
+                  else if (strncmp ((gchar *) value, "MONOCHROME2", 11) == 0)
+                    {
+                      /* The minimum sample value is intended to be displayed
+                       * as black after any VOI gray scale transformations
+                       * have been performed. */
+                      dicominfo->bw_inverted = FALSE;
+                    }
+                  else
+                    supported = FALSE;
+                }
+              else if (samples_per_pixel == 3)
+                {
+                  if (strncmp ((gchar *) value, "RGB", 2) != 0)
+                    {
+                      supported = FALSE;
+                    }
+                }
+              else
+                {
+                  supported = FALSE;
+                }
+              if (! supported)
+                {
+                  g_set_error (error, GIMP_PLUG_IN_ERROR, 0,
+                               _("%s is not supported by GIMP in combination "
+                                 "with samples per pixel: %d"),
+                               (gchar *) value, samples_per_pixel);
+                  g_free (dicominfo);
+                  fclose (dicom);
+                  return NULL;
+                }
+
               break;
             case 0x0006:  /* planar configuration */
               g_debug ("planar configuration: %u", ctx_us);
@@ -727,7 +772,7 @@ dicom_loader (guint8     *pix_buffer,
        * (i.e., compensate for high_bit and bits_stored).
        */
       for (pix_idx = 0; pix_idx < width * height * samples_per_pixel; pix_idx++)
-        buf16[pix_idx] = g_htons (buf16[pix_idx]) >> shift;
+        buf16[pix_idx] = g_ntohs (GUINT16_SWAP_LE_BE  (buf16[pix_idx])) >> shift;
     }
 
   data = g_malloc (gimp_tile_height () * width * samples_per_pixel);
@@ -762,6 +807,11 @@ dicom_loader (guint8     *pix_buffer,
                    */
                   d[col_idx] = (guint8) (row_start[col_idx] >>
                                          (info->bits_stored - 8));
+                  if (info->bw_inverted)
+                    {
+                      d[col_idx] = ~d[col_idx];
+                    }
+
                   if (info->is_signed)
                     {
                       /* If the data is negative, make it 0. Otherwise,
@@ -791,6 +841,10 @@ dicom_loader (guint8     *pix_buffer,
                        * less than bpp.
                        */
                       d[col_idx] = row_start[col_idx] << (8 - info->bits_stored);
+                      if (info->bw_inverted)
+                        {
+                          d[col_idx] = ~d[col_idx];
+                        }
 
                       if (info->is_signed)
                         {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]