]> Creatis software - gdcm.git/blobdiff - src/gdcmPixelReadConvert.cxx
Fix mistypings
[gdcm.git] / src / gdcmPixelReadConvert.cxx
index c776743a7560f13ba1189cbc141fbc9cfe013c12..45aaf812dd75df17a02bc981bebf4232b6f29c06 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmPixelReadConvert.cxx,v $
   Language:  C++
-  Date:      $Date: 2007/09/17 12:18:25 $
-  Version:   $Revision: 1.123 $
+  Date:      $Date: 2008/05/20 09:22:03 $
+  Version:   $Revision: 1.128 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -24,6 +24,7 @@
 #include "gdcmDocEntry.h"
 #include "gdcmRLEFramesInfo.h"
 #include "gdcmJPEGFragmentsInfo.h"
+#include "gdcmSegmentedPalette.h"
 
 #include <fstream>
 #include <stdio.h> //for sscanf
@@ -44,7 +45,7 @@ bool gdcm_read_JPEG2000_file (void* raw,
 //-----------------------------------------------------------------------------
 // Constructor / Destructor
 /// Constructor
-PixelReadConvert::PixelReadConvert() 
+PixelReadConvert::PixelReadConvert()
 {
    RGB          = 0;
    RGBSize      = 0;
@@ -143,10 +144,10 @@ void PixelReadConvert::GrabInformationsFromFile( File *file,
       while (true) // shorter to write than 'if elseif elseif elseif' ...
       {
          // mind the order : check the most usual first.
-         if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRLittleEndian)         break;
-         if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian )        break;
-         if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian)            break;
-         if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE)   break;
+         if( IsRaw = (Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRLittleEndian))         break;
+         if( IsRaw = (Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian))         break;
+         if( IsRaw = (Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian))            break;
+         if( IsRaw = (Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE))   break;
          // DeflatedExplicitVRLittleEndian syntax means the whole Dataset (Header + Pixels) is compressed !
          // Not dealt with ! (Parser hangs)
          //if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::DeflatedExplicitVRLittleEndian) break;
@@ -164,13 +165,14 @@ void PixelReadConvert::GrabInformationsFromFile( File *file,
          while(true)
          {
             // mind the order : check the most usual first.
-            if( IsJPEGLossy     = Global::GetTS()->IsJPEGLossy(ts) )    break;
-            if( IsJPEGLossless  = Global::GetTS()->IsJPEGLossless(ts) ) break;
-            if( IsRLELossless   = Global::GetTS()->IsRLELossless(ts) )  break;
-            if( IsJPEG2000      = Global::GetTS()->IsJPEG2000(ts) )     break;
-            if( IsMPEG          = Global::GetTS()->IsMPEG(ts) )         break;
-            if( IsJPEGLS        = Global::GetTS()->IsJPEGLS(ts) )       break;
-            // DeflatedExplicitVRLittleEndian is considered as 'Unexpected' (we don't know yet how to process !)
+            if( IsJPEGLossy     = (Global::GetTS()->IsJPEGLossy(ts)))    break;
+            if( IsJPEGLossless  = (Global::GetTS()->IsJPEGLossless(ts))) break;
+            if( IsRLELossless   = (Global::GetTS()->IsRLELossless(ts)))  break;
+            if( IsJPEG2000      = (Global::GetTS()->IsJPEG2000(ts)))     break;
+            if( IsMPEG          = (Global::GetTS()->IsMPEG(ts)))         break;
+            if( IsJPEGLS        = (Global::GetTS()->IsJPEGLS(ts)))       break;
+            // DeflatedExplicitVRLittleEndian is considered as 'Unexpected' 
+            // (we don't know yet how to process !)
             gdcmWarningMacro("Unexpected Transfer Syntax :[" << ts << "]");
             break;
          } 
@@ -194,51 +196,114 @@ void PixelReadConvert::GrabInformationsFromFile( File *file,
    HasLUT = file->HasLUT();
    if ( HasLUT )
    {
-      // Just in case some access to a File element requires disk access.
+/*   
+ C.7.6.3.1.5
+   The three values of Palette Color Lookup Table Descriptor (0028,1101-1103)
+   describe the format of the Lookup Table Data in the corresponding
+   Data Element (0028,1201-1203) or (0028,1221-1223).
+    
+   The first value is the number of entries in the lookup table. 
+   When the number of table entries is equal to 2**16 then this value shall be 0.
+
+   The second value is the first stored pixel value mapped. 
+   This pixel value is mapped to the first entry in the Lookup Table Data. 
+   All image pixel values less than the first entry value mapped are also 
+   mapped to the first entry in the Lookup Table Data. 
+   An image pixel value one greater than the first entry value mapped is 
+   mapped to the second entry in the Lookup Table Data. 
+   Subsequent image pixel values are mapped to the subsequent entries in 
+   the Lookup Table Data up to an image pixel value equal to number of 
+   entries + first entry value mapped - 1 which is mapped to the last entry 
+   in the Lookup Table Data. 
+   Image pixel values greater than or equal to number of entries + first entry
+   value mapped are also mapped to the last entry in the Lookup Table Data.
+
+   The third value specifies the number of bits for each entry in the Lookup 
+   Table Data. It shall take the value of 8 or 16. 
+   The LUT Data shall be stored in a format equivalent to 8 or 16 bits 
+   allocated where the high bit is equal to bits allocated-1.
+
+   When the Palette Color Lookup Table Descriptor (0028,1101-1103) are used as
+   part of the Palette Color Lookup Table Module, the third value shall be 
+   equal to 16.
+
+    Note: A value of 16 indicates the Lookup Table Data will range from (0,0,0)
+    minimum intensity to (65535,65535,65535) maximum intensity. 
+
+*/ 
+
+     // Just in case some access to a File element requires disk access.
       LutRedDescriptor   = file->GetEntryString( 0x0028, 0x1101 );
       LutGreenDescriptor = file->GetEntryString( 0x0028, 0x1102 );
       LutBlueDescriptor  = file->GetEntryString( 0x0028, 0x1103 );
-   
-      // FIXME : The following comment is probabely meaningless, since LUT are *always*
-      // loaded at parsing time, whatever their length is.
-         
-      // Depending on the value of Document::MAX_SIZE_LOAD_ELEMENT_VALUE
-      // [ refer to invocation of Document::SetMaxSizeLoadEntry() in
-      // Document::Document() ], the loading of the value (content) of a
-      // [Bin|Val]Entry occurence migth have been hindered (read simply NOT
-      // loaded). Hence, we first try to obtain the LUTs data from the file
-      // and when this fails we read the LUTs data directly from disk.
-      // \todo Reading a [Bin|Val]Entry directly from disk is a kludge.
-      //       We should NOT bypass the [Bin|Val]Entry class. Instead
-      //       an access to an UNLOADED content of a [Bin|Val]Entry occurence
-      //       (e.g. DataEntry::GetBinArea()) should force disk access from
-      //       within the [Bin|Val]Entry class itself. The only problem
-      //       is that the [Bin|Val]Entry is unaware of the FILE* is was
-      //       parsed from. Fix that. FIXME.
-   
-      // //// Red round
-      file->LoadEntryBinArea(0x0028, 0x1201);
-      LutRedData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1201 );
-      if ( ! LutRedData )
-      {
-         gdcmWarningMacro("Unable to read Red Palette Color Lookup Table data");
-      }
-
-      // //// Green round:
-      file->LoadEntryBinArea(0x0028, 0x1202);
-      LutGreenData = (uint8_t*)file->GetEntryBinArea(0x0028, 0x1202 );
-      if ( ! LutGreenData)
-      {
-         gdcmWarningMacro("Unable to read Green Palette Color Lookup Table data");
-      }
-
-      // //// Blue round:
-      file->LoadEntryBinArea(0x0028, 0x1203);
-      LutBlueData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1203 );
-      if ( ! LutBlueData )
-      {
-         gdcmWarningMacro("Unable to read Blue Palette Color Lookup Table data");
-      }
+      // Is it a Segmented Palette ? Check if we find the red one:
+      if( file->GetDocEntry(0x0028,0x1221) ) // no need to check for blue & green
+        {
+        GDCM_NAME_SPACE::TagKey DCM_RedPaletteColorLookupTableDescriptor (0x0028, 0x1101);
+        GDCM_NAME_SPACE::TagKey DCM_GreenPaletteColorLookupTableDescriptor (0x0028, 0x1102);
+        GDCM_NAME_SPACE::TagKey DCM_BluePaletteColorLookupTableDescriptor (0x0028, 0x1103);
+
+        GDCM_NAME_SPACE::TagKey DCM_SegmentedRedPaletteColorLookupTableData (0x0028, 0x1221);
+        GDCM_NAME_SPACE::TagKey DCM_SegmentedGreenPaletteColorLookupTableData (0x0028, 0x1222);
+        GDCM_NAME_SPACE::TagKey DCM_SegmentedBluePaletteColorLookupTableData (0x0028, 0x1223);
+
+
+        LutRedData = new uint8_t[65535*2]; // FIXME: leak
+        LutGreenData = new uint8_t[65535*2];
+        LutBlueData = new uint8_t[65535*2];
+        // TODO need to check file is indeed PALETTE COLOR:
+        ReadPaletteInto(file, DCM_RedPaletteColorLookupTableDescriptor,
+          DCM_SegmentedRedPaletteColorLookupTableData,LutRedData);
+        ReadPaletteInto(file, DCM_GreenPaletteColorLookupTableDescriptor,
+          DCM_SegmentedGreenPaletteColorLookupTableData,LutGreenData);
+        ReadPaletteInto(file, DCM_BluePaletteColorLookupTableDescriptor,
+          DCM_SegmentedBluePaletteColorLookupTableData,LutBlueData);
+
+        }
+      else
+        {
+
+        // FIXME : The following comment is probabely meaningless, since LUT are *always*
+        // loaded at parsing time, whatever their length is.
+
+        // Depending on the value of Document::MAX_SIZE_LOAD_ELEMENT_VALUE
+        // [ refer to invocation of Document::SetMaxSizeLoadEntry() in
+        // Document::Document() ], the loading of the value (content) of a
+        // [Bin|Val]Entry occurence migth have been hindered (read simply NOT
+        // loaded). Hence, we first try to obtain the LUTs data from the file
+        // and when this fails we read the LUTs data directly from disk.
+        // \TODO Reading a [Bin|Val]Entry directly from disk is a kludge.
+        //       We should NOT bypass the [Bin|Val]Entry class. Instead
+        //       an access to an UNLOADED content of a [Bin|Val]Entry occurence
+        //       (e.g. DataEntry::GetBinArea()) should force disk access from
+        //       within the [Bin|Val]Entry class itself. The only problem
+        //       is that the [Bin|Val]Entry is unaware of the FILE* is was
+        //       parsed from. Fix that. FIXME.
+
+        // //// Red round
+        file->LoadEntryBinArea(0x0028, 0x1201);
+        LutRedData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1201 );
+        if ( ! LutRedData )
+          {
+          gdcmWarningMacro("Unable to read Red Palette Color Lookup Table data");
+          }
+
+        // //// Green round:
+        file->LoadEntryBinArea(0x0028, 0x1202);
+        LutGreenData = (uint8_t*)file->GetEntryBinArea(0x0028, 0x1202 );
+        if ( ! LutGreenData)
+          {
+          gdcmWarningMacro("Unable to read Green Palette Color Lookup Table data");
+          }
+
+        // //// Blue round:
+        file->LoadEntryBinArea(0x0028, 0x1203);
+        LutBlueData = (uint8_t*)file->GetEntryBinArea( 0x0028, 0x1203 );
+        if ( ! LutBlueData )
+          {
+          gdcmWarningMacro("Unable to read Blue Palette Color Lookup Table data");
+          }
+        }
    }
    FileInternal = file;   
    FH = fileHelper;
@@ -381,9 +446,9 @@ void PixelReadConvert::Squeeze()
       delete [] Raw;
    Raw = 0;
 
-   if ( LutRGBA )
-      delete [] LutRGBA;
-   LutRGBA = 0;
+   //if ( LutRGBA )
+   //   delete [] LutRGBA;
+   //LutRGBA = 0;
 }
 
 /**
@@ -614,7 +679,7 @@ bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp )
 //    if ( ! gdcm_read_JPEGLS_file( fp,Raw ) )
          return false;
    }
-   else
+   else if( JPEGInfo )
    {
      // make sure this is the right JPEG compression
      assert( !IsJPEGLS || !IsJPEG2000 );
@@ -631,6 +696,8 @@ bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp )
      JPEGInfo->DecompressFromFile(fp, Raw, dummy, numberBytes, length );
      return true;
    }
+   //else (not sure how get there...), must be one of those crazy DICOM file
+   return false;
 }
 
 /**
@@ -856,7 +923,7 @@ void PixelReadConvert::BuildLUTRGBA()
          *a16 = 1; // Alpha component
          a16 += 4;
       }
-/* Just to 'see' the LUT, at debug time
+// Just to 'see' the LUT, at debug time
 // Don't remove this commented out code.
 
       a16=(uint16_t*)LutRGBA;
@@ -866,7 +933,7 @@ void PixelReadConvert::BuildLUTRGBA()
                    << *(a16+2) << " " << *(a16+3) << std::endl;
          a16+=4;
       }
-*/
+
    }
 }