]> Creatis software - gdcm.git/commitdiff
2004-10-18 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
authorfrog <frog>
Mon, 18 Oct 2004 12:49:19 +0000 (12:49 +0000)
committerfrog <frog>
Mon, 18 Oct 2004 12:49:19 +0000 (12:49 +0000)
  * Doc/CMakeLists.txt, doxygen.config.in: when dot is present the
    collaboration diagram and inheritance diagram should be generated with
    doxygen.
  * Doc/Website/Sidebar.html: Dashboard is now also in the sidebar.
  * gdcmPython/gdcm.i: gdcmRLEFramesInfo.h gdcmJPEGFragmentsInfo.h are
    pointlessly wrapped (see
    http://www.creatis.insa-lyon.fr/pipermail/dcmlib/2004-October/000692.html )
  * CLEANUP_ROUND (12) for gdcmPixelConvert (sugar is my friend stage)
    - Header::GetLUTRGBA() moved to PixelConvert::GetLutRGBA()
    - vtk/vtkGdcmReader.cxx: adapted to displacment of Header::GetLUTRGBA()
    - Document::RLEInfo and JPEGInfo are now pointer members (Swig thing)
    - src/gdcmFile.[cxx|h] and gdcmPixelConvert.[cxx|h]:
      -- File::Initialise: PixelConverter setup moved away to
           PixelConverter::GrabInformationsFromHeader()
      -- File::GetImageDataIntoVector(): Lut R + Lut G + Lut B color table
         interpretation moved away to PixelConverter::BuildRGBImage()

17 files changed:
ChangeLog
Doc/CMakeLists.txt
Doc/Website/Sidebar.html
Doc/doxygen.config.in
gdcmPython/gdcm.i
src/gdcmBinEntry.h
src/gdcmDocument.cxx
src/gdcmDocument.h
src/gdcmFile.cxx
src/gdcmFile.h
src/gdcmHeader.cxx
src/gdcmHeader.h
src/gdcmJPEGFragmentsInfo.h
src/gdcmPixelConvert.cxx
src/gdcmPixelConvert.h
src/gdcmRLEFrame.h
vtk/vtkGdcmReader.cxx

index f3ead76cbb313b8830df58dc2e815ad0cda28f49..4e6982ee88b4a6bd7112e8a47e9e44620b83b6ff 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2004-10-18 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
+  * Doc/CMakeLists.txt, doxygen.config.in: when dot is present the
+    collaboration diagram and inheritance diagram should be generated with
+    doxygen.
+  * Doc/Website/Sidebar.html: Dashboard is now also in the sidebar.
+  * gdcmPython/gdcm.i: gdcmRLEFramesInfo.h gdcmJPEGFragmentsInfo.h are
+    pointlessly wrapped (see
+    http://www.creatis.insa-lyon.fr/pipermail/dcmlib/2004-October/000692.html )
+  * CLEANUP_ROUND (12) for gdcmPixelConvert (sugar is my friend stage)
+    - Header::GetLUTRGBA() moved to PixelConvert::GetLutRGBA()
+    - vtk/vtkGdcmReader.cxx: adapted to displacment of Header::GetLUTRGBA()
+    - Document::RLEInfo and JPEGInfo are now pointer members (Swig thing)
+    - src/gdcmFile.[cxx|h] and gdcmPixelConvert.[cxx|h]:
+      -- File::Initialise: PixelConverter setup moved away to
+           PixelConverter::GrabInformationsFromHeader()
+      -- File::GetImageDataIntoVector(): Lut R + Lut G + Lut B color table
+         interpretation moved away to PixelConverter::BuildRGBImage()
+
 2004-10-16 Mathieu Malaterre  <Mathieu.Malaterre@creatis.insa-lyon.fr>
   * Remove GDCM_EXPORT keyword from gdcm::DirList due to :
     http://support.microsoft.com/support/kb/articles/Q168/9/58.ASP
index 6102dc841cdfe862a2bab3e94cf7964569390b3a..2c0d73af89b64decb5fd919766fbb30990dae0ab 100644 (file)
@@ -31,6 +31,14 @@ IF(GDCM_DOCUMENTATION)
          "${GDCM_DOCUMENTATION_INPUT_COMMON} ${GDCM_SOURCE_DIR}/vtk")
   ENDIF(GDCM_VTK)
 
+  IF(DOT)
+     GET_FILENAME_COMPONENT(GDCM_DOCUMENTATION_DOT_PATH ${DOT} PATH)
+     SET(GDCM_DOCUMENTATION_HAVE_DOT "YES")
+  ELSE(DOT)
+     SET(GDCM_DOCUMENTATION_DOT_PATH "")
+     SET(GDCM_DOCUMENTATION_HAVE_DOT "NO")
+  ENDIF(DOT)
+
   #Should rewrote this thing with FOREACH:
   #-----------------------------------------------------------------------------
   # Build the documentation for developpers
index 9e502b3c5306cf1db99c19a53a37a6e7099f5c87..3e455ddb8d2108c5d20ecf67dd151dd132a4b9f9 100644 (file)
       Online browsing of sources</A>
    </TD></TR>
 
+   <TR><TD BGCOLOR="#99ccff">
+      <A HREF="http://public.kitware.com/dashboard.php?name=public"
+      target="rite">
+      DashBoard</A>
+   </TD></TR>
 
    </TABLE>
    
index 4783a68a0435d021340a6c9706fb86a9d9cfdd1c..ddb51f19e9145113adf5a24252ca7bde48dc7c0d 100644 (file)
@@ -785,7 +785,7 @@ CLASS_DIAGRAMS         = YES
 # toolkit from AT&T and Lucent Bell Labs. The other options in this section 
 # have no effect if this option is set to NO (the default)
 
-HAVE_DOT               = NO
+HAVE_DOT               = @GDCM_DOCUMENTATION_HAVE_DOT@
 
 # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
 # will generate a graph for each documented class showing the direct and 
@@ -840,7 +840,7 @@ DOT_IMAGE_FORMAT       = png
 # The tag DOT_PATH can be used to specify the path where the dot tool can be 
 # found. If left blank, it is assumed the dot tool can be found on the path.
 
-DOT_PATH               = 
+DOT_PATH               = @GDCM_DOCUMENTATION_DOT_PATH@
 
 # The DOTFILE_DIRS tag can be used to specify one or more directories that 
 # contain dot files that are included in the documentation (see the 
index 27a7b02a3aba323304413d54bf9755c28678f1c5..b4d93b1aa1342c6afe00249243a104fb2d9e7bae 100644 (file)
@@ -1,26 +1,28 @@
 %module gdcm
 %{
 #include "gdcmCommon.h"
-#include "gdcmDictEntry.h"
 #include "gdcmDict.h"
+#include "gdcmDictEntry.h"
 #include "gdcmDictSet.h"
-#include "gdcmDocEntrySet.h"
-#include "gdcmSQItem.h"
-#include "gdcmDocument.h"
-#include "gdcmElementSet.h"
-#include "gdcmHeader.h"
-#include "gdcmHeaderHelper.h"
-#include "gdcmFile.h"
-#include "gdcmUtil.h"
-#include "gdcmGlobal.h"
-#include "gdcmDicomDirObject.h"
 #include "gdcmDicomDir.h"
 #include "gdcmDicomDirElement.h"
+#include "gdcmDicomDirImage.h"
 #include "gdcmDicomDirMeta.h"
+#include "gdcmDicomDirObject.h"
 #include "gdcmDicomDirPatient.h"
 #include "gdcmDicomDirStudy.h"
 #include "gdcmDicomDirSerie.h"
-#include "gdcmDicomDirImage.h"
+#include "gdcmDocEntrySet.h"
+#include "gdcmDocument.h"
+#include "gdcmElementSet.h"
+#include "gdcmFile.h"
+#include "gdcmGlobal.h"
+#include "gdcmHeader.h"
+#include "gdcmHeaderHelper.h"
+#include "gdcmRLEFramesInfo.h"
+#include "gdcmJPEGFragmentsInfo.h"
+#include "gdcmSQItem.h"
+#include "gdcmUtil.h"
 #include "gdcmValEntry.h"
 
 ////////////////////////////////////////////////////////////////////////////
@@ -227,6 +229,8 @@ typedef  unsigned int guint32;
 ////////////////////////////////////////////////////////////////////////////
 // Warning: Order matters !
 %include "gdcmCommon.h"
+%include "gdcmRLEFramesInfo.h"
+%include "gdcmJPEGFragmentsInfo.h"
 %include "gdcmDictEntry.h"
 %include "gdcmDict.h"
 %include "gdcmDocEntry.h"
index 6ba0cba2c6aad3333f2bf5d1ae1cf5bcecd6fc3c..5191670a54b6872916e1d5ebf6f9d70c86edeace 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmBinEntry.h,v $
   Language:  C++
-  Date:      $Date: 2004/10/12 04:35:44 $
-  Version:   $Revision: 1.22 $
+  Date:      $Date: 2004/10/18 12:49:22 $
+  Version:   $Revision: 1.23 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -36,30 +36,23 @@ namespace gdcm
 class GDCM_EXPORT BinEntry  : public ValEntry
 {
 public:
-
-   BinEntry(DictEntry* e);
-   BinEntry(DocEntry* d); 
+   BinEntry( DictEntry* e );
+   BinEntry( DocEntry* d ); 
 
    ~BinEntry();
    
-   void Print(std::ostream &os = std::cout);
-   void Write(FILE*, FileType);
+   void Print( std::ostream &os = std::cout );
+   void Write( FILE*, FileType );
 
    /// \brief Returns the area value of the current Dicom Header Entry
    ///  when it's not string-translatable (e.g : a LUT table)         
    uint8_t* GetBinArea()  { return BinArea; }
    void  SetBinArea( uint8_t* area );
          
-protected:
-
 private:
-
-// Variables
-   
    /// \brief unsecure memory area to hold 'non string' values 
    ///       (ie : Lookup Tables, overlays, icons)   
    uint8_t* BinArea;
-
 };
 } // end namespace gdcm
 //-----------------------------------------------------------------------------
index 60ca2dff2fae566e9b8171cb07bef9e4b44839ae..1dbde430bb3f710d2f7e093fdafe121fb46aadec 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/10/12 17:31:56 $
-  Version:   $Revision: 1.104 $
+  Date:      $Date: 2004/10/18 12:49:22 $
+  Version:   $Revision: 1.105 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -1109,7 +1109,12 @@ void*  Document::GetEntryBinAreaByNumber(uint16_t group, uint16_t elem)
       dbg.Verbose(1, "Document::GetDocEntryByNumber: no entry");
       return 0;
    }
-   return ((BinEntry *)entry)->GetBinArea();
+   if ( BinEntry* binEntry = dynamic_cast<BinEntry*>(entry) )
+   {
+      return binEntry->GetBinArea();
+   }
+
+   return 0;
 }
 
 /**
@@ -2447,6 +2452,8 @@ void Document::Initialise()
 {
    RefPubDict = Global::GetDicts()->GetDefaultPubDict();
    RefShaDict = NULL;
+   RLEInfo  = new RLEFramesInfo;
+   JPEGInfo = new JPEGFragmentsInfo;
 }
 
 /**
@@ -2962,7 +2969,7 @@ void Document::ComputeRLEInfo()
           newFrameInfo->Offset[uk] = frameOffset + rleSegmentOffsetTable[uk];
           newFrameInfo->Length[uk] = rleSegmentLength[uk];
        }
-       RLEInfo.Frames.push_back( newFrameInfo );
+       RLEInfo->Frames.push_back( newFrameInfo );
    }
 
    // Make sure that at the end of the item we encounter a 'Sequence
@@ -3001,7 +3008,7 @@ void Document::ComputeJPEGFragmentInfo()
        JPEGFragment* newFragment = new JPEGFragment;
        newFragment->Offset = fragmentOffset;
        newFragment->Length = fragmentLength;
-       JPEGInfo.Fragments.push_back( newFragment );
+       JPEGInfo->Fragments.push_back( newFragment );
 
        SkipBytes( fragmentLength );
    }
index 657fe8c250d662aa1fe653f769d058912a3231a3..6b730260e576388e2eae7034af73b8f5c9b9a4f4 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDocument.h,v $
   Language:  C++
-  Date:      $Date: 2004/10/13 14:15:29 $
-  Version:   $Revision: 1.51 $
+  Date:      $Date: 2004/10/18 12:49:22 $
+  Version:   $Revision: 1.52 $
  
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -48,11 +48,11 @@ class GDCM_EXPORT Document : public ElementSet
 friend class File;
 private:
    /// Public dictionary used to parse this header
-   Dict *RefPubDict;
+   DictRefPubDict;
    
    /// \brief Optional "shadow dictionary" (private elements) used to parse
    /// this header
-   Dict *RefShaDict;
+   DictRefShaDict;
 
    /// \brief Size threshold above which an element value will NOT be loaded
    /// in memory (to avoid loading the image/volume itself). By default,
@@ -75,7 +75,7 @@ protected:
    int SwapCode;
 
    /// File Pointer, opened during Header parsing.
-   FILE *Fp;
+   FILEFp;
 
    /// ACR, ACR_LIBIDO, ExplicitVR, ImplicitVR, Unknown
    FileType Filetype;  
@@ -95,10 +95,10 @@ protected:
    static const unsigned int MAX_SIZE_PRINT_ELEMENT_VALUE;
 
    /// Store the RLE frames info obtained during parsing of pixels.
-   RLEFramesInfo RLEInfo;
+   RLEFramesInfo* RLEInfo;
 
    /// Store the JPEG fragments info obtained during parsing of pixels.
-   JPEGFragmentsInfo JPEGInfo;
+   JPEGFragmentsInfo* JPEGInfo;
 
    /// \brief Amount of printed details for each Header Entry (Dicom Element):
    /// 0 : stands for the least detail level.
@@ -110,9 +110,9 @@ public:
    virtual void PrintShaDict (std::ostream &os = std::cout);
 
 // Dictionnaries
-   Dict *GetPubDict();
-   Dict *GetShaDict();
-   bool SetShaDict(Dict *dict);
+   DictGetPubDict();
+   DictGetShaDict();
+   bool SetShaDict(Dictdict);
    bool SetShaDict(DictKey const & dictName);
 
 // Informations contained in the parser
@@ -138,7 +138,7 @@ public:
    FILE* OpenFile();
    bool CloseFile();
 
-   void Write(FILE* fp, FileType type);
+   void Write( FILE* fp, FileType type );
 
    ValEntry* ReplaceOrCreateByNumber(std::string const & value,
                                          uint16_t group, uint16_t elem,
@@ -205,6 +205,8 @@ public:
 
    ValEntry* GetValEntryByNumber(uint16_t group, uint16_t element); 
    //BinEntry* GetBinEntryByNumber(uint16_t group, uint16_t element); 
+   RLEFramesInfo* GetRLEInfo() { return RLEInfo; }
+   JPEGFragmentsInfo* GetJPEGInfo() { return JPEGInfo; }
 
    void LoadDocEntrySafe(DocEntry* entry);
    TagDocEntryHT* BuildFlatHashTable();
index 02e6a08ad5618281327011bdc88f1b7c2a48a6de..da8105e3b8eaca4f2bb10fb1851c8397f510ae9e 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmFile.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/10/15 10:43:27 $
-  Version:   $Revision: 1.144 $
+  Date:      $Date: 2004/10/18 12:49:22 $
+  Version:   $Revision: 1.145 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -84,70 +84,7 @@ void File::Initialise()
          ImageDataSize = ImageDataSizeRaw;
       }
 
-
-
-                                                                                
-      // Just in case some access to a Header element requires disk access.
-      // Note: gdcmDocument::Fp is leaved open after OpenFile. 
-      (void)HeaderInternal->OpenFile();
-      // Number of Bits Allocated for storing a Pixel is defaulted to 16
-      // when absent from the header.
-      int numberBitsAllocated = HeaderInternal->GetBitsAllocated();
-      if ( numberBitsAllocated == 0 )
-      {
-         numberBitsAllocated = 16;
-      }
-      PixelConverter.SetBitsAllocated( numberBitsAllocated );
-                                                                                
-      // Number of "Bits Stored" defaulted to number of "Bits Allocated"
-      // when absent from the header.
-      int numberBitsStored = HeaderInternal->GetBitsStored();
-      if ( numberBitsStored == 0 )
-      {
-         numberBitsStored = numberBitsAllocated;
-      }
-      PixelConverter.SetBitsStored( numberBitsStored );
-                                                                                
-      // High Bit Position
-      int highBitPosition = HeaderInternal->GetHighBitPosition();
-      if ( highBitPosition == 0 )
-      {
-         highBitPosition = numberBitsAllocated - 1;
-      }
-      PixelConverter.SetHighBitPosition( highBitPosition );
-                                                                                
-                                                                                
-      PixelConverter.SetXSize( HeaderInternal->GetXSize() );
-      PixelConverter.SetYSize( HeaderInternal->GetYSize() );
-      PixelConverter.SetZSize( HeaderInternal->GetZSize() );
-      PixelConverter.SetSamplesPerPixel( HeaderInternal->GetSamplesPerPixel() );
-      PixelConverter.SetPixelSize( HeaderInternal->GetPixelSize() );
-      PixelConverter.SetPixelSign( HeaderInternal->IsSignedPixelData() );
-      PixelConverter.SetSwapCode( HeaderInternal->GetSwapCode() );
-      PixelConverter.SetIsUncompressed(
-         ! HeaderInternal->IsDicomV3()
-        || HeaderInternal->IsImplicitVRLittleEndianTransferSyntax()
-        || HeaderInternal->IsExplicitVRLittleEndianTransferSyntax()
-        || HeaderInternal->IsExplicitVRBigEndianTransferSyntax()
-        || HeaderInternal->IsDeflatedExplicitVRLittleEndianTransferSyntax() );
-      PixelConverter.SetIsJPEG2000( HeaderInternal->IsJPEG2000() );
-      PixelConverter.SetIsJPEGLossless( HeaderInternal->IsJPEGLossless() );
-      PixelConverter.SetIsRLELossless(
-                        HeaderInternal->IsRLELossLessTransferSyntax() );
-      PixelConverter.SetPixelOffset( HeaderInternal->GetPixelOffset() );
-      PixelConverter.SetPixelDataLength( HeaderInternal->GetPixelAreaLength() );
-      PixelConverter.SetRLEInfo( &(HeaderInternal->RLEInfo) );
-      PixelConverter.SetJPEGInfo( &(HeaderInternal->JPEGInfo) );
-      PixelConverter.SetHasLUT( HeaderInternal->HasLUT() );
-
-      PixelConverter.SetPlanarConfiguration(
-          HeaderInternal->GetPlanarConfiguration() );
-      PixelConverter.SetIsMonochrome( HeaderInternal->IsMonochrome() );
-      PixelConverter.SetIsPaletteColor( HeaderInternal->IsPaletteColor() );
-      PixelConverter.SetIsYBRFull( HeaderInternal->IsYBRFull() );
-                                                                                
-      HeaderInternal->CloseFile();
-
+      PixelConverter.GrabInformationsFromHeader( HeaderInternal );
    }
    SaveInitialValues();
 }
@@ -424,41 +361,30 @@ size_t File::GetImageDataIntoVector (void* destination, size_t maxSize)
       return ImageDataSize;
    }
                             
-   // from Lut R + Lut G + Lut B
-   uint8_t *newDest = new uint8_t[ImageDataSize];
-   uint8_t *a       = (uint8_t *)destination;
-   uint8_t *lutRGBA = HeaderInternal->GetLUTRGBA();
-
-   if ( lutRGBA )
+   FILE* fp = HeaderInternal->OpenFile();
+   if ( PixelConverter.BuildRGBImage( fp ) )
    {
-      int j;
-      // move Gray pixels to temp area  
-      memmove(newDest, destination, ImageDataSizeRaw);
-      for (size_t i=0; i<ImageDataSizeRaw; ++i) 
-      {
-         // Build RGB Pixels
-         j    = newDest[i]*4;
-         *a++ = lutRGBA[j];
-         *a++ = lutRGBA[j+1];
-         *a++ = lutRGBA[j+2];
-      }
-      delete[] newDest;
+      memmove( destination,
+               (void*)PixelConverter.GetRGB(),
+               PixelConverter.GetRGBSize() );
     
-   // now, it's an RGB image
-   // Lets's write it in the Header
+      // now, it's an RGB image
+      // Lets's write it in the Header
 
-   // FIXME : Better use CreateOrReplaceIfExist ?
+      // FIXME : Better use CreateOrReplaceIfExist ?
 
-   std::string spp = "3";        // Samples Per Pixel
-   HeaderInternal->SetEntryByNumber(spp,0x0028,0x0002);
-   std::string rgb = "RGB ";     // Photometric Interpretation
-   HeaderInternal->SetEntryByNumber(rgb,0x0028,0x0004);
-   std::string planConfig = "0"; // Planar Configuration
-   HeaderInternal->SetEntryByNumber(planConfig,0x0028,0x0006);
+      std::string spp = "3";        // Samples Per Pixel
+      HeaderInternal->SetEntryByNumber(spp,0x0028,0x0002);
+      std::string rgb = "RGB ";     // Photometric Interpretation
+      HeaderInternal->SetEntryByNumber(rgb,0x0028,0x0004);
+      std::string planConfig = "0"; // Planar Configuration
+      HeaderInternal->SetEntryByNumber(planConfig,0x0028,0x0006);
 
    }
-   else  // GetLUTRGBA() failed
+   else
    { 
+      // PixelConverter.BuildRGBImage( fp ) failed probably because
+      // PixelConverter.GetLUTRGBA() failed:
       // (gdcm-US-ALOKA-16.dcm), contains Segmented xxx Palette Color 
       // that are *more* than 65535 long ?!? 
       // No idea how to manage such an image !
@@ -468,6 +394,7 @@ size_t File::GetImageDataIntoVector (void* destination, size_t maxSize)
       std::string photomInterp = "MONOCHROME1 ";  // Photometric Interpretation
       HeaderInternal->SetEntryByNumber(photomInterp,0x0028,0x0004);
    } 
+   HeaderInternal->CloseFile();
 
    /// \todo Drop Palette Color out of the Header?
    return ImageDataSize; 
@@ -785,5 +712,13 @@ bool File::WriteBase (std::string const & fileName, FileType type)
    return true;
 }
 
+/**
+ * \brief Access to the underlying \ref PixelConvertver RGBA LUT
+ */
+uint8_t* File::GetLutRGBA()
+{
+   return PixelConverter.GetLutRGBA();
+}
+
 } // end namespace gdcm
 
index eb430a8cd442c87c5ea5d93c257314be4d669995..361bc3d81285154b3360d1b89e92decc94cf8e1a 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmFile.h,v $
   Language:  C++
-  Date:      $Date: 2004/10/13 14:15:30 $
-  Version:   $Revision: 1.62 $
+  Date:      $Date: 2004/10/18 12:49:22 $
+  Version:   $Revision: 1.63 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -80,6 +80,7 @@ public:
       HeaderInternal->SetEntryByNumber(content,group,element);
       return true;
    }
+   uint8_t* GetLutRGBA();
      
 protected:
    bool WriteBase(std::string const& fileName, FileType type);
@@ -101,6 +102,7 @@ private:
    void RestoreInitialValues(); // will belong to the future PixelData class
    void DeleteInitialValues();  // will belong to the future PixelData class 
 
+private:
 // members variables:
 
    /// Header to use to load the file
index b6801f8b88955802c6ee3ac9e19aa0aee749e7ef..12420a38e289e041380df7b4e1a017132ed1fb16 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmHeader.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/10/12 04:35:46 $
-  Version:   $Revision: 1.193 $
+  Date:      $Date: 2004/10/18 12:49:22 $
+  Version:   $Revision: 1.194 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -1127,169 +1127,6 @@ int Header::GetLUTNbits()
    return lutNbits;
 }
 
-/**
-  * \brief builts Red/Green/Blue/Alpha LUT from Header
-  *         when (0028,0004),Photometric Interpretation = [PALETTE COLOR ]
-  *          and (0028,1101),(0028,1102),(0028,1102)  
-  *            - xxx Palette Color Lookup Table Descriptor - are found
-  *          and (0028,1201),(0028,1202),(0028,1202) 
-  *            - xxx Palette Color Lookup Table Data - are found 
-  * \warning does NOT deal with :
-  *   0028 1100 Gray Lookup Table Descriptor (Retired)
-  *   0028 1221 Segmented Red Palette Color Lookup Table Data
-  *   0028 1222 Segmented Green Palette Color Lookup Table Data
-  *   0028 1223 Segmented Blue Palette Color Lookup Table Data 
-  *   no known Dicom reader deals with them :-(
-  * @return a RGBA Lookup Table 
-  */ 
-uint8_t* Header::GetLUTRGBA()
-{
-   // Not so easy : see 
-   // http://www.barre.nom.fr/medical/dicom2/limitations.html#Color%20Lookup%20Tables
-
-//  if Photometric Interpretation # PALETTE COLOR, no LUT to be done
-   if ( GetEntryByNumber(0x0028,0x0004) != "PALETTE COLOR " )
-   {
-      return NULL;
-   }
-
-   int lengthR, debR, nbitsR;
-   int lengthG, debG, nbitsG;
-   int lengthB, debB, nbitsB;
-   
-   // Get info from Lut Descriptors
-   // (the 3 LUT descriptors may be different)    
-   std::string lutDescriptionR = GetEntryByNumber(0x0028,0x1101);
-   if ( lutDescriptionR == GDCM_UNFOUND )
-   {
-      return NULL;
-   }
-
-   std::string lutDescriptionG = GetEntryByNumber(0x0028,0x1102);
-   if ( lutDescriptionG == GDCM_UNFOUND )
-   {
-      return NULL;
-   }
-
-   std::string lutDescriptionB = GetEntryByNumber(0x0028,0x1103);
-   if ( lutDescriptionB == GDCM_UNFOUND )
-   {
-      return NULL;
-   }
-
-   // lengthR: Red LUT length in Bytes
-   // debR:    subscript of the first Lut Value
-   // nbitsR:  Lut item size (in Bits)
-   int nbRead = sscanf( lutDescriptionR.c_str(), "%d\\%d\\%d", 
-                        &lengthR, &debR, &nbitsR );
-   if( nbRead != 3 )
-   {
-      dbg.Verbose(0, "Header::GetLUTRGBA: trouble reading red LUT");
-   }
-   
-   // lengthG: Green LUT length in Bytes
-   // debG:    subscript of the first Lut Value
-   // nbitsG:  Lut item size (in Bits)
-   nbRead = sscanf( lutDescriptionG.c_str(), "%d\\%d\\%d", 
-                    &lengthG, &debG, &nbitsG );
-   if( nbRead != 3 )
-   {
-      dbg.Verbose(0, "Header::GetLUTRGBA: trouble reading green LUT");
-   }
-
-   // lengthB: Blue LUT length in Bytes
-   // debB:    subscript of the first Lut Value
-   // nbitsB:  Lut item size (in Bits)
-   nbRead = sscanf( lutDescriptionB.c_str(), "%d\\%d\\%d", 
-                    &lengthB, &debB, &nbitsB );
-   if( nbRead != 3 )
-   {
-      dbg.Verbose(0, "Header::GetLUTRGBA: trouble reading blue LUT");
-   }
-   // Load LUTs into memory, (as they were stored on disk)
-   uint8_t* lutR = (uint8_t*) GetEntryBinAreaByNumber(0x0028,0x1201);
-   uint8_t* lutG = (uint8_t*) GetEntryBinAreaByNumber(0x0028,0x1202);
-   uint8_t* lutB = (uint8_t*) GetEntryBinAreaByNumber(0x0028,0x1203); 
-
-   if ( !lutR || !lutG || !lutB )
-   {
-      dbg.Verbose(0, "Header::GetLUTRGBA: trouble with one of the LUT");
-      return NULL;
-   } 
-   // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT 
-
-   uint8_t* LUTRGBA = new uint8_t[1024]; // 256 * 4 (R, G, B, Alpha) 
-   if ( !LUTRGBA )
-   {
-      return NULL;
-   }
-   memset(LUTRGBA, 0, 1024);
-
-   // Bits Allocated
-   int nb;
-   std::string str_nb = GetEntryByNumber(0x0028,0x0100);
-   if ( str_nb == GDCM_UNFOUND )
-   {
-      nb = 16;
-   }
-   else
-   {
-      nb = atoi( str_nb.c_str() );
-   }
-   int mult;
-
-   if ( nbitsR == 16 && nb == 8)
-   {
-      // when LUT item size is different than pixel size
-      mult = 2; // high byte must be = low byte 
-   }
-   else
-   {
-      // See PS 3.3-2003 C.11.1.1.2 p 619
-      mult = 1;
-   }
-
-   // if we get a black image, let's just remove the '+1'
-   // from 'i*mult+1' and check again 
-   // if it works, we shall have to check the 3 Palettes
-   // to see which byte is ==0 (first one, or second one)
-   // and fix the code
-   // We give up the checking to avoid some (useless ?)overhead 
-   // (optimistic asumption)
-   uint8_t* a;      
-   int i;
-
-   a = LUTRGBA + 0;
-   for( i=0; i < lengthR; ++i)
-   {
-      *a = lutR[i*mult+1];
-      a += 4;
-   }        
-
-   a = LUTRGBA + 1;
-   for( i=0; i < lengthG; ++i)
-   {
-      *a = lutG[i*mult+1];
-      a += 4;
-   }  
-
-   a = LUTRGBA + 2;
-   for(i=0; i < lengthB; ++i)
-   {
-      *a = lutB[i*mult+1];
-      a += 4;
-   }
-
-   a = LUTRGBA + 3;
-   for(i=0; i < 256; ++i)
-   {
-      *a = 1; // Alpha component
-      a += 4;
-   }
-   return LUTRGBA;
-} 
-
 /**
  * \brief Accesses the info from 0002,0010 : Transfert Syntax and TS
  *        else 1.
index b16dd9af44065f88d401af7df3bf49296ead0d01..684b99aac0d2641d1caebf7fc3654684111f981d 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmHeader.h,v $
   Language:  C++
-  Date:      $Date: 2004/10/12 04:35:46 $
-  Version:   $Revision: 1.89 $
+  Date:      $Date: 2004/10/18 12:49:22 $
+  Version:   $Revision: 1.90 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -162,7 +162,6 @@ public:
 
    bool   HasLUT();
    int    GetLUTNbits();
-   unsigned char * GetLUTRGBA();
 
    std::string GetTransfertSyntaxName();
 
index 80cd904d62d00344cc84efe13cdd96c53c7e7d24..815750eb0f44353c3cd120f06f11cd6802edd99f 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmJPEGFragmentsInfo.h,v $
   Language:  C++
-  Date:      $Date: 2004/10/14 22:35:01 $
-  Version:   $Revision: 1.3 $
+  Date:      $Date: 2004/10/18 12:49:22 $
+  Version:   $Revision: 1.4 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -39,10 +39,11 @@ namespace gdcm
  */
 class GDCM_EXPORT JPEGFragmentsInfo
 {
-   typedef std::list< JPEGFragment* > JPEGFragmentsList;
 friend class Document;
 friend class File;
 friend class PixelConvert;
+private:
+   typedef std::list< JPEGFragment* > JPEGFragmentsList;
    JPEGFragmentsList Fragments;
 public:
    ~JPEGFragmentsInfo();
index b9e5e3ab0f97554944e5dc0398c78a1e1345cafc..4649cbb11bf3d980077c0f5e663700503907e559 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmPixelConvert.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/10/15 10:43:28 $
-  Version:   $Revision: 1.14 $
+  Date:      $Date: 2004/10/18 12:49:22 $
+  Version:   $Revision: 1.15 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -53,16 +53,26 @@ PixelConvert::PixelConvert()
    RGBSize = 0;
    Decompressed = 0;
    DecompressedSize = 0;
+   LutRGBA = 0;
+   LutRedData = 0;
+   LutGreenData = 0;
+   LutBlueData =0;
 }
 
 void PixelConvert::Squeeze() 
 {
-   if ( RGB ) {
+   if ( RGB )
+   {
       delete [] RGB;
    } 
-   if ( Decompressed ) {
+   if ( Decompressed )
+   {
       delete [] Decompressed;
    }
+   if ( LutRGBA )
+   {
+      delete [] LutRGBA;
+   }
 }
 
 PixelConvert::~PixelConvert() 
@@ -75,7 +85,7 @@ void PixelConvert::AllocateRGB()
   if ( RGB ) {
      delete [] RGB;
   }
-  RGB = new uint8_t[RGBSize];
+  RGB = new uint8_t[ RGBSize ];
 }
 
 void PixelConvert::AllocateDecompressed()
@@ -87,7 +97,7 @@ void PixelConvert::AllocateDecompressed()
 }
 
 /**
- * \brief Read from file a 12 bits per pixel image and uncompress it
+ * \brief Read from file a 12 bits per pixel image and decompress it
  *        into a 16 bits per pixel image.
  */
 void PixelConvert::ReadAndDecompress12BitsTo16Bits( FILE* fp )
@@ -146,15 +156,15 @@ void PixelConvert::ReadAndDecompress12BitsTo16Bits( FILE* fp )
 bool PixelConvert::DecompressRLE16BitsFromRLE8Bits( int NumberOfFrames )
 {
    size_t PixelNumber = XSize * YSize;
-   size_t uncompressedSize = XSize * YSize * NumberOfFrames;
+   size_t decompressedSize = XSize * YSize * NumberOfFrames;
 
    // We assumed Decompressed contains the decoded RLE pixels but as
    // 8 bits per pixel. In order to convert those pixels to 16 bits
    // per pixel we cannot work in place within Decompressed and hence
    // we copy it in a safe place, say copyDecompressed.
 
-   uint8_t* copyDecompressed = new uint8_t[ uncompressedSize * 2 ];
-   memmove( copyDecompressed, Decompressed, uncompressedSize * 2 );
+   uint8_t* copyDecompressed = new uint8_t[ decompressedSize * 2 ];
+   memmove( copyDecompressed, Decompressed, decompressedSize * 2 );
 
    uint8_t* x = Decompressed;
    uint8_t* a = copyDecompressed;
@@ -176,26 +186,26 @@ bool PixelConvert::DecompressRLE16BitsFromRLE8Bits( int NumberOfFrames )
 }
 
 /**
- * \brief Implementation of the RLE decoding algorithm for uncompressing
+ * \brief Implementation of the RLE decoding algorithm for decompressing
  *        a RLE fragment. [refer to PS 3.5-2003, section G.3.2 p 86]
  * @param subDecompressed Sub region of \ref Decompressed where the de
  *        decoded fragment should be placed.
  * @param fragmentSize The length of the binary fragment as found on the disk.
- * @param uncompressedSegmentSize The expected length of the fragment ONCE
+ * @param decompressedSegmentSize The expected length of the fragment ONCE
  *        decompressed.
  * @param fp File Pointer: on entry the position should be the one of
  *        the fragment to be decoded.
  */
 bool PixelConvert::ReadAndDecompressRLEFragment( uint8_t* subDecompressed,
                                                  long fragmentSize,
-                                                 long uncompressedSegmentSize,
+                                                 long decompressedSegmentSize,
                                                  FILE* fp )
 {
    int8_t count;
    long numberOfOutputBytes = 0;
    long numberOfReadBytes = 0;
                                                                                 
-   while( numberOfOutputBytes < uncompressedSegmentSize )
+   while( numberOfOutputBytes < decompressedSegmentSize )
    {
       fread( &count, 1, 1, fp );
       numberOfReadBytes += 1;
@@ -239,7 +249,7 @@ bool PixelConvert::ReadAndDecompressRLEFragment( uint8_t* subDecompressed,
 
 /**
  * \brief     Reads from disk the Pixel Data of 'Run Length Encoded'
- *            Dicom encapsulated file and uncompress it.
+ *            Dicom encapsulated file and decompress it.
  * @param     fp already open File Pointer
  *            at which the pixel data should be copied
  * @return    Boolean
@@ -385,7 +395,7 @@ void PixelConvert::ConvertReorderEndianity()
 
 /**
  * \brief     Reads from disk the Pixel Data of JPEG Dicom encapsulated
- &            file and uncompress it.
+ &            file and decompress it.
  * @param     fp File Pointer
  * @return    Boolean
  */
@@ -572,9 +582,7 @@ void PixelConvert::ConvertRGBPlanesToRGBPixels()
 
 bool PixelConvert::ReadAndDecompressPixelData( FILE* fp )
 {
-   ComputeDecompressedImageDataSize();
-   if ( HasLUT )
-      DecompressedSize *= 3;
+   ComputeDecompressedAndRGBSizes();
    AllocateDecompressed();
    //////////////////////////////////////////////////
    //// First stage: get our hands on the Pixel Data.
@@ -593,18 +601,18 @@ bool PixelConvert::ReadAndDecompressPixelData( FILE* fp )
    }
                                                                                 
    //////////////////////////////////////////////////
-   //// Second stage: read from disk dans uncompress.
+   //// Second stage: read from disk dans decompress.
    if ( BitsAllocated == 12 )
    {
       ReadAndDecompress12BitsTo16Bits( fp);
    }
-   else if ( IsUncompressed )
+   else if ( IsDecompressed )
    {
       size_t ItemRead = fread( Decompressed, PixelDataLength, 1, fp );
       if ( ItemRead != 1 )
       {
          dbg.Verbose( 0, "PixelConvert::ReadAndDecompressPixelData: "
-                         "reading of uncompressed pixel data failed." );
+                         "reading of decompressed pixel data failed." );
          return false;
       }
    } 
@@ -715,7 +723,7 @@ bool PixelConvert::IsDecompressedRGB()
    return true;
 }
 
-void PixelConvert::ComputeDecompressedImageDataSize()
+void PixelConvert::ComputeDecompressedAndRGBSizes()
 {
    int bitsAllocated = BitsAllocated;
    // Number of "Bits Allocated" is fixed to 16 when it's 12, since
@@ -726,11 +734,317 @@ void PixelConvert::ComputeDecompressedImageDataSize()
       bitsAllocated = 16;
    }
                                                                                 
-   DecompressedSize = XSize * YSize * ZSize
-                    * ( bitsAllocated / 8 )
-                    * SamplesPerPixel;
+   DecompressedSize =  XSize * YSize * ZSize
+                     * ( bitsAllocated / 8 )
+                     * SamplesPerPixel;
+   if ( HasLUT )
+   {
+      RGBSize = 3 * DecompressedSize;
+   }
+
+}
+
+void PixelConvert::GrabInformationsFromHeader( Header* header )
+{
+   // Just in case some access to a Header element requires disk access.
+   // Note: gdcmDocument::Fp is leaved open after OpenFile.
+   FILE* fp = header->OpenFile();
+   // Number of Bits Allocated for storing a Pixel is defaulted to 16
+   // when absent from the header.
+   BitsAllocated = header->GetBitsAllocated();
+   if ( BitsAllocated == 0 )
+   {
+      BitsAllocated = 16;
+   }
+
+   // Number of "Bits Stored" defaulted to number of "Bits Allocated"
+   // when absent from the header.
+   BitsStored = header->GetBitsStored();
+   if ( BitsStored == 0 )
+   {
+      BitsStored = BitsAllocated;
+   }
+
+   // High Bit Position
+   HighBitPosition = header->GetHighBitPosition();
+   if ( HighBitPosition == 0 )
+   {
+      HighBitPosition = BitsAllocated - 1;
+   }
+
+   XSize = header->GetXSize();
+   YSize = header->GetYSize();
+   ZSize = header->GetZSize();
+   SamplesPerPixel = header->GetSamplesPerPixel();
+   PixelSize = header->GetPixelSize();
+   PixelSign = header->IsSignedPixelData();
+   SwapCode  = header->GetSwapCode();
+   IsDecompressed =
+        ( ! header->IsDicomV3() )
+     || header->IsImplicitVRLittleEndianTransferSyntax()
+     || header->IsExplicitVRLittleEndianTransferSyntax()
+     || header->IsExplicitVRBigEndianTransferSyntax()
+     || header->IsDeflatedExplicitVRLittleEndianTransferSyntax();
+   IsJPEG2000     = header->IsJPEG2000();
+   IsJPEGLossless = header->IsJPEGLossless();
+   IsRLELossless  = header->IsRLELossLessTransferSyntax();
+   PixelOffset     = header->GetPixelOffset();
+   PixelDataLength = header->GetPixelAreaLength();
+   RLEInfo  = header->GetRLEInfo();
+   JPEGInfo = header->GetJPEGInfo();
+                                                                             
+   PlanarConfiguration = header->GetPlanarConfiguration();
+   IsMonochrome = header->IsMonochrome();
+   IsPaletteColor = header->IsPaletteColor();
+   IsYBRFull = header->IsYBRFull();
+
+   /////////////////////////////////////////////////////////////////
+   // LUT section:
+   HasLUT = header->HasLUT();
+   if ( HasLUT )
+   {
+      LutRedDescriptor   = header->GetEntryByNumber( 0x0028, 0x1101 );
+      LutGreenDescriptor = header->GetEntryByNumber( 0x0028, 0x1102 );
+      LutBlueDescriptor  = header->GetEntryByNumber( 0x0028, 0x1103 );
+   
+      // 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 header
+      // and when this fails we read the LUTs data directely 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. BinEntry::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:
+      LutRedData = (uint8_t*)header->GetEntryBinAreaByNumber( 0x0028, 0x1201 );
+      if ( ! LutRedData )
+      {
+         // Read the Lut Data from disk
+         DocEntry* lutRedDataEntry = header->GetDocEntryByNumber( 0x0028,
+                                                                  0x1201 );
+         LutRedData = new uint8_t[ lutRedDataEntry->GetLength() ];
+         fseek( fp, lutRedDataEntry->GetOffset() ,SEEK_SET );
+         int numberItem = fread( LutRedData,
+                                 (size_t)lutRedDataEntry->GetLength(),
+                                 1, fp );
+         if ( numberItem != 1 )
+         {
+            dbg.Verbose(0, "PixelConvert::GrabInformationsFromHeader: "
+                            "unable to read red LUT data" );
+            return;
+         }
+      }
+   
+      ////// Green round:
+      LutGreenData = (uint8_t*)header->GetEntryBinAreaByNumber(0x0028, 0x1202 );
+      if ( ! LutGreenData)
+      {
+         // Read the Lut Data from disk
+         DocEntry* lutGreenDataEntry = header->GetDocEntryByNumber( 0x0028,
+                                                                    0x1202 );
+         LutGreenData = new uint8_t[ lutGreenDataEntry->GetLength() ];
+         fseek( fp, lutGreenDataEntry->GetOffset() ,SEEK_SET );
+         int numberItem = fread( LutGreenData,
+                                 (size_t)lutGreenDataEntry->GetLength(),
+                                 1, fp );
+         if ( numberItem != 1 )
+         {
+            dbg.Verbose(0, "PixelConvert::GrabInformationsFromHeader: "
+                           "unable to read green LUT data" );
+            return;
+         }
+      }
+                                                                                   
+      ////// Blue round:
+      LutBlueData = (uint8_t*)header->GetEntryBinAreaByNumber( 0x0028, 0x1203 );
+      if ( ! LutBlueData )
+      {
+         // Read the Lut Data from disk
+         DocEntry* lutBlueDataEntry  = header->GetDocEntryByNumber( 0x0028,
+                                                                    0x1203 );
+         LutBlueData = new uint8_t[ lutBlueDataEntry->GetLength() ];
+         fseek( fp, lutBlueDataEntry->GetOffset() ,SEEK_SET );
+         int numberItem = fread( LutBlueData,
+                                 (size_t)lutBlueDataEntry->GetLength(),
+                                 1, fp );
+         if ( numberItem != 1 )
+         {
+            dbg.Verbose(0, "PixelConvert::GrabInformationsFromHeader: "
+                           "unable to read blue LUT data" );
+            return;
+         }
+      }
+   }
+                                                                                
+   header->CloseFile();
+}
+
+/**
+ * \brief Build Red/Green/Blue/Alpha LUT from Header
+ *         when (0028,0004),Photometric Interpretation = [PALETTE COLOR ]
+ *          and (0028,1101),(0028,1102),(0028,1102)
+ *            - xxx Palette Color Lookup Table Descriptor - are found
+ *          and (0028,1201),(0028,1202),(0028,1202)
+ *            - xxx Palette Color Lookup Table Data - are found
+ * \warning does NOT deal with :
+ *   0028 1100 Gray Lookup Table Descriptor (Retired)
+ *   0028 1221 Segmented Red Palette Color Lookup Table Data
+ *   0028 1222 Segmented Green Palette Color Lookup Table Data
+ *   0028 1223 Segmented Blue Palette Color Lookup Table Data
+ *   no known Dicom reader deals with them :-(
+ * @return a RGBA Lookup Table
+ */
+void PixelConvert::BuildLUTRGBA( FILE* fp )
+{
+   if ( LutRGBA )
+   {
+      return;
+   }
+   // Not so easy : see
+   // http://www.barre.nom.fr/medical/dicom2/limitations.html#Color%20Lookup%20Tables
+                                                                                
+   if ( ! IsPaletteColor )
+   {
+      return;
+   }
+                                                                                
+   if (   ( LutRedDescriptor   == GDCM_UNFOUND )
+       || ( LutGreenDescriptor == GDCM_UNFOUND )
+       || ( LutBlueDescriptor  == GDCM_UNFOUND ) )
+   {
+      return;
+   }
+
+   ////////////////////////////////////////////
+   // Extract the info from the LUT descriptors
+   int lengthR;   // Red LUT length in Bytes
+   int debR;      // Subscript of the first Lut Value
+   int nbitsR;    // Lut item size (in Bits)
+   int nbRead = sscanf( LutRedDescriptor.c_str(),
+                        "%d\\%d\\%d",
+                        &lengthR, &debR, &nbitsR );
+   if( nbRead != 3 )
+   {
+      dbg.Verbose(0, "PixelConvert::BuildLUTRGBA: wrong red LUT descriptor");
+   }
+                                                                                
+   int lengthG;  // Green LUT length in Bytes
+   int debG;     // Subscript of the first Lut Value
+   int nbitsG;   // Lut item size (in Bits)
+   nbRead = sscanf( LutGreenDescriptor.c_str(),
+                    "%d\\%d\\%d",
+                    &lengthG, &debG, &nbitsG );
+   if( nbRead != 3 )
+   {
+      dbg.Verbose(0, "PixelConvert::BuildLUTRGBA: wrong green LUT descriptor");
+   }
+                                                                                
+   int lengthB;  // Blue LUT length in Bytes
+   int debB;     // Subscript of the first Lut Value
+   int nbitsB;   // Lut item size (in Bits)
+   nbRead = sscanf( LutRedDescriptor.c_str(),
+                    "%d\\%d\\%d",
+                    &lengthB, &debB, &nbitsB );
+   if( nbRead != 3 )
+   {
+      dbg.Verbose(0, "PixelConvert::BuildLUTRGBA: wrong blue LUT descriptor");
+   }
+                                                                                
+   ////////////////////////////////////////////////////////
+   if ( ( ! LutRedData ) || ( ! LutGreenData ) || ( ! LutBlueData ) )
+   {
+      return;
+   }
+
+   ////////////////////////////////////////////////
+   // forge the 4 * 8 Bits Red/Green/Blue/Alpha LUT
+   LutRGBA = new uint8_t[ 1024 ]; // 256 * 4 (R, G, B, Alpha)
+   if ( !LutRGBA )
+   {
+      return;
+   }
+   memset( LutRGBA, 0, 1024 );
+                                                                                
+   int mult;
+   if ( ( nbitsR == 16 ) && ( BitsAllocated == 8 ) )
+   {
+      // when LUT item size is different than pixel size
+      mult = 2; // high byte must be = low byte
+   }
+   else
+   {
+      // See PS 3.3-2003 C.11.1.1.2 p 619
+      mult = 1;
+   }
+                                                                                
+   // if we get a black image, let's just remove the '+1'
+   // from 'i*mult+1' and check again
+   // if it works, we shall have to check the 3 Palettes
+   // to see which byte is ==0 (first one, or second one)
+   // and fix the code
+   // We give up the checking to avoid some (useless ?)overhead
+   // (optimistic asumption)
+   int i;
+   uint8_t* a = LutRGBA + 0;
+   for( i=0; i < lengthR; ++i )
+   {
+      *a = LutRedData[i*mult+1];
+      a += 4;
+   }
+                                                                                
+   a = LutRGBA + 1;
+   for( i=0; i < lengthG; ++i)
+   {
+      *a = LutGreenData[i*mult+1];
+      a += 4;
+   }
+                                                                                
+   a = LutRGBA + 2;
+   for(i=0; i < lengthB; ++i)
+   {
+      *a = LutBlueData[i*mult+1];
+      a += 4;
+   }
+                                                                                
+   a = LutRGBA + 3;
+   for(i=0; i < 256; ++i)
+   {
+      *a = 1; // Alpha component
+      a += 4;
+   }
 }
 
+/**
+ * \brief Build the RGB image from the Decompressed imagage and the LUTs.
+ */
+bool PixelConvert::BuildRGBImage( FILE* fp )
+{
+   BuildLUTRGBA( fp );
+   if ( ! LutRGBA )
+   {
+       return false;
+   }
+                                                                                
+   // Build RGB Pixels
+   AllocateRGB();
+   uint8_t* localRGB = RGB;
+   for (size_t i = 0; i < DecompressedSize; ++i )
+   {
+      int j  = Decompressed[i] * 4; // \todo I don't get this 4 coefficient !
+      *localRGB++ = LutRGBA[j];
+      *localRGB++ = LutRGBA[j+1];
+      *localRGB++ = LutRGBA[j+2];
+   }
+   return true;
+}
+
+
 } // end namespace gdcm
 
 // NOTES on File internal calls
index 784c2e0e6b81cad59a94c8c9f7e60b67403c7404..e65a701c0470924d1c532f48af57be3adcadb175 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmPixelConvert.h,v $
   Language:  C++
-  Date:      $Date: 2004/10/15 10:43:28 $
-  Version:   $Revision: 1.9 $
+  Date:      $Date: 2004/10/18 12:49:23 $
+  Version:   $Revision: 1.10 $
                                                                                 
   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 "gdcmRLEFramesInfo.h"
 #include "gdcmJPEGFragmentsInfo.h"
 #include "gdcmException.h"
+#include "gdcmHeader.h"
 
 namespace gdcm
 {
@@ -33,106 +34,37 @@ namespace gdcm
  *        migth take during the user demanded processes.
  */
 class GDCM_EXPORT PixelConvert {
-friend class File;
-   /// Pixel data represented as RGB after color interpretation
-   uint8_t* RGB;
-   size_t   RGBSize;          //aka ImageDataSize
-   /// Pixel data after decompression and bit/byte rearrangement.
-   uint8_t* Decompressed;
-   size_t   DecompressedSize;
-
-   // Set by the accessors:
-   size_t PixelOffset;
-   size_t PixelDataLength;
-   int XSize;
-   int YSize;
-   int ZSize;
-   int BitsAllocated;
-   int BitsStored;
-   int HighBitPosition;
-   int SamplesPerPixel;
-   int PixelSize;
-   bool PixelSign;
-   int SwapCode;
-
-   bool IsUncompressed;
-   bool IsJPEG2000;
-   bool IsJPEGLossless;
-   bool IsRLELossless;
-
-   RLEFramesInfo* RLEInfo;
-   JPEGFragmentsInfo* JPEGInfo;
-
-   // For handling color stage
-   int PlanarConfiguration;
-   bool IsMonochrome;
-   bool IsPaletteColor;
-   bool IsYBRFull;
-   bool HasLUT;
-
 public:
    PixelConvert();
    ~PixelConvert();
 
-   //// Setter accessors:
-   void SetXSize( int xSize ) { XSize = xSize; }
-   void SetYSize( int ySize ) { YSize = ySize; }
-   void SetZSize( int zSize ) { ZSize = zSize; }
-   void SetBitsAllocated( int bitsAllocated ) { BitsAllocated = bitsAllocated; }
-   void SetBitsStored( int bitsStored ) { BitsStored = bitsStored; }
-   void SetHighBitPosition( int highBitPosition )
-           { HighBitPosition = highBitPosition; }
-   void SetSamplesPerPixel( int samplesPerPixel )
-           { SamplesPerPixel = samplesPerPixel; }
-   void SetPixelSize( int pixelSize ) { PixelSize = pixelSize; }
-   void SetPixelSign( int pixelSign ) { PixelSign = pixelSign; }
-   void SetSwapCode( int swapCode ) { SwapCode = swapCode; }
-   void SetIsUncompressed( bool isUncompressed )
-           { IsUncompressed = isUncompressed; }
-   void SetIsJPEG2000( bool isJPEG2000 ) { IsJPEG2000 = isJPEG2000; }
-   void SetIsJPEGLossless( bool isJPEGLossless )
-           { IsJPEGLossless = isJPEGLossless; }
-   void SetIsRLELossless( bool isRLELossless )
-           { IsRLELossless = isRLELossless; }
-   void SetPixelOffset( size_t pixelOffset ) { PixelOffset = pixelOffset; }
-   void SetPixelDataLength( size_t pixelDataLength )
-           { PixelDataLength = pixelDataLength; }
-   void SetRLEInfo( RLEFramesInfo* inRLEFramesInfo )
-           { RLEInfo = inRLEFramesInfo; }
-   void SetJPEGInfo( JPEGFragmentsInfo* inJPEGFragmentsInfo )
-           { JPEGInfo = inJPEGFragmentsInfo; }
-
-   void SetPlanarConfiguration( size_t planarConfiguration )
-           { PlanarConfiguration = planarConfiguration; }
-   void SetIsMonochrome( bool isMonochrome ) { IsMonochrome = isMonochrome; }
-   void SetIsPaletteColor( bool isPaletteColor )
-           { IsPaletteColor = isPaletteColor; }
-   void SetIsYBRFull( bool isYBRFull ) { IsYBRFull = isYBRFull; }
-   void SetHasLUT ( bool hasLUT ) { HasLUT = hasLUT; }
-   void     SetRGBSize( size_t size ) { RGBSize = size; }
-   void     SetDecompressedSize( size_t size ) { DecompressedSize = size; }
-
    //// Getter accessors:
    uint8_t* GetRGB() { return RGB; }
    size_t   GetRGBSize() { return RGBSize; }
    uint8_t* GetDecompressed() { return Decompressed; }
    size_t   GetDecompressedSize() { return DecompressedSize; }
+   uint8_t* GetLutRGBA() { return LutRGBA; }
 
    //// Predicates:
    bool IsDecompressedRGB();
 
-//////////////////////////////////////////////////////////
+// In progress
+   void GrabInformationsFromHeader( Header* header );
+   bool ReadAndDecompressPixelData( FILE* fp );
+   void Squeeze();
+   bool BuildRGBImage( FILE* fp );
+
 private:
    // Use the fp:
    bool ReadAndDecompressRLEFragment(
-                  uint8_t* decodedZone,
+                  uint8_t* subDecompressed,
                   long fragmentSize,
-                  long uncompressedSegmentSize,
+                  long decompressedSegmentSize,
                   FILE* fp );
    void ReadAndDecompress12BitsTo16Bits( FILE* fp ) throw ( FormatError );
    bool ReadAndDecompressRLEFile( FILE* fp );
    bool ReadAndDecompressJPEGFile( FILE* fp );
+   void BuildLUTRGBA( FILE* fp );
 
    // In place (within Decompressed and with no fp access) decompression
    // or convertion:
@@ -144,13 +76,58 @@ private:
    void ConvertYcBcRPlanesToRGBPixels();
    void ConvertHandleColor();
 
-   void ComputeDecompressedImageDataSize();
+   void ComputeDecompressedAndRGBSizes();
    void AllocateRGB();
    void AllocateDecompressed();
-public:
-// In progress
-   bool ReadAndDecompressPixelData( FILE* fp );
-   void Squeeze();
+
+// Variables
+   /// Pixel data represented as RGB after LUT color interpretation.
+   uint8_t* RGB;
+   /// Size of \ref RGB image.
+   size_t   RGBSize;
+   /// Pixel data after decompression and bit/byte rearrangement.
+   uint8_t* Decompressed;
+   /// Size of \ref Decompressed image.
+   size_t   DecompressedSize;
+   /// \brief Red/Green/Blue/Alpha LookUpTable build out of the
+   ///        Red/Green/Blue LUT descriptors (see \ref BuildLUTRGBA ).
+   uint8_t* LutRGBA;
+
+   size_t PixelOffset;
+   size_t PixelDataLength;
+   int XSize;
+   int YSize;
+   int ZSize;
+   int BitsAllocated;
+   int BitsStored;
+   int HighBitPosition;
+   int SamplesPerPixel;
+   int PixelSize;
+   bool PixelSign;
+   int SwapCode;
+
+   bool IsDecompressed;
+   bool IsJPEG2000;
+   bool IsJPEGLossless;
+   bool IsRLELossless;
+
+   RLEFramesInfo* RLEInfo;
+   JPEGFragmentsInfo* JPEGInfo;
+
+   // For handling color stage
+   int PlanarConfiguration;
+   bool IsMonochrome;
+   bool IsPaletteColor;
+   bool IsYBRFull;
+   bool HasLUT;
+   // The 3 LUT descriptors may be different:
+   std::string LutRedDescriptor;
+   std::string LutGreenDescriptor;
+   std::string LutBlueDescriptor;
+   uint8_t* LutRedData;
+   uint8_t* LutGreenData;
+   uint8_t* LutBlueData;
+
 };
 } // end namespace gdcm
 
index f1e27c6e3316a7eb5207dd375b030964b0a7b93b..f7dcf0d5575ed2f88d88faa9dc2f5bd25e9bc8e8 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmRLEFrame.h,v $
   Language:  C++
-  Date:      $Date: 2004/10/12 04:35:47 $
-  Version:   $Revision: 1.5 $
+  Date:      $Date: 2004/10/18 12:49:23 $
+  Version:   $Revision: 1.6 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -21,6 +21,7 @@
 #define GDCMRLEFRAME_H
 
 #include "gdcmCommon.h"
+
 namespace gdcm 
 {
 /**
index dc8662708c825f645b121456b40ceed821f1ccc1..60f038133515f425eb5533af06f917dd343093c3 100644 (file)
@@ -58,7 +58,7 @@
 #include <vtkPointData.h>
 #include <vtkLookupTable.h>
 
-vtkCxxRevisionMacro(vtkGdcmReader, "$Revision: 1.51 $");
+vtkCxxRevisionMacro(vtkGdcmReader, "$Revision: 1.52 $");
 vtkStandardNewMacro(vtkGdcmReader);
 
 //-----------------------------------------------------------------------------
@@ -633,7 +633,7 @@ size_t vtkGdcmReader::LoadImageInMemory(
    {
       size               = file.GetImageDataSizeRaw();
       source             = (unsigned char*) file.GetImageDataRaw();
-      unsigned char *lut =                  file.GetHeader()->GetLUTRGBA();
+      unsigned char *lut = (unsigned char*) file.GetLutRGBA();
 
       if(!this->LookupTable)
       {