]> granicus.if.org Git - imagemagick/commitdiff
Refactored reading DCM pixels.
authordirk <dirk@git.imagemagick.org>
Fri, 30 Sep 2016 18:23:42 +0000 (20:23 +0200)
committerdirk <dirk@git.imagemagick.org>
Fri, 30 Sep 2016 18:23:42 +0000 (20:23 +0200)
coders/dcm.c

index 75489be9210da1369450ca4f36a58c50aa5fe283..43e1ec8c31321c856c019e28ff6a9e0eb08b8d7a 100644 (file)
@@ -2675,6 +2675,31 @@ static MagickBooleanType IsDCM(const unsigned char *magick,const size_t length)
 %    o exception: return any errors or warnings in this structure.
 %
 */
+typedef struct _DCMInfo
+{
+  MagickBooleanType
+    polarity;
+
+  Quantum
+    *scale;
+
+  size_t
+    bits_allocated,
+    bytes_per_pixel,
+    depth,
+    mask,
+    max_value,
+    samples_per_pixel,
+    signed_data,
+    significant_bits,
+    window_width;
+
+  ssize_t
+    rescale_intercept,
+    rescale_slope,
+    window_center;
+} DCMInfo;
+
 typedef struct _DCMStreamInfo
 {
   size_t
@@ -2776,6 +2801,169 @@ static signed short ReadDCMSignedShort(DCMStreamInfo *stream_info,Image *image)
   return(quantum.signed_value);
 }
 
+static MagickBooleanType ReadDCMPixels(Image *image,DCMInfo *info,
+  DCMStreamInfo *stream_info,MagickBooleanType first_segment,
+  ExceptionInfo *exception)
+{
+  int
+    byte,
+    index;
+
+  MagickBooleanType
+    status;
+
+  PixelPacket
+    pixel;
+
+  register ssize_t
+    i,
+    x;
+
+  register Quantum
+    *q;
+
+  ssize_t
+    y;
+
+  /*
+    Convert DCM Medical image to pixel packets.
+  */
+  byte=0;
+  i=0;
+  status=MagickTrue;
+  (void) ResetMagickMemory(&pixel,0,sizeof(pixel));
+  for (y=0; y < (ssize_t) image->rows; y++)
+  {
+    q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
+    if (q == (Quantum *) NULL)
+      break;
+    for (x=0; x < (ssize_t) image->columns; x++)
+    {
+      if (info->samples_per_pixel == 1)
+        {
+          int
+            pixel_value;
+
+          if (info->bytes_per_pixel == 1)
+            pixel_value=info->polarity != MagickFalse ?
+              ((int) info->max_value-ReadDCMByte(stream_info,image)) :
+              ReadDCMByte(stream_info,image);
+          else
+            if ((info->bits_allocated != 12) || (info->significant_bits != 12))
+              {
+                if (info->signed_data)
+                  pixel_value=ReadDCMSignedShort(stream_info,image);
+                else
+                  pixel_value=ReadDCMShort(stream_info,image);
+                if (info->polarity != MagickFalse)
+                  pixel_value=(int)info->max_value-pixel_value;
+              }
+            else
+              {
+                if ((i & 0x01) != 0)
+                  pixel_value=(ReadDCMByte(stream_info,image) << 8) |
+                    byte;
+                else
+                  {
+                    pixel_value=ReadDCMSignedShort(stream_info,image);
+                    byte=(int) (pixel_value & 0x0f);
+                    pixel_value>>=4;
+                  }
+                i++;
+              }
+          index=(pixel_value*info->rescale_slope)+info->rescale_intercept;
+          if (info->window_width == 0)
+            {
+              if (info->signed_data == 1)
+                index-=32767;
+            }
+          else
+            {
+              ssize_t
+                window_max,
+                window_min;
+
+              window_min=(ssize_t) ceil((double) info->window_center-
+                (info->window_width-1.0)/2.0-0.5);
+              window_max=(ssize_t) floor((double) info->window_center+
+                (info->window_width-1.0)/2.0+0.5);
+              if ((ssize_t)index <= window_min)
+                index=0;
+              else
+                if ((ssize_t)index > window_max)
+                  index=(int) info->max_value;
+                else
+                  index=(int) (info->max_value*(((index-info->window_center-
+                    0.5)/(info->window_width-1))+0.5));
+            }
+          index&=info->mask;
+          index=(int) ConstrainColormapIndex(image,(size_t) index,exception);
+          if (first_segment)
+            SetPixelIndex(image,(Quantum) index,q);
+          else
+            SetPixelIndex(image,(Quantum) (((size_t) GetPixelIndex(image,q)) |
+              (((size_t) index) << 8)),q);
+          pixel.red=(unsigned int) image->colormap[index].red;
+          pixel.green=(unsigned int) image->colormap[index].green;
+          pixel.blue=(unsigned int) image->colormap[index].blue;
+        }
+      else
+        {
+          if (info->bytes_per_pixel == 1)
+            {
+              pixel.red=(unsigned int) ReadDCMByte(stream_info,image);
+              pixel.green=(unsigned int) ReadDCMByte(stream_info,image);
+              pixel.blue=(unsigned int) ReadDCMByte(stream_info,image);
+            }
+          else
+            {
+              pixel.red=ReadDCMShort(stream_info,image);
+              pixel.green=ReadDCMShort(stream_info,image);
+              pixel.blue=ReadDCMShort(stream_info,image);
+            }
+          pixel.red&=info->mask;
+          pixel.green&=info->mask;
+          pixel.blue&=info->mask;
+          if (info->scale != (Quantum *) NULL)
+            {
+              if (pixel.red <= GetQuantumRange(info->depth))
+                pixel.red=info->scale[pixel.red];
+              if (pixel.green <= GetQuantumRange(info->depth))
+                pixel.green=info->scale[pixel.green];
+              if (pixel.blue <= GetQuantumRange(info->depth))
+                pixel.blue=info->scale[pixel.blue];
+            }
+        }
+      if (first_segment != MagickFalse)
+        {
+          SetPixelRed(image,(Quantum) pixel.red,q);
+          SetPixelGreen(image,(Quantum) pixel.green,q);
+          SetPixelBlue(image,(Quantum) pixel.blue,q);
+        }
+      else
+        {
+          SetPixelRed(image,(Quantum) (((size_t) GetPixelRed(image,q)) |
+            (((size_t) pixel.red) << 8)),q);
+          SetPixelGreen(image,(Quantum) (((size_t) GetPixelGreen(image,q)) |
+            (((size_t) pixel.green) << 8)),q);
+          SetPixelBlue(image,(Quantum) (((size_t) GetPixelBlue(image,q)) |
+            (((size_t) pixel.blue) << 8)),q);
+        }
+      q+=GetPixelChannels(image);
+    }
+    if (SyncAuthenticPixels(image,exception) == MagickFalse)
+      break;
+    if (image->previous == (Image *) NULL)
+      {
+        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
+          image->rows);
+        if (status == MagickFalse)
+          break;
+      }
+  }
+  return(status);
+}
+
 static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
 {
   char
@@ -2784,6 +2972,9 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
     magick[MagickPathExtent],
     photometric[MagickPathExtent];
 
+  DCMInfo
+    info;
+
   DCMStreamInfo
     *stream_info;
 
@@ -2795,57 +2986,35 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
     datum,
     *greenmap,
     *graymap,
-    index,
     *redmap;
 
   MagickBooleanType
     explicit_file,
     explicit_retry,
-    polarity,
     sequence,
     use_explicit;
 
   MagickOffsetType
     offset;
 
-  Quantum
-    *scale;
-
-  register ssize_t
-    i,
-    x;
-
-  register Quantum
-    *q;
-
   register unsigned char
     *p;
 
+  register ssize_t
+    i;
+
   size_t
-    bits_allocated,
-    bytes_per_pixel,
     colors,
-    depth,
     height,
     length,
-    mask,
-    max_value,
     number_scenes,
     quantum,
-    samples_per_pixel,
-    signed_data,
-    significant_bits,
     status,
-    width,
-    window_width;
+    width;
 
   ssize_t
     count,
-    rescale_intercept,
-    rescale_slope,
-    scene,
-    window_center,
-    y;
+    scene;
 
   unsigned char
     *data;
@@ -2894,11 +3063,21 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
     Read DCM Medical image.
   */
   (void) CopyMagickString(photometric,"MONOCHROME1 ",MagickPathExtent);
-  bits_allocated=8;
-  bytes_per_pixel=1;
-  polarity=MagickFalse;
+  info.bits_allocated=8;
+  info.bytes_per_pixel=1;
+  info.depth=8;
+  info.max_value=255UL;
+  info.mask=0xffff;
+  info.polarity=MagickFalse;
+  info.rescale_intercept=0;
+  info.rescale_slope=1;
+  info.samples_per_pixel=1;
+  info.scale=(Quantum *) NULL;
+  info.signed_data=(~0UL);
+  info.significant_bits=0;
+  info.window_center=0;
+  info.window_width=0;
   data=(unsigned char *) NULL;
-  depth=8;
   element=0;
   explicit_vr[2]='\0';
   explicit_file=MagickFalse;
@@ -2908,21 +3087,11 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
   bluemap=(int *) NULL;
   graymap=(int *) NULL;
   height=0;
-  max_value=255UL;
-  mask=0xffff;
   number_scenes=1;
-  rescale_intercept=0;
-  rescale_slope=1;
-  samples_per_pixel=1;
-  scale=(Quantum *) NULL;
   sequence=MagickFalse;
-  signed_data=(~0UL);
-  significant_bits=0;
   use_explicit=MagickFalse;
   explicit_retry = MagickFalse;
   width=0;
-  window_center=0;
-  window_width=0;
   for (group=0; (group != 0x7FE0) || (element != 0x0010) ||
                 (sequence != MagickFalse); )
   {
@@ -3208,7 +3377,7 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
             /*
               Samples per pixel.
             */
-            samples_per_pixel=(size_t) datum;
+            info.samples_per_pixel=(size_t) datum;
             break;
           }
           case 0x0004:
@@ -3221,7 +3390,7 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
             for (i=0; i < (ssize_t) MagickMin(length,MagickPathExtent-1); i++)
               photometric[i]=(char) data[i];
             photometric[i]='\0';
-            polarity=LocaleCompare(photometric,"MONOCHROME1 ") == 0 ?
+            info.polarity=LocaleCompare(photometric,"MONOCHROME1 ") == 0 ?
               MagickTrue : MagickFalse;
             break;
           }
@@ -3265,14 +3434,14 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
             /*
               Bits allocated.
             */
-            bits_allocated=(size_t) datum;
-            bytes_per_pixel=1;
+            info.bits_allocated=(size_t) datum;
+            info.bytes_per_pixel=1;
             if (datum > 8)
-              bytes_per_pixel=2;
-            depth=bits_allocated;
-            if (depth > 32)
+              info.bytes_per_pixel=2;
+            info.depth=info.bits_allocated;
+            if (info.depth > 32)
               ThrowReaderException(CorruptImageError,"ImproperImageHeader");
-            max_value=(1UL << bits_allocated)-1;
+            info.max_value=(1UL << info.bits_allocated)-1;
             break;
           }
           case 0x0101:
@@ -3280,15 +3449,15 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
             /*
               Bits stored.
             */
-            significant_bits=(size_t) datum;
-            bytes_per_pixel=1;
-            if (significant_bits > 8)
-              bytes_per_pixel=2;
-            depth=significant_bits;
-            if (depth > 32)
+            info.significant_bits=(size_t) datum;
+            info.bytes_per_pixel=1;
+            if (info.significant_bits > 8)
+              info.bytes_per_pixel=2;
+            info.depth=info.significant_bits;
+            if (info.depth > 32)
               ThrowReaderException(CorruptImageError,"ImproperImageHeader");
-            max_value=(1UL << significant_bits)-1;
-            mask=(size_t) GetQuantumRange(significant_bits);
+            info.max_value=(1UL << info.significant_bits)-1;
+            info.mask=(size_t) GetQuantumRange(info.significant_bits);
             break;
           }
           case 0x0102:
@@ -3303,7 +3472,7 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
             /*
               Pixel representation.
             */
-            signed_data=(size_t) datum;
+            info.signed_data=(size_t) datum;
             break;
           }
           case 0x1050:
@@ -3312,7 +3481,7 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
               Visible pixel range: center.
             */
             if (data != (unsigned char *) NULL)
-              window_center=(ssize_t) StringToLong((char *) data);
+              info.window_center=(ssize_t) StringToLong((char *) data);
             break;
           }
           case 0x1051:
@@ -3321,7 +3490,7 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
               Visible pixel range: width.
             */
             if (data != (unsigned char *) NULL)
-              window_width=StringToUnsignedLong((char *) data);
+              info.window_width=StringToUnsignedLong((char *) data);
             break;
           }
           case 0x1052:
@@ -3330,7 +3499,7 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
               Rescale intercept
             */
             if (data != (unsigned char *) NULL)
-              rescale_intercept=(ssize_t) StringToLong((char *) data);
+              info.rescale_intercept=(ssize_t) StringToLong((char *) data);
             break;
           }
           case 0x1053:
@@ -3339,7 +3508,7 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
               Rescale slope
             */
             if (data != (unsigned char *) NULL)
-              rescale_slope=(ssize_t) StringToLong((char *) data);
+              info.rescale_slope=(ssize_t) StringToLong((char *) data);
             break;
           }
           case 0x1200:
@@ -3350,14 +3519,14 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
             */
             if (data == (unsigned char *) NULL)
               break;
-            colors=(size_t) (length/bytes_per_pixel);
+            colors=(size_t) (length/info.bytes_per_pixel);
             datum=(int) colors;
             graymap=(int *) AcquireQuantumMemory((size_t) colors,
               sizeof(*graymap));
             if (graymap == (int *) NULL)
               ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
             for (i=0; i < (ssize_t) colors; i++)
-              if (bytes_per_pixel == 1)
+              if (info.bytes_per_pixel == 1)
                 graymap[i]=(int) data[i];
               else
                 graymap[i]=(int) ((short *) data)[i];
@@ -3460,7 +3629,7 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
           {
             if ((data != (unsigned char *) NULL) &&
                 (strncmp((char *) data,"INVERSE",7) == 0))
-              polarity=MagickTrue;
+              info.polarity=MagickTrue;
             break;
           }
           default:
@@ -3539,8 +3708,8 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
   image->columns=(size_t) width;
   image->rows=(size_t) height;
-  if (signed_data == 0xffff)
-    signed_data=(size_t) (significant_bits == 16 ? 1 : 0);
+  if (info.signed_data == 0xffff)
+    info.signed_data=(size_t) (info.significant_bits == 16 ? 1 : 0);
   if ((image->compression == JPEGCompression) ||
       (image->compression == JPEG2000Compression))
     {
@@ -3662,7 +3831,7 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
       image=DestroyImage(image);
       return(GetFirstImageInList(images));
     }
-  if (depth != (1UL*MAGICKCORE_QUANTUM_DEPTH))
+  if (info.depth != (1UL*MAGICKCORE_QUANTUM_DEPTH))
     {
       QuantumAny
         range;
@@ -3673,13 +3842,13 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
       /*
         Compute pixel scaling table.
       */
-      length=(size_t) (GetQuantumRange(depth)+1);
-      scale=(Quantum *) AcquireQuantumMemory(length,sizeof(*scale));
-      if (scale == (Quantum *) NULL)
+      length=(size_t) (GetQuantumRange(info.depth)+1);
+      info.scale=(Quantum *) AcquireQuantumMemory(length,sizeof(*info.scale));
+      if (info.scale == (Quantum *) NULL)
         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
-      range=GetQuantumRange(depth);
-      for (i=0; i <= (ssize_t) GetQuantumRange(depth); i++)
-        scale[i]=ScaleAnyToQuantum((size_t) i,range);
+      range=GetQuantumRange(info.depth);
+      for (i=0; i <= (ssize_t) GetQuantumRange(info.depth); i++)
+        info.scale[i]=ScaleAnyToQuantum((size_t) i,range);
     }
   if (image->compression == RLECompression)
     {
@@ -3720,51 +3889,59 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
       break;
     image->columns=(size_t) width;
     image->rows=(size_t) height;
-    image->depth=depth;
+    image->depth=info.depth;
     status=SetImageExtent(image,image->columns,image->rows,exception);
     if (status == MagickFalse)
       break;
     image->colorspace=RGBColorspace;
-    if ((image->colormap == (PixelInfo *) NULL) && (samples_per_pixel == 1))
+    if ((image->colormap == (PixelInfo *) NULL) &&
+        (info.samples_per_pixel == 1))
       {
+        int
+          index;
+
         size_t
           one;
 
         one=1;
         if (colors == 0)
-          colors=one << depth;
-        if (AcquireImageColormap(image,one << depth,exception) == MagickFalse)
+          colors=one << info.depth;
+        if (AcquireImageColormap(image,one << info.depth,exception) == MagickFalse)
           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
         if (redmap != (int *) NULL)
           for (i=0; i < (ssize_t) colors; i++)
           {
             index=redmap[i];
-            if ((scale != (Quantum *) NULL) && (index <= (int) max_value))
-              index=(int) scale[index];
+            if ((info.scale != (Quantum *) NULL) &&
+                (index <= (int) info.max_value))
+              index=(int) info.scale[index];
             image->colormap[i].red=(MagickRealType) index;
           }
         if (greenmap != (int *) NULL)
           for (i=0; i < (ssize_t) colors; i++)
           {
             index=greenmap[i];
-            if ((scale != (Quantum *) NULL) && (index <= (int) max_value))
-              index=(int) scale[index];
+            if ((info.scale != (Quantum *) NULL) &&
+                (index <= (int) info.max_value))
+              index=(int) info.scale[index];
             image->colormap[i].green=(MagickRealType) index;
           }
         if (bluemap != (int *) NULL)
           for (i=0; i < (ssize_t) colors; i++)
           {
             index=bluemap[i];
-            if ((scale != (Quantum *) NULL) && (index <= (int) max_value))
-              index=(int) scale[index];
+            if ((info.scale != (Quantum *) NULL) &&
+                (index <= (int) info.max_value))
+              index=(int) info.scale[index];
             image->colormap[i].blue=(MagickRealType) index;
           }
         if (graymap != (int *) NULL)
           for (i=0; i < (ssize_t) colors; i++)
           {
             index=graymap[i];
-            if ((scale != (Quantum *) NULL) && (index <= (int) max_value))
-              index=(int) scale[index];
+            if ((info.scale != (Quantum *) NULL) &&
+                (index <= (int) info.max_value))
+              index=(int) info.scale[index];
             image->colormap[i].red=(MagickRealType) index;
             image->colormap[i].green=(MagickRealType) index;
             image->colormap[i].blue=(MagickRealType) index;
@@ -3789,19 +3966,28 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
         stream_info->segment_count=ReadBlobLSBLong(image);
         if (stream_info->segment_count > 1)
           {
-            bytes_per_pixel=1;
-            depth=8;
+            info.bytes_per_pixel=1;
+            info.depth=8;
           }
         for (i=0; i < 15; i++)
           stream_info->segments[i]=(ssize_t) ReadBlobLSBSignedLong(image);
         stream_info->remaining-=64;
       }
-    if ((samples_per_pixel > 1) && (image->interlace == PlaneInterlace))
+    if ((info.samples_per_pixel > 1) && (image->interlace == PlaneInterlace))
       {
+        register ssize_t
+          x;
+
+        register Quantum
+          *q;
+
+        ssize_t
+          y;
+
         /*
           Convert Planar RGB DCM Medical image to pixel packets.
         */
-        for (i=0; i < (ssize_t) samples_per_pixel; i++)
+        for (i=0; i < (ssize_t) info.samples_per_pixel; i++)
         {
           for (y=0; y < (ssize_t) image->rows; y++)
           {
@@ -3858,255 +4044,20 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
         const char
           *option;
 
-        int
-          byte;
-
-        PixelPacket
-          pixel;
-
         /*
           Convert DCM Medical image to pixel packets.
         */
-        byte=0;
-        i=0;
-        if ((window_center != 0) && (window_width == 0))
-          window_width=(size_t) window_center;
+        if ((info.window_center != 0) && (info.window_width == 0))
+          info.window_width=(size_t) info.window_center;
         option=GetImageOption(image_info,"dcm:display-range");
         if (option != (const char *) NULL)
           {
             if (LocaleCompare(option,"reset") == 0)
-              window_width=0;
-          }
-        (void) ResetMagickMemory(&pixel,0,sizeof(pixel));
-        for (y=0; y < (ssize_t) image->rows; y++)
-        {
-          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
-          if (q == (Quantum *) NULL)
-            break;
-          for (x=0; x < (ssize_t) image->columns; x++)
-          {
-            if (samples_per_pixel == 1)
-              {
-                int
-                  pixel_value;
-
-                if (bytes_per_pixel == 1)
-                  pixel_value=polarity != MagickFalse ?
-                    ((int) max_value-ReadDCMByte(stream_info,image)) :
-                    ReadDCMByte(stream_info,image);
-                else
-                  if ((bits_allocated != 12) || (significant_bits != 12))
-                    {
-                      if (signed_data)
-                        pixel_value=ReadDCMSignedShort(stream_info,image);
-                      else
-                        pixel_value=ReadDCMShort(stream_info,image);
-                      if (polarity != MagickFalse)
-                        pixel_value=(int)max_value-pixel_value;
-                    }
-                  else
-                    {
-                      if ((i & 0x01) != 0)
-                        pixel_value=(ReadDCMByte(stream_info,image) << 8) |
-                          byte;
-                      else
-                        {
-                          pixel_value=ReadDCMSignedShort(stream_info,image);
-                          byte=(int) (pixel_value & 0x0f);
-                          pixel_value>>=4;
-                        }
-                      i++;
-                    }
-                index=(pixel_value*rescale_slope)+rescale_intercept;
-                if (window_width == 0)
-                  {
-                    if (signed_data == 1)
-                      index-=32767;
-                  }
-                else
-                  {
-                    ssize_t
-                      window_max,
-                      window_min;
-
-                    window_min=(ssize_t) ceil((double) window_center-
-                      (window_width-1.0)/2.0-0.5);
-                    window_max=(ssize_t) floor((double) window_center+
-                      (window_width-1.0)/2.0+0.5);
-                    if ((ssize_t)index <= window_min)
-                      index=0;
-                    else
-                      if ((ssize_t)index > window_max)
-                        index=(int) max_value;
-                      else
-                        index=(int) (max_value*(((index-window_center-
-                          0.5)/(window_width-1))+0.5));
-                  }
-                index&=mask;
-                index=(int) ConstrainColormapIndex(image,(size_t) index,
-                  exception);
-                SetPixelIndex(image,(Quantum) index,q);
-                pixel.red=(unsigned int) image->colormap[index].red;
-                pixel.green=(unsigned int) image->colormap[index].green;
-                pixel.blue=(unsigned int) image->colormap[index].blue;
-              }
-            else
-              {
-                if (bytes_per_pixel == 1)
-                  {
-                    pixel.red=(unsigned int) ReadDCMByte(stream_info,image);
-                    pixel.green=(unsigned int) ReadDCMByte(stream_info,image);
-                    pixel.blue=(unsigned int) ReadDCMByte(stream_info,image);
-                  }
-                else
-                  {
-                    pixel.red=ReadDCMShort(stream_info,image);
-                    pixel.green=ReadDCMShort(stream_info,image);
-                    pixel.blue=ReadDCMShort(stream_info,image);
-                  }
-                pixel.red&=mask;
-                pixel.green&=mask;
-                pixel.blue&=mask;
-                if (scale != (Quantum *) NULL)
-                  {
-                    if (pixel.red <= GetQuantumRange(depth))
-                      pixel.red=scale[pixel.red];
-                    if (pixel.green <= GetQuantumRange(depth))
-                      pixel.green=scale[pixel.green];
-                    if (pixel.blue <= GetQuantumRange(depth))
-                      pixel.blue=scale[pixel.blue];
-                  }
-              }
-            SetPixelRed(image,(Quantum) pixel.red,q);
-            SetPixelGreen(image,(Quantum) pixel.green,q);
-            SetPixelBlue(image,(Quantum) pixel.blue,q);
-            q+=GetPixelChannels(image);
-          }
-          if (SyncAuthenticPixels(image,exception) == MagickFalse)
-            break;
-          if (image->previous == (Image *) NULL)
-            {
-              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
-                image->rows);
-              if (status == MagickFalse)
-                break;
-            }
-        }
-        if (stream_info->segment_count > 1)
-          for (y=0; y < (ssize_t) image->rows; y++)
-          {
-            q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
-            if (q == (Quantum *) NULL)
-              break;
-            for (x=0; x < (ssize_t) image->columns; x++)
-            {
-              if (samples_per_pixel == 1)
-                {
-                  int
-                    pixel_value;
-
-                  if (bytes_per_pixel == 1)
-                    pixel_value=polarity != MagickFalse ?
-                      ((int) max_value-ReadDCMByte(stream_info,image)) :
-                      ReadDCMByte(stream_info,image);
-                  else
-                    if ((bits_allocated != 12) || (significant_bits != 12))
-                      {
-                        pixel_value=(int) (polarity != MagickFalse ?
-                          (max_value-ReadDCMShort(stream_info,image)) :
-                          ReadDCMShort(stream_info,image));
-                        if (signed_data == 1)
-                          pixel_value=((signed short) pixel_value);
-                      }
-                    else
-                      {
-                        if ((i & 0x01) != 0)
-                          pixel_value=(ReadDCMByte(stream_info,image) << 8) |
-                            byte;
-                        else
-                          {
-                            pixel_value=ReadDCMShort(stream_info,image);
-                            byte=(int) (pixel_value & 0x0f);
-                            pixel_value>>=4;
-                          }
-                        i++;
-                      }
-                  index=(pixel_value*rescale_slope)+rescale_intercept;
-                  if (window_width == 0)
-                    {
-                      if (signed_data == 1)
-                        index-=32767;
-                    }
-                  else
-                    {
-                      ssize_t
-                        window_max,
-                        window_min;
-
-                      window_min=(ssize_t) ceil((double) window_center-
-                        (window_width-1.0)/2.0-0.5);
-                      window_max=(ssize_t) floor((double) window_center+
-                        (window_width-1.0)/2.0+0.5);
-                      if ((ssize_t)index <= window_min)
-                        index=0;
-                      else
-                        if ((ssize_t)index > window_max)
-                          index=(int) max_value;
-                        else
-                          index=(int) (max_value*(((index-window_center-
-                            0.5)/(window_width-1))+0.5));
-                    }
-                  index&=mask;
-                  index=(int) ConstrainColormapIndex(image,(size_t) index,
-                    exception);
-                  SetPixelIndex(image,(Quantum) (((size_t)
-                    GetPixelIndex(image,q)) | (((size_t) index) << 8)),q);
-                  pixel.red=(unsigned int) image->colormap[index].red;
-                  pixel.green=(unsigned int) image->colormap[index].green;
-                  pixel.blue=(unsigned int) image->colormap[index].blue;
-                }
-              else
-                {
-                  if (bytes_per_pixel == 1)
-                    {
-                      pixel.red=(unsigned int) ReadDCMByte(stream_info,image);
-                      pixel.green=(unsigned int) ReadDCMByte(stream_info,image);
-                      pixel.blue=(unsigned int) ReadDCMByte(stream_info,image);
-                    }
-                  else
-                    {
-                      pixel.red=ReadDCMShort(stream_info,image);
-                      pixel.green=ReadDCMShort(stream_info,image);
-                      pixel.blue=ReadDCMShort(stream_info,image);
-                    }
-                  pixel.red&=mask;
-                  pixel.green&=mask;
-                  pixel.blue&=mask;
-                  if (scale != (Quantum *) NULL)
-                    {
-                      pixel.red=scale[pixel.red];
-                      pixel.green=scale[pixel.green];
-                      pixel.blue=scale[pixel.blue];
-                    }
-                }
-              SetPixelRed(image,(Quantum) (((size_t) GetPixelRed(image,q)) |
-                (((size_t) pixel.red) << 8)),q);
-              SetPixelGreen(image,(Quantum) (((size_t) GetPixelGreen(image,q)) |
-                (((size_t) pixel.green) << 8)),q);
-              SetPixelBlue(image,(Quantum) (((size_t) GetPixelBlue(image,q)) |
-                (((size_t) pixel.blue) << 8)),q);
-              q+=GetPixelChannels(image);
-            }
-            if (SyncAuthenticPixels(image,exception) == MagickFalse)
-              break;
-            if (image->previous == (Image *) NULL)
-              {
-                status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
-                  image->rows);
-                if (status == MagickFalse)
-                  break;
-              }
+              info.window_width=0;
           }
+        status=ReadDCMPixels(image,&info,stream_info,MagickTrue,exception);
+        if ((status != MagickFalse) && (stream_info->segment_count > 1))
+          ReadDCMPixels(image,&info,stream_info,MagickFalse,exception);
       }
     if (SetImageGray(image,exception) != MagickFalse)
       (void) SetImageColorspace(image,GRAYColorspace,exception);
@@ -4147,8 +4098,8 @@ static Image *ReadDCMImage(const ImageInfo *image_info,ExceptionInfo *exception)
     stream_info->offsets=(ssize_t *)
       RelinquishMagickMemory(stream_info->offsets);
   stream_info=(DCMStreamInfo *) RelinquishMagickMemory(stream_info);
-  if (scale != (Quantum *) NULL)
-    scale=(Quantum *) RelinquishMagickMemory(scale);
+  if (info.scale != (Quantum *) NULL)
+    info.scale=(Quantum *) RelinquishMagickMemory(info.scale);
   if (graymap != (int *) NULL)
     graymap=(int *) RelinquishMagickMemory(graymap);
   if (bluemap != (int *) NULL)