File GraphicsMagick-dcm.c-update-2.patch of Package GraphicsMagick.9388

Index: GraphicsMagick-1.3.25/coders/dcm.c
===================================================================
--- GraphicsMagick-1.3.25.orig/coders/dcm.c	2018-06-13 20:15:45.674498775 +0200
+++ GraphicsMagick-1.3.25/coders/dcm.c	2018-06-13 20:16:37.039244592 +0200
@@ -1,5 +1,5 @@
 /*
-% Copyright (C) 2003-2017 GraphicsMagick Group
+% Copyright (C) 2003-2018 GraphicsMagick Group
 % Copyright (C) 2002 ImageMagick Studio
 % Copyright 1991-1999 E. I. du Pont de Nemours and Company
 %
@@ -183,7 +183,7 @@ typedef struct _DicomStream
     lower_lim;
 
   Quantum
-    *rescale_map;
+    *rescale_map; /* Allocated with dcm->max_value_in+1 entries */
 
 #if defined(USE_GRAYMAP)
   unsigned short
@@ -2851,6 +2851,7 @@ static MagickPassFail IsDCM(const unsign
 
 static MagickPassFail DCM_InitDCM(DicomStream *dcm,int verbose)
 {
+  (void) memset(dcm,0,sizeof(*dcm));
   dcm->columns=0;
   dcm->rows=0;
   dcm->samples_per_pixel=1;
@@ -2891,6 +2892,16 @@ static MagickPassFail DCM_InitDCM(DicomS
   return MagickPass;
 }
 
+static void DCM_DestroyDCM(DicomStream *dcm)
+{
+  MagickFreeMemory(dcm->offset_arr);
+  MagickFreeMemory(dcm->data);
+#if defined(USE_GRAYMAP)
+  MagickFreeMemory(dcm->graymap);
+#endif
+  MagickFreeMemory(dcm->rescale_map);
+}
+
 /*
   Parse functions for DICOM elements
 */
@@ -3110,9 +3121,18 @@ static MagickPassFail funcDCM_BitsStored
 
   dcm->significant_bits=dcm->datum;
   dcm->bytes_per_pixel=1;
+  if ((dcm->significant_bits == 0U) || (dcm->significant_bits > 16U))
+    {
+      if (image->logging)
+        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                              "DICOM significant_bits = %u",
+                              dcm->significant_bits);
+      ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+      return MagickFail;
+    }
   if (dcm->significant_bits > 8)
     dcm->bytes_per_pixel=2;
-  dcm->max_value_in=(1 << dcm->significant_bits)-1;
+  dcm->max_value_in=MaxValueGivenBits(dcm->significant_bits);
   dcm->max_value_out=dcm->max_value_in;
   image->depth=Min(dcm->significant_bits,QuantumDepth);
   return MagickPass;
@@ -3316,6 +3336,10 @@ static MagickPassFail funcDCM_Palette(Im
       return MagickFail;
     }
 
+  if (image->logging)
+    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                          "Palette with %" MAGICK_SIZE_T_F "u entries...",
+                          (MAGICK_SIZE_T) dcm->length);
   /*
     Initialize colormap (entries are always 16 bit)
     1201/2/3 = red/green/blue palette
@@ -3345,9 +3369,9 @@ static MagickPassFail funcDCM_Palette(Im
   for (i=0; i < (long) image->colors; i++)
     {
       if (dcm->msb_state == DCM_MSB_BIG)
-        index=(*p << 8) | *(p+1);
+        index=((unsigned short) *p << 8) | (unsigned short) *(p+1);
       else
-        index=*p | (*(p+1) << 8);
+        index=(unsigned short) *p | ((unsigned short) *(p+1) << 8);
       if (dcm->element == 0x1201)
         image->colormap[i].red=ScaleShortToQuantum(index);
       else if (dcm->element == 0x1202)
@@ -3408,7 +3432,8 @@ static magick_uint8_t DCM_RLE_ReadByte(I
 
 static magick_uint16_t DCM_RLE_ReadShort(Image *image, DicomStream *dcm)
 {
-  return (DCM_RLE_ReadByte(image,dcm) << 4) | DCM_RLE_ReadByte(image,dcm);
+  return (((magick_uint16_t) DCM_RLE_ReadByte(image,dcm) << 4) |
+          (magick_uint16_t) DCM_RLE_ReadByte(image,dcm));
 }
 
 static MagickPassFail DCM_ReadElement(Image *image, DicomStream *dcm,ExceptionInfo *exception)
@@ -3760,20 +3785,38 @@ static MagickPassFail DCM_SetupRescaleMa
     Xw_min,
     Xw_max;
 
-  unsigned long
+  unsigned int
     i;
 
   if (dcm->rescaling == DCM_RS_NONE)
     return MagickPass;
 
+  if (image->logging)
+    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                          "Set up rescale map for input range of %u"
+                          " (%u entries)...",
+                          dcm->max_value_in+1,MaxMap+1);
+
+  /*
+    The rescale map must be limited to MaxMap+1 entries, which is 256
+    or 65536, depending on QuantumDepth.  Using a QuantumDepth less
+    than 16 for DICOM is a bad idea.
+
+    The dcm->significant_bits value is limited to 16 (larger values
+    are outright rejected) so dcm->max_value_in and dcm->max_value_out
+    are limited to 65535.
+  */
+
   if (dcm->rescale_map == (Quantum *) NULL)
     {
-      dcm->rescale_map=MagickAllocateArray(Quantum *,dcm->max_value_in+1,sizeof(Quantum));
+      size_t num_entries = Max(MaxMap+1,dcm->max_value_in+1);
+      dcm->rescale_map=MagickAllocateArray(Quantum *,num_entries,sizeof(Quantum));
       if (dcm->rescale_map == NULL)
         {
           ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,image->filename);
           return MagickFail;
         }
+      (void) memset(dcm->rescale_map,0,num_entries*sizeof(Quantum));
     }
 
   if (dcm->window_width == 0)
@@ -3803,7 +3846,7 @@ static MagickPassFail DCM_SetupRescaleMa
   Xw_max = win_center - 0.5 + ((win_width-1)/2);
   for (i=0; i < (dcm->max_value_in+1); i++)
     {
-      if ((dcm->pixel_representation == 1) && (i >= (1U << (dcm->significant_bits-1))))
+      if ((dcm->pixel_representation == 1) && (i >= MaxValueGivenBits(dcm->significant_bits)))
         Xr = -((dcm->max_value_in+1-i) * dcm->rescale_slope) + dcm->rescale_intercept;
       else
         Xr = (i * dcm->rescale_slope) + dcm->rescale_intercept;
@@ -3815,8 +3858,9 @@ static MagickPassFail DCM_SetupRescaleMa
         dcm->rescale_map[i]=(Quantum)(((Xr-Xw_min)/(win_width-1))*dcm->max_value_out+0.5);
     }
   if (dcm->phot_interp == DCM_PI_MONOCHROME1)
-    for (i=0; i < (dcm->max_value_in+1); i++)
+    for (i=0; i <= dcm->max_value_in; i++)
       dcm->rescale_map[i]=dcm->max_value_out-dcm->rescale_map[i];
+
   return MagickPass;
 }
 
@@ -3882,6 +3926,15 @@ void DCM_SetRescaling(DicomStream *dcm,i
   dcm->rescaling=DCM_RS_PRE;
 }
 
+/*
+  FIXME: This code is totally broken since DCM_SetupRescaleMap
+  populates dcm->rescale_map and dcm->rescale_map has
+  dcm->max_value_in+1 entries, which has nothing to do with the number
+  of colormap entries or the range of MaxRGB.
+
+  Disabling this whole function and code invoking it until someone
+  figures it out.
+*/
 static MagickPassFail DCM_PostRescaleImage(Image *image,DicomStream *dcm,unsigned long ScanLimits,ExceptionInfo *exception)
 {
   unsigned long
@@ -3952,7 +4005,8 @@ static MagickPassFail DCM_PostRescaleIma
         }
     }
 
-  DCM_SetupRescaleMap(image,dcm,exception);
+  if (DCM_SetupRescaleMap(image,dcm,exception) == MagickFail)
+    return MagickFail;
   for (y=0; y < image->rows; y++)
     {
       q=GetImagePixels(image,0,y,image->columns,1);
@@ -3993,10 +4047,10 @@ static MagickPassFail DCM_PostRescaleIma
 
 static MagickPassFail DCM_ReadPaletteImage(Image *image,DicomStream *dcm,ExceptionInfo *exception)
 {
-  long
+  unsigned long
     y;
 
-  register long
+  register unsigned long
     x;
 
   register PixelPacket
@@ -4013,13 +4067,17 @@ static MagickPassFail DCM_ReadPaletteIma
 
   byte=0;
 
-  for (y=0; y < (long) image->rows; y++)
+  if (image->logging)
+    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                          "Reading Palette image...");
+
+  for (y=0; y < image->rows; y++)
     {
       q=SetImagePixels(image,0,y,image->columns,1);
       if (q == (PixelPacket *) NULL)
         return MagickFail;
       indexes=AccessMutableIndexes(image);
-      for (x=0; x < (long) image->columns; x++)
+      for (x=0; x < image->columns; x++)
         {
           if (dcm->bytes_per_pixel == 1)
             {
@@ -4075,6 +4133,8 @@ static MagickPassFail DCM_ReadPaletteIma
               index=(IndexPacket) (index);
               VerifyColormapIndex(image,index);
               indexes[x]=index;
+              *q=image->colormap[index];
+              q++;
             }
 
           if (EOFBlob(image))
@@ -4097,16 +4157,16 @@ static MagickPassFail DCM_ReadPaletteIma
 
 static MagickPassFail DCM_ReadGrayscaleImage(Image *image,DicomStream *dcm,ExceptionInfo *exception)
 {
-  long
+  unsigned long
     y;
 
-  register long
+  register unsigned long
     x;
 
   register PixelPacket
     *q;
 
-#if defined(GRAYSCALE_USES_PALETTE)
+#if defined(GRAYSCALE_USES_PALETTE) /* not used */
   register IndexPacket
     *indexes;
 #endif
@@ -4117,18 +4177,29 @@ static MagickPassFail DCM_ReadGrayscaleI
   unsigned char
     byte;
 
+  if (image->logging)
+    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                          "Reading Grayscale %lux%lu image...",image->columns,image->rows);
+
+#if !defined(GRAYSCALE_USES_PALETTE)
+  /*
+    If a palette was provided, the image may be in PseudoClass
+  */
+  image->storage_class=DirectClass;
+#endif
+
   dcm->lower_lim = dcm->max_value_in;
   dcm->upper_lim = -(dcm->lower_lim);
   byte=0;
-  for (y=0; y < (long) image->rows; y++)
+  for (y=0; y < image->rows; y++)
     {
-      q=SetImagePixels(image,0,y,image->columns,1);
+      q=SetImagePixelsEx(image,0,y,image->columns,1,exception);
       if (q == (PixelPacket *) NULL)
         return MagickFail;
-#if defined(GRAYSCALE_USES_PALETTE)
+#if defined(GRAYSCALE_USES_PALETTE) /* not used */
       indexes=AccessMutableIndexes(image);
 #endif
-      for (x=0; x < (long) image->columns; x++)
+      for (x=0; x < image->columns; x++)
         {
           if (dcm->bytes_per_pixel == 1)
             {
@@ -4181,17 +4252,21 @@ static MagickPassFail DCM_ReadGrayscaleI
               if ((int) l > dcm->upper_lim)
                 dcm->upper_lim = l;
             }
-#if defined(GRAYSCALE_USES_PALETTE)
+#if defined(GRAYSCALE_USES_PALETTE) /* not used */
           if (dcm->rescaling == DCM_RS_PRE)
             indexes[x]=dcm->rescale_map[index];
           else
             indexes[x]=index;
 #else
-          if (dcm->rescaling == DCM_RS_PRE)
-            index=dcm->rescale_map[index];
+          if ((dcm->rescaling == DCM_RS_PRE) &&
+              (dcm->rescale_map != (Quantum *) NULL))
+            {
+              index=dcm->rescale_map[index];
+            }
           q->red=index;
           q->green=index;
           q->blue=index;
+          q->opacity=OpaqueOpacity;
           q++;
 #endif
           if (EOFBlob(image))
@@ -4200,7 +4275,7 @@ static MagickPassFail DCM_ReadGrayscaleI
               return MagickFail;
             }
         }
-      if (!SyncImagePixels(image))
+      if (!SyncImagePixelsEx(image,exception))
         return MagickFail;
       if (image->previous == (Image *) NULL)
         if (QuantumTick(y,image->rows))
@@ -4222,13 +4297,28 @@ static MagickPassFail DCM_ReadPlanarRGBI
   register PixelPacket
     *q;
 
+  if (image->logging)
+    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                          "Reading Planar RGB %s compressed image with %u planes...",
+                          (dcm->transfer_syntax == DCM_TS_RLE ? "RLE" : "not"),
+                          dcm->samples_per_pixel);
+  /*
+    Force image to DirectClass since we are only updating DirectClass
+    representation.  The image may be in PseudoClass if we were
+    previously provided with a Palette.
+  */
+  image->storage_class=DirectClass;
+
   for (plane=0; plane < dcm->samples_per_pixel; plane++)
     {
+      if (image->logging)
+        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                              "  Plane %lu...",plane);
       for (y=0; y < image->rows; y++)
         {
           q=GetImagePixels(image,0,y,image->columns,1);
           if (q == (PixelPacket *) NULL)
-            return MagickFail;
+              return MagickFail;
 
           for (x=0; x < image->columns; x++)
             {
@@ -4297,6 +4387,17 @@ static MagickPassFail DCM_ReadRGBImage(I
   green=0;
   blue=0;
 
+  if (image->logging)
+    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                          "Reading RGB image...");
+
+  /*
+    Force image to DirectClass since we are only updating DirectClass
+    representation.  The image may be in PseudoClass if we were
+    previously provided with a Palette.
+  */
+  image->storage_class=DirectClass;
+
   for (y=0; y < image->rows; y++)
     {
       q=GetImagePixels(image,0,y,image->columns,1);
@@ -4339,7 +4440,8 @@ static MagickPassFail DCM_ReadRGBImage(I
           red&=dcm->max_value_in;
           green&=dcm->max_value_in;
           blue&=dcm->max_value_in;
-          if (dcm->rescaling == DCM_RS_PRE)
+          if ((dcm->rescaling == DCM_RS_PRE) &&
+              (dcm->rescale_map != (Quantum *) NULL))
             {
               red=dcm->rescale_map[red];
               green=dcm->rescale_map[green];
@@ -4349,6 +4451,7 @@ static MagickPassFail DCM_ReadRGBImage(I
           q->red=(Quantum) red;
           q->green=(Quantum) green;
           q->blue=(Quantum) blue;
+          q->opacity=OpaqueOpacity;
           q++;
           if (EOFBlob(image))
             {
@@ -4376,7 +4479,8 @@ static MagickPassFail DCM_ReadOffsetTabl
     length,
     i;
 
-  tag=(dcm->funcReadShort(image) << 16) | dcm->funcReadShort(image);
+  tag=((magick_uint32_t) dcm->funcReadShort(image) << 16) |
+    (magick_uint32_t) dcm->funcReadShort(image);
   length=dcm->funcReadLong(image);
   if (tag != 0xFFFEE000)
     return MagickFail;
@@ -4476,7 +4580,8 @@ static MagickPassFail DCM_ReadNonNativeI
           /*
             Read fragment tag
           */
-          tag=(dcm->funcReadShort(*image) << 16) | dcm->funcReadShort(*image);
+          tag=(((magick_uint32_t) dcm->funcReadShort(*image) << 16) |
+               (magick_uint32_t) dcm->funcReadShort(*image));
           length=dcm->funcReadLong(*image);
           if (EOFBlob(*image))
             {
@@ -4561,7 +4666,7 @@ static MagickPassFail DCM_ReadNonNativeI
                 dcm->bytes_per_pixel=1;
                 if (dcm->significant_bits > 8)
                   dcm->bytes_per_pixel=2;
-                dcm->max_value_in=(1 << dcm->significant_bits)-1;
+                dcm->max_value_in=MaxValueGivenBits(dcm->significant_bits);
                 dcm->max_value_out=dcm->max_value_in;
                 status=DCM_PostRescaleImage(next_image,dcm,True,exception);
               }
@@ -4574,11 +4679,33 @@ static MagickPassFail DCM_ReadNonNativeI
               else
                 AppendImageToList(&image_list,next_image);
             }
+          else if (next_image != (Image *) NULL)
+            {
+              DestroyImage(next_image);
+              next_image=(Image *) NULL;
+            }
         }
       (void) LiberateTemporaryFile(filename);
+
+      if (status == MagickFail)
+        break;
+    }
+  if (EOFBlob(*image))
+    {
+      status = MagickFail;
+      ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,(*image)->filename);
+    }
+
+  if (status == MagickFail)
+    {
+      DestroyImageList(image_list);
+      image_list = (Image *) NULL;
+    }
+  else
+    {
+      DestroyImage(*image);
+      *image=image_list;
     }
-  DestroyImage(*image);
-  *image=image_list;
   return status;
 }
 
@@ -4613,6 +4740,11 @@ static MagickPassFail DCM_ReadNonNativeI
 %
 %
 */
+#define ThrowDCMReaderException(code_,reason_,image_)   \
+  {                                                     \
+    DCM_DestroyDCM(&dcm);                               \
+    ThrowReaderException(code_,reason_,image_);         \
+}
 static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
 {
   char
@@ -4640,18 +4772,19 @@ static Image *ReadDCMImage(const ImageIn
   assert(image_info->signature == MagickSignature);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
+  (void) DCM_InitDCM(&dcm,image_info->verbose);
   image=AllocateImage(image_info);
   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
   if (status == MagickFail)
-    ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+    ThrowDCMReaderException(FileOpenError,UnableToOpenFile,image);
 
   /*
     Read DCM preamble
   */
   if ((count=ReadBlob(image,128,(char *) magick)) != 128)
-    ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+    ThrowDCMReaderException(CorruptImageError,UnexpectedEndOfFile,image);
   if ((count=ReadBlob(image,4,(char *) magick)) != 4)
-    ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+    ThrowDCMReaderException(CorruptImageError,UnexpectedEndOfFile,image);
   if (image->logging)
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                           "magick: \"%.4s\"",magick);
@@ -4661,7 +4794,6 @@ static Image *ReadDCMImage(const ImageIn
   /*
     Loop to read DCM image header one element at a time
   */
-  (void) DCM_InitDCM(&dcm,image_info->verbose);
   status=DCM_ReadElement(image,&dcm,exception);
   while ((status == MagickPass) && ((dcm.group != 0x7FE0) || (dcm.element != 0x0010)))
     {
@@ -4689,31 +4821,44 @@ static Image *ReadDCMImage(const ImageIn
     Now process the image data
   */
   if (status == MagickFail)
-    ;
-  else
-    if ((dcm.columns == 0) || (dcm.rows == 0))
-      {
-        ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
-        status=MagickFail;
-      }
-    else if ((dcm.transfer_syntax != DCM_TS_IMPL_LITTLE) &&
-             (dcm.transfer_syntax != DCM_TS_EXPL_LITTLE) &&
-             (dcm.transfer_syntax != DCM_TS_EXPL_BIG) &&
-             (dcm.transfer_syntax != DCM_TS_RLE))
-      {
-        status=DCM_ReadNonNativeImages(&image,image_info,&dcm,exception);
-        dcm.number_scenes=0;
-      }
-    else if (dcm.rescaling != DCM_RS_POST)
-      {
-        status=DCM_SetupRescaleMap(image,&dcm,exception);
-      }
+    goto dcm_read_failure;
+
+  if ((dcm.columns == 0) || (dcm.rows == 0))
+    {
+      ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+      status=MagickFail;
+    }
+  else if ((dcm.samples_per_pixel == 0) || (dcm.samples_per_pixel > 4))
+    {
+      ThrowException(exception,CorruptImageError,ImproperImageHeader,image->filename);
+      status=MagickFail;
+    }
+  else if ((dcm.transfer_syntax != DCM_TS_IMPL_LITTLE) &&
+           (dcm.transfer_syntax != DCM_TS_EXPL_LITTLE) &&
+           (dcm.transfer_syntax != DCM_TS_EXPL_BIG) &&
+           (dcm.transfer_syntax != DCM_TS_RLE))
+    {
+      status=DCM_ReadNonNativeImages(&image,image_info,&dcm,exception);
+      dcm.number_scenes=0;
+    }
+  else if (dcm.rescaling != DCM_RS_POST)
+    {
+      status=DCM_SetupRescaleMap(image,&dcm,exception);
+    }
+
+  if (status == MagickFail)
+    goto dcm_read_failure;
 
   if (dcm.transfer_syntax == DCM_TS_RLE)
     status=DCM_ReadOffsetTable(image,&dcm,exception);
 
   /* Loop to process all scenes in image */
-  if (status == MagickFail) dcm.number_scenes = 0;
+  if (image->logging)
+    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                          "DICOM has %d scenes", dcm.number_scenes);
+  if (status == MagickFail)
+    goto dcm_read_failure;
+
   for (scene=0; scene < (long) dcm.number_scenes; scene++)
     {
       if (dcm.transfer_syntax == DCM_TS_RLE)
@@ -4729,14 +4874,15 @@ static Image *ReadDCMImage(const ImageIn
             SeekBlob(image,dcm.frag_bytes,SEEK_CUR);
 
           /*
-           Read fragment tag
+            Read fragment tag
           */
-          tag=(dcm.funcReadShort(image) << 16) | dcm.funcReadShort(image);
+          tag=(((magick_uint32_t) dcm.funcReadShort(image)) << 16) |
+            (magick_uint32_t) dcm.funcReadShort(image);
           length=dcm.funcReadLong(image);
           if ((tag != 0xFFFEE000) || (length <= 64) || EOFBlob(image))
             {
               status=MagickFail;
-              ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+              ThrowDCMReaderException(CorruptImageError,UnexpectedEndOfFile,image);
               break;
             }
 
@@ -4756,7 +4902,7 @@ static Image *ReadDCMImage(const ImageIn
           if (EOFBlob(image))
             {
               status=MagickFail;
-              ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+              ThrowDCMReaderException(CorruptImageError,UnexpectedEndOfFile,image);
               break;
             }
           if (dcm.rle_seg_ct > 1)
@@ -4773,6 +4919,9 @@ static Image *ReadDCMImage(const ImageIn
       image->columns=dcm.columns;
       image->rows=dcm.rows;
       image->interlace=(dcm.interlace==1)?PlaneInterlace:NoInterlace;
+      if (image->logging)
+        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                              "Scene[%d]: %lux%lu", scene, image->columns, image->rows);
 #if defined(GRAYSCALE_USES_PALETTE)
       if ((image->colormap == (PixelPacket *) NULL) && (dcm.samples_per_pixel == 1))
 #else
@@ -4787,7 +4936,7 @@ static Image *ReadDCMImage(const ImageIn
         break;
 
       if (CheckImagePixelLimits(image, exception) != MagickPass)
-        ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
+        ThrowDCMReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
 
       /*
         Process image according to type
@@ -4813,15 +4962,23 @@ static Image *ReadDCMImage(const ImageIn
           ((dcm.phot_interp == DCM_PI_MONOCHROME1) ||
            (dcm.phot_interp == DCM_PI_MONOCHROME2)))
         {
+          if (image->logging)
+            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                  "Normalizing image channels...");
           NormalizeImage(image);
         }
       else
-        if (dcm.rescaling == DCM_RS_POST)
-          {
-            status = DCM_PostRescaleImage(image,&dcm,False,exception);
-            if (status != MagickPass)
-              break;
-          }
+        {
+          if (dcm.rescaling == DCM_RS_POST)
+            {
+              if (image->logging)
+                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                      "Rescaling image channels...");
+              status = DCM_PostRescaleImage(image,&dcm,False,exception);
+              if (status != MagickPass)
+                break;
+            }
+        }
 
       /*
         Proceed to next image.
@@ -4852,17 +5009,8 @@ static Image *ReadDCMImage(const ImageIn
   /*
     Free allocated resources
   */
-
-  if (dcm.offset_arr != NULL)
-    MagickFreeMemory(dcm.offset_arr);
-  if (dcm.data != NULL)
-    MagickFreeMemory(dcm.data);
-#if defined(USE_GRAYMAP)
-  if (dcm.graymap != (unsigned short *) NULL)
-    MagickFreeMemory(dcm.graymap);
-#endif
-  if (dcm.rescale_map != (Quantum *) NULL)
-    MagickFreeMemory(dcm.rescale_map);
+ dcm_read_failure:
+  DCM_DestroyDCM(&dcm);
   if (status == MagickPass)
     {
       /* It is possible to have success status yet have no image */
openSUSE Build Service is sponsored by