]> Creatis software - gdcm.git/commitdiff
* CLEANUP_ROUND (11) for gdcmPixelConvert (cafeine is my friend stage)
authorfrog <frog>
Tue, 12 Oct 2004 09:59:44 +0000 (09:59 +0000)
committerfrog <frog>
Tue, 12 Oct 2004 09:59:44 +0000 (09:59 +0000)
    src/gdcmFile.[cxx|h] and gdcmPixelConvert.[cxx|h]:
     - more code moved away from File:: to PixelConvert::
     - fat setup of PixelConverter set in place in File::Initialise.

ChangeLog
src/gdcmFile.cxx
src/gdcmFile.h
src/gdcmPixelConvert.cxx
src/gdcmPixelConvert.h

index 7b3e64d3744851ecdde6ac1a36ca2559754f9ee1..e9dc56562d6b0af629c0d8276911bea60cb320b8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,16 @@
+2004-10-12 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
+  * CLEANUP_ROUND (11) for gdcmPixelConvert (cafeine is my friend stage)
+    src/gdcmFile.[cxx|h] and gdcmPixelConvert.[cxx|h]:
+     - more code moved away from File:: to PixelConvert::
+     - fat setup of PixelConverter set in place in File::Initialise.
+
 2004-10-10 Eric Boix <Eric.Boix@creatis.insa-lyon.fr>
   * CLEANUP_ROUND (10) for gdcmPixelConvert (Xanax is my friend stage)
     The JPEG fragments are now parsed at the same stage than the RLE
     information. All code related to JPEG is now in gdcmPixelConvert:
     - src/gdcmJPEGFragment.h and gdcmJPEGFragmentsInfo.[h|cxx] added 
     - src/gdcmJpeg12.cxx, gdcmJpeg2000.cxx and gdcmJpeg8.cxx no longer
-      export a gdcmFile:: method. This are simply global functions
+      export a gdcmFile:: method. Those are simply global functions
       (for the time being this is better than having them attach to
        either gdcmFile:: or gdcmPixelConvert::).
     - src/gdcmDocument.[cxx|h], gdcmDocument:: now parser the JPEG fragments
index 3484aecf075b7f470081797e839877fc5ff296f3..9a9dc3ae160adce704c8b32dce1372bd05837286 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmFile.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/10/12 04:35:46 $
-  Version:   $Revision: 1.139 $
+  Date:      $Date: 2004/10/12 09:59:45 $
+  Version:   $Revision: 1.140 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -18,7 +18,6 @@
 
 #include "gdcmFile.h"
 #include "gdcmDebug.h"
-#include "gdcmPixelConvert.h"
 
 namespace gdcm 
 {
@@ -84,6 +83,64 @@ void File::Initialise()
       {
          ImageDataSize = ImageDataSizeRaw;
       }
+
+
+
+                                                                                
+      // Just in case some access to a Header element requires disk access:
+      FILE* fp = 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.SetDecompressedSize( ImageDataSize );
+                                                                                
+      HeaderInternal->CloseFile();
+
    }
    SaveInitialValues();
 }
@@ -266,8 +323,11 @@ int File::ComputeDecompressedPixelDataSizeFromHeader()
    // 0028|1202 [US]   [Green Palette Color Lookup Table Data]
    // 0028|1203 [US]   [Blue Palette Color Lookup Table Data]
 
-   // Number of "Bits Allocated"
    int numberBitsAllocated = HeaderInternal->GetBitsAllocated();
+   // Number of "Bits Allocated" is fixed to 16 when:
+   //  - it is not defined (i.e. it's value is 0)
+   //  - it's 12, since we will expand the image to 16 bits (see
+   //    PixelConvert::ConvertDecompress12BitsTo16Bits() )
    if ( ( numberBitsAllocated == 0 ) || ( numberBitsAllocated == 12 ) )
    {
       numberBitsAllocated = 16;
@@ -496,45 +556,13 @@ size_t File::GetImageDataIntoVectorRaw (void* destination, size_t maxSize)
       return (size_t)0;
    }
 
-   ReadPixelData( destination );
-
-   // Number of Bits Allocated for storing a Pixel
-   int numberBitsAllocated = HeaderInternal->GetBitsAllocated();
-   if ( numberBitsAllocated == 0 )
-   {
-      numberBitsAllocated = 16;
-   }
-
-   // Number of Bits actually used
-   int numberBitsStored = HeaderInternal->GetBitsStored();
-   if ( numberBitsStored == 0 )
-   {
-      numberBitsStored = numberBitsAllocated;
-   }
-
-   // High Bit Position
-   int highBitPosition = HeaderInternal->GetHighBitPosition();
-   if ( highBitPosition == 0 )
-   {
-      highBitPosition = numberBitsAllocated - 1;
-   }
-
-   bool signedPixel = HeaderInternal->IsSignedPixelData();
-
-   PixelConvert::ConvertReorderEndianity(
-                         (uint8_t*) destination,
-                         ImageDataSize,
-                         numberBitsStored,
-                         numberBitsAllocated,
-                         HeaderInternal->GetSwapCode(),
-                         signedPixel );
-
-   PixelConvert::ConvertReArrangeBits(
-                         (uint8_t*) destination,
-                         ImageDataSize,
-                         numberBitsStored,
-                         numberBitsAllocated,
-                         highBitPosition );
+   FILE* fp = HeaderInternal->OpenFile();
+   PixelConverter.ReadAndDecompressPixelData( destination, fp );
+   HeaderInternal->CloseFile();
+                                                                                
+   PixelConverter.ReorderEndianity( (uint8_t*) destination );
+                                                                                
+   PixelConverter.ReArrangeBits( (uint8_t*) destination );
 
 #ifdef GDCM_DEBUG
    FILE*  DebugFile;
@@ -579,18 +607,20 @@ size_t File::GetImageDataIntoVectorRaw (void* destination, size_t maxSize)
 
    if ( planConf == 1 )
    {
-      uint8_t* newDest = new uint8_t[ImageDataSize];
       // Warning : YBR_FULL_422 acts as RGB
       if ( HeaderInternal->IsYBRFull() )
       {
-         ConvertYcBcRPlanesToRGBPixels((uint8_t*)destination, newDest);
+         PixelConverter.ConvertYcBcRPlanesToRGBPixels(
+                              (uint8_t*)destination,
+                              ImageDataSize );
       }
       else
       {
-         ConvertRGBPlanesToRGBPixels((uint8_t*)destination, newDest);
+         PixelConverter.ConvertRGBPlanesToRGBPixels(
+                              (uint8_t*)destination,
+                              ImageDataSize );
       }
-      memmove(destination, newDest, ImageDataSize);
-      delete[] newDest;
+
    }
 
 ///////////////////////////////////////////////////
@@ -616,77 +646,6 @@ size_t File::GetImageDataIntoVectorRaw (void* destination, size_t maxSize)
    return ImageDataSize; 
 }
 
-/**
- * \brief   Convert (Y plane, cB plane, cR plane) to RGB pixels
- * \warning Works on all the frames at a time
- */
-void File::ConvertYcBcRPlanesToRGBPixels(uint8_t* source,
-                                             uint8_t* destination)
-{
-   // to see the tricks about YBR_FULL, YBR_FULL_422, 
-   // YBR_PARTIAL_422, YBR_ICT, YBR_RCT have a look at :
-   // ftp://medical.nema.org/medical/dicom/final/sup61_ft.pdf
-   // and be *very* affraid
-   //
-   int l        = HeaderInternal->GetXSize() * HeaderInternal->GetYSize();
-   int nbFrames = HeaderInternal->GetZSize();
-
-   uint8_t* a = source;
-   uint8_t* b = source + l;
-   uint8_t* c = source + l + l;
-   double R, G, B;
-
-   /// \todo : Replace by the 'well known' integer computation
-   ///         counterpart. Refer to
-   ///            http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf
-   ///         for code optimisation.
-   for (int i = 0; i < nbFrames; i++)
-   {
-      for (int j = 0; j < l; j++)
-      {
-         R = 1.164 *(*a-16) + 1.596 *(*c -128) + 0.5;
-         G = 1.164 *(*a-16) - 0.813 *(*c -128) - 0.392 *(*b -128) + 0.5;
-         B = 1.164 *(*a-16) + 2.017 *(*b -128) + 0.5;
-
-         if (R < 0.0)   R = 0.0;
-         if (G < 0.0)   G = 0.0;
-         if (B < 0.0)   B = 0.0;
-         if (R > 255.0) R = 255.0;
-         if (G > 255.0) G = 255.0;
-         if (B > 255.0) B = 255.0;
-
-         *(destination++) = (uint8_t)R;
-         *(destination++) = (uint8_t)G;
-         *(destination++) = (uint8_t)B;
-         a++;
-         b++;
-         c++;  
-      }
-   }
-}
-
-/**
- * \brief   Convert (Red plane, Green plane, Blue plane) to RGB pixels
- * \warning Works on all the frames at a time
- */
-void File::ConvertRGBPlanesToRGBPixels(uint8_t* source,
-                                           uint8_t* destination)
-{
-   int l = HeaderInternal->GetXSize() * HeaderInternal->GetYSize() * HeaderInternal->GetZSize();
-
-   uint8_t* a = source;
-   uint8_t* b = source + l;
-   uint8_t* c = source + l + l;
-
-   for (int j = 0; j < l; j++)
-   {
-      *(destination++) = *(a++);
-      *(destination++) = *(b++);
-      *(destination++) = *(c++);
-   }
-}
-
 /**
  * \brief   Points the internal Pixel_Data pointer to the callers inData
  *          image representation, BUT WITHOUT COPYING THE DATA.
@@ -874,95 +833,5 @@ bool File::WriteBase (std::string const & fileName, FileType type)
    return true;
 }
 
-//-----------------------------------------------------------------------------
-// Private
-/**
- * \brief   Read pixel data from disk (optionaly decompressing) into the
- *          caller specified memory location.
- * @param   destination where the pixel data should be stored.
- *
- */
-bool File::ReadPixelData(void* destination) 
-{
-   FILE* fp = HeaderInternal->OpenFile();
-
-   if ( !fp )
-   {
-      return false;
-   }
-   if ( fseek(fp, HeaderInternal->GetPixelOffset(), SEEK_SET) == -1 )
-   {
-      HeaderInternal->CloseFile();
-      return false;
-   }
-
-   if ( HeaderInternal->GetBitsAllocated() == 12 )
-   {
-      PixelConvert::ConvertDecompress12BitsTo16Bits(
-                                       (uint8_t*)destination, 
-                                       HeaderInternal->GetXSize(),
-                                       HeaderInternal->GetYSize(),
-                                       fp);
-      HeaderInternal->CloseFile();
-      return true;
-   }
-
-   // ----------------------  Uncompressed File
-   if ( !HeaderInternal->IsDicomV3()                             ||
-        HeaderInternal->IsImplicitVRLittleEndianTransferSyntax() ||
-        HeaderInternal->IsExplicitVRLittleEndianTransferSyntax() ||
-        HeaderInternal->IsExplicitVRBigEndianTransferSyntax()    ||
-        HeaderInternal->IsDeflatedExplicitVRLittleEndianTransferSyntax() )
-   {
-      size_t ItemRead = fread(destination, HeaderInternal->GetPixelAreaLength(), 1, fp);
-      HeaderInternal->CloseFile();
-      if ( ItemRead != 1 )
-      {
-         return false;
-      }
-      else
-      {
-         return true;
-      }
-   }
-
-   // ---------------------- Run Length Encoding
-   if ( HeaderInternal->IsRLELossLessTransferSyntax() )
-   {
-      bool res = PixelConvert::ReadAndDecompressRLEFile(
-                                      destination,
-                                      HeaderInternal->GetXSize(),
-                                      HeaderInternal->GetYSize(),
-                                      HeaderInternal->GetZSize(),
-                                      HeaderInternal->GetBitsAllocated(),
-                                      &(HeaderInternal->RLEInfo),
-                                      fp );
-      HeaderInternal->CloseFile();
-      return res; 
-   }  
-    
-   // --------------- SingleFrame/Multiframe JPEG Lossless/Lossy/2000 
-   int numberBitsAllocated = HeaderInternal->GetBitsAllocated();
-   if ( ( numberBitsAllocated == 0 ) || ( numberBitsAllocated == 12 ) )
-   {
-      numberBitsAllocated = 16;
-   }
-
-   bool res = PixelConvert::ReadAndDecompressJPEGFile(
-                                   (uint8_t*)destination,
-                                   HeaderInternal->GetXSize(),
-                                   HeaderInternal->GetYSize(),
-                                   HeaderInternal->GetBitsAllocated(),
-                                   HeaderInternal->GetBitsStored(),
-                                   HeaderInternal->GetSamplesPerPixel(),
-                                   HeaderInternal->GetPixelSize(),
-                                   HeaderInternal->IsJPEG2000(),
-                                   HeaderInternal->IsJPEGLossless(),
-                                   &(HeaderInternal->JPEGInfo),
-                                   fp );
-   HeaderInternal->CloseFile();
-   return res;
-}
-
 } // end namespace gdcm
 
index 5ef9efeae7b060a8e1743fc435b3fe19b2a66539..31c51a35a133ceea13de6ea2b6dbe8ac0065fa20 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmFile.h,v $
   Language:  C++
-  Date:      $Date: 2004/10/12 04:35:46 $
-  Version:   $Revision: 1.60 $
+  Date:      $Date: 2004/10/12 09:59:45 $
+  Version:   $Revision: 1.61 $
                                                                                 
   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 @@
 
 #include "gdcmCommon.h"
 #include "gdcmHeader.h"
+#include "gdcmPixelConvert.h"
 
 namespace gdcm 
 {
@@ -44,9 +45,6 @@ public:
 
    int ComputeDecompressedPixelDataSizeFromHeader();
 
-   void ConvertRGBPlanesToRGBPixels( uint8_t* source, uint8_t* destination );
-   void ConvertYcBcRPlanesToRGBPixels( uint8_t* source, uint8_t* destination );
-   
    /// Accessor to \ref ImageDataSize
    size_t GetImageDataSize(){ return ImageDataSize; };
 
@@ -89,8 +87,6 @@ protected:
 private:
    void Initialise();
 
-   bool ReadPixelData(void* destination);
-   
    // For JPEG 8 Bits, body in file gdcmJpeg.cxx
    bool gdcm_write_JPEG_file    (FILE* fp, void* image_buffer, 
                                  int image_width, int image_heigh,
@@ -107,7 +103,7 @@ private:
 
 // members variables:
 
-   /// \brief Header to use to load the file
+   /// Header to use to load the file
    Header *HeaderInternal;
 
    /// \brief Whether the underlying \ref Header was loaded by
@@ -118,6 +114,8 @@ private:
    /// wether already parsed 
    bool Parsed;
       
+   /// FIXME
+   PixelConvert PixelConverter;
 //
 // --------------- Will be moved to a PixelData class
 //
index 74f305ac5fcc030cb1cd56ecc3e470b9019dc8c5..d3a0d8963a36ee7dff9069594d4d007411be42f2 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmPixelConvert.cxx,v $
   Language:  C++
-  Date:      $Date: 2004/10/12 04:35:47 $
-  Version:   $Revision: 1.8 $
+  Date:      $Date: 2004/10/12 09:59:45 $
+  Version:   $Revision: 1.9 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
                                                                                 
 =========================================================================*/
 
-//////////////////   TEMPORARY NOT
+//////////////////   TEMPORARY NOTE
 // look for "fixMem" and convert that to a member of this class
 // Removing the prefix fixMem and dealing with allocations should do the trick
 //
 // grep PIXELCONVERT everywhere and clean up !
+
 #include "gdcmDebug.h"
 #include "gdcmPixelConvert.h"
 
 // for JPEGLosslessDecodeImage
 #include "jpeg/ljpg/jpegless.h"
 
-
-namespace gdcm 
+namespace gdcm
 {
-
+                                                                                
 #define str2num(str, typeNum) *((typeNum *)(str))
 
 // For JPEG 2000, body in file gdcmJpeg2000.cxx
@@ -52,8 +52,8 @@ PixelConvert::PixelConvert()
 {
    RGB = 0;
    RGBSize = 0;
-   Uncompressed = 0;
-   UncompressedSize = 0;
+   Decompressed = 0;
+   DecompressedSize = 0;
 }
 
 void PixelConvert::Squeeze() 
@@ -61,8 +61,8 @@ void PixelConvert::Squeeze()
    if ( RGB ) {
       delete [] RGB;
    } 
-   if ( Uncompressed ) {
-      delete [] Uncompressed;
+   if ( Decompressed ) {
+      delete [] Decompressed;
    }
 }
 
@@ -79,26 +79,24 @@ void PixelConvert::AllocateRGB()
   RGB = new uint8_t[RGBSize];
 }
 
-void PixelConvert::AllocateUncompressed()
+void PixelConvert::AllocateDecompressed()
 {
-  if ( Uncompressed ) {
-     delete [] Uncompressed;
+  if ( Decompressed ) {
+     delete [] Decompressed;
   }
-  Uncompressed = new uint8_t[ UncompressedSize ];
+  Decompressed = new uint8_t[ DecompressedSize ];
 }
 
 /**
  * \brief Read from file a 12 bits per pixel image and uncompress it
  *        into a 16 bits per pixel image.
  */
-void PixelConvert::ConvertDecompress12BitsTo16Bits(
+void PixelConvert::Decompress12BitsTo16Bits(
                   uint8_t* pixelZone,
-                  int sizeX,
-                  int sizeY,
                   FILE* filePtr)
                throw ( FormatError )
 {
-   int nbPixels = sizeX * sizeY;
+   int nbPixels = XSize * YSize;
    uint16_t* destination = (uint16_t*)pixelZone;
                                                                                 
    for( int p = 0; p < nbPixels; p += 2 )
@@ -109,22 +107,22 @@ void PixelConvert::ConvertDecompress12BitsTo16Bits(
       ItemRead = fread( &b0, 1, 1, filePtr);
       if ( ItemRead != 1 )
       {
-         throw FormatError( "File::ConvertDecompress12BitsTo16Bits()",
-                            "Unfound first block" );
+         throw FormatError( "File::Decompress12BitsTo16Bits()",
+                                "Unfound first block" );
       }
                                                                                 
       ItemRead = fread( &b1, 1, 1, filePtr);
       if ( ItemRead != 1 )
       {
-         throw FormatError( "File::ConvertDecompress12BitsTo16Bits()",
-                            "Unfound second block" );
+         throw FormatError( "File::Decompress12BitsTo16Bits()",
+                                "Unfound second block" );
       }
                                                                                 
       ItemRead = fread( &b2, 1, 1, filePtr);
       if ( ItemRead != 1 )
       {
-         throw FormatError( "File::ConvertDecompress12BitsTo16Bits()",
-                            "Unfound second block" );
+         throw FormatError( "File::Decompress12BitsTo16Bits()",
+                                "Unfound second block" );
       }
                                                                                 
       // Two steps are necessary to please VC++
@@ -149,8 +147,6 @@ void PixelConvert::ConvertDecompress12BitsTo16Bits(
  * @return    Boolean
  */
 bool PixelConvert::UncompressRLE16BitsFromRLE8Bits(
-                       int XSize,
-                       int YSize,
                        int NumberOfFrames,
                        uint8_t* fixMemUncompressed )
 {
@@ -247,13 +243,9 @@ bool PixelConvert::ReadAndUncompressRLEFragment( uint8_t* decodedZone,
  *            at which the pixel data should be copied
  * @return    Boolean
  */
-bool PixelConvert::ReadAndDecompressRLEFile( void* image_buffer,
-                                   int XSize,
-                                   int YSize,
-                                   int ZSize,
-                                   int BitsAllocated,
-                                   RLEFramesInfo* RLEInfo,
-                                   FILE* fp )
+bool PixelConvert::ReadAndDecompressRLEFile(
+                          void* image_buffer,
+                          FILE* fp )
 {
    uint8_t* im = (uint8_t*)image_buffer;
    long uncompressedSegmentSize = XSize * YSize;
@@ -279,10 +271,7 @@ bool PixelConvert::ReadAndDecompressRLEFile( void* image_buffer,
    if ( BitsAllocated == 16 )
    {
       // Try to deal with RLE 16 Bits
-      (void)PixelConvert::UncompressRLE16BitsFromRLE8Bits(
-                                             XSize,
-                                             YSize,
-                                             ZSize,
+      (void)UncompressRLE16BitsFromRLE8Bits( ZSize,
                                              (uint8_t*) image_buffer);
    }
                                                                                 
@@ -293,18 +282,15 @@ bool PixelConvert::ReadAndDecompressRLEFile( void* image_buffer,
  * \brief   Swap the bytes, according to swap code.
  * \warning not end user intended
  * @param   im area to deal with
- * @param   swap swap code
- * @param   lgr Area Length
- * @param   nb Pixels Bit number
  */
-void PixelConvert::SwapZone(void* im, int swap, int lgr, int nb)
+void PixelConvert::SwapZone( uint8_t* im )
 {
    int i;
                                                                                 
-   if( nb == 16 )
+   if( BitsAllocated == 16 )
    {
       uint16_t* im16 = (uint16_t*)im;
-      switch( swap )
+      switch( SwapCode )
       {
          case 0:
          case 12:
@@ -314,28 +300,28 @@ void PixelConvert::SwapZone(void* im, int swap, int lgr, int nb)
          case 3412:
          case 2143:
          case 4321:
-            for(i=0; i < lgr/2; i++)
+            for( i = 0; i < DecompressedSize / 2; i++ )
             {
                im16[i]= (im16[i] >> 8) | (im16[i] << 8 );
             }
             break;
          default:
-            std::cout << "SWAP value (16 bits) not allowed :i" << swap <<
-            std::endl;
+            dbg.Verbose( 0, "PixelConvert::SwapZone: SwapCode value "
+                            "(16 bits) not allowed." );
       }
    }
-   else if( nb == 32 )
+   else if( BitsAllocated == 32 )
    {
       uint32_t s32;
       uint16_t fort, faible;
       uint32_t* im32 = (uint32_t*)im;
-      switch ( swap )
+      switch ( SwapCode )
       {
          case 0:
          case 1234:
             break;
          case 4321:
-            for(i = 0; i < lgr/4; i++)
+            for( i = 0; i < DecompressedSize / 4; i++ )
             {
                faible  = im32[i] & 0x0000ffff;  // 4321
                fort    = im32[i] >> 16;
@@ -346,7 +332,7 @@ void PixelConvert::SwapZone(void* im, int swap, int lgr, int nb)
             }
             break;
          case 2143:
-            for(i = 0; i < lgr/4; i++)
+            for( i = 0; i < DecompressedSize / 4; i++ )
             {
                faible  = im32[i] & 0x0000ffff;   // 2143
                fort    = im32[i] >> 16;
@@ -357,7 +343,7 @@ void PixelConvert::SwapZone(void* im, int swap, int lgr, int nb)
             }
             break;
          case 3412:
-            for(i = 0; i < lgr/4; i++)
+            for( i = 0; i < DecompressedSize / 4; i++ )
             {
                faible  = im32[i] & 0x0000ffff; // 3412
                fort    = im32[i] >> 16;
@@ -366,35 +352,28 @@ void PixelConvert::SwapZone(void* im, int swap, int lgr, int nb)
             }
             break;
          default:
-            std::cout << "SWAP value (32 bits) not allowed : " << swap <<
-            std::endl;
+            dbg.Verbose( 0, "PixelConvert::SwapZone: SwapCode value "
+                            "(32 bits) not allowed." );
       }
    }
 }
 
-
-
 /**
  * \brief Deal with endianity i.e. re-arange bytes inside the integer
  */
-void PixelConvert::ConvertReorderEndianity( uint8_t* pixelZone,
-                                        size_t imageDataSize,
-                                        int numberBitsStored,
-                                        int numberBitsAllocated,
-                                        int swapCode,
-                                        bool signedPixel)
+void PixelConvert::ReorderEndianity( uint8_t* pixelZone )
 {
-   if ( numberBitsAllocated != 8 )
+   if ( BitsAllocated != 8 )
    {
-      SwapZone( pixelZone, swapCode, imageDataSize, numberBitsAllocated );
+      SwapZone( pixelZone );
    }
                                                                                 
    // Special kludge in order to deal with xmedcon broken images:
-   if (  ( numberBitsAllocated == 16 )
-      && ( numberBitsStored < numberBitsAllocated )
-      && ( ! signedPixel ) )
+   if (  ( BitsAllocated == 16 )
+       && ( BitsStored < BitsAllocated )
+       && ( ! PixelSign ) )
    {
-      int l = (int)(imageDataSize / (numberBitsAllocated/8));
+      int l = (int)( DecompressedSize / ( BitsAllocated / 8 ) );
       uint16_t *deb = (uint16_t *)pixelZone;
       for(int i = 0; i<l; i++)
       {
@@ -414,17 +393,9 @@ void PixelConvert::ConvertReorderEndianity( uint8_t* pixelZone,
  * @param     destination Where decompressed fragments should end up
  * @return    Boolean
  */
-bool PixelConvert::ReadAndDecompressJPEGFile( uint8_t* destination,
-                                   int XSize,
-                                   int YSize,
-                                   int BitsAllocated,
-                                   int BitsStored,
-                                   int SamplesPerPixel,
-                                   int PixelSize,
-                                   bool isJPEG2000,
-                                   bool isJPEGLossless,
-                                   JPEGFragmentsInfo* JPEGInfo,
-                                   FILE* fp )
+bool PixelConvert::ReadAndDecompressJPEGFile(
+                          uint8_t* destination,
+                          FILE* fp )
 {
    // Loop on the fragment[s]
    for( JPEGFragmentsInfo::JPEGFragmentsList::iterator
@@ -434,14 +405,14 @@ bool PixelConvert::ReadAndDecompressJPEGFile( uint8_t* destination,
    {
       fseek( fp, (*it)->Offset, SEEK_SET );
                                                                                 
-      if ( isJPEG2000 )
+      if ( IsJPEG2000 )
       {
          if ( ! gdcm_read_JPEG2000_file( fp, destination ) )
          {
             return false;
          }
       }
-      else if ( isJPEGLossless )
+      else if ( IsJPEGLossless )
       {
          // JPEG LossLess : call to xmedcom Lossless JPEG
          JPEGLosslessDecodeImage( fp,
@@ -468,7 +439,7 @@ bool PixelConvert::ReadAndDecompressJPEGFile( uint8_t* destination,
       else
       {
          // other JPEG lossy not supported
-         dbg.Error(" File::ReadPixelData : unknown jpeg lossy "
+         dbg.Error(" File::ReadAndDecompressJPEGFile: unknown jpeg lossy "
                    " compression ");
          return false;
       }
@@ -490,46 +461,180 @@ bool PixelConvert::ReadAndDecompressJPEGFile( uint8_t* destination,
  * @param  destination Where decompressed fragments should end up
  * @return Boolean
  */
-bool PixelConvert::ConvertReArrangeBits(
-                          uint8_t* pixelZone,
-                          size_t imageDataSize,
-                          int numberBitsStored,
-                          int numberBitsAllocated,
-                          int highBitPosition )
+bool PixelConvert::ReArrangeBits( uint8_t* pixelZone )
      throw ( FormatError )
 {
-   if ( numberBitsStored != numberBitsAllocated )
+   if ( BitsStored != BitsAllocated )
    {
-      int l = (int)(imageDataSize / (numberBitsAllocated/8));
-      if ( numberBitsAllocated == 16 )
+      int l = (int)( DecompressedSize / ( BitsAllocated / 8 ) );
+      if ( BitsAllocated == 16 )
       {
          uint16_t mask = 0xffff;
-         mask = mask >> ( numberBitsAllocated - numberBitsStored );
+         mask = mask >> ( BitsAllocated - BitsStored );
          uint16_t* deb = (uint16_t*)pixelZone;
          for(int i = 0; i<l; i++)
          {
-            *deb = (*deb >> (numberBitsStored - highBitPosition - 1)) & mask;
+            *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & mask;
             deb++;
          }
       }
-      else if ( numberBitsAllocated == 32 )
+      else if ( BitsAllocated == 32 )
       {
          uint32_t mask = 0xffffffff;
-         mask = mask >> ( numberBitsAllocated - numberBitsStored );
+         mask = mask >> ( BitsAllocated - BitsStored );
          uint32_t* deb = (uint32_t*)pixelZone;
          for(int i = 0; i<l; i++)
          {
-            *deb = (*deb >> (numberBitsStored - highBitPosition - 1)) & mask;
+            *deb = (*deb >> (BitsStored - HighBitPosition - 1)) & mask;
             deb++;
          }
       }
       else
       {
-         dbg.Verbose(0, "PixelConvert::ConvertReArrangeBits: weird image");
-         throw FormatError( "File::ConvertReArrangeBits()",
+         dbg.Verbose(0, "PixelConvert::ReArrangeBits: weird image");
+         throw FormatError( "File::ReArrangeBits()",
                                 "weird image !?" );
       }
    }
-   return true; //???
 }
+
+/**
+ * \brief   Convert (Y plane, cB plane, cR plane) to RGB pixels
+ * \warning Works on all the frames at a time
+ */
+void PixelConvert::ConvertYcBcRPlanesToRGBPixels(
+                           uint8_t* destination,
+                           size_t imageDataSize )
+{
+   uint8_t* oldPixelZone = new uint8_t[ imageDataSize ];
+   memmove( oldPixelZone, destination, imageDataSize );
+                                                                                
+   // to see the tricks about YBR_FULL, YBR_FULL_422,
+   // YBR_PARTIAL_422, YBR_ICT, YBR_RCT have a look at :
+   // ftp://medical.nema.org/medical/dicom/final/sup61_ft.pdf
+   // and be *very* affraid
+   //
+   int l        = XSize * YSize;
+   int nbFrames = ZSize;
+                                                                                
+   uint8_t* a = oldPixelZone;
+   uint8_t* b = oldPixelZone + l;
+   uint8_t* c = oldPixelZone + l + l;
+   double R, G, B;
+                                                                                
+   /// \todo : Replace by the 'well known' integer computation
+   ///         counterpart. Refer to
+   ///            http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf
+   ///         for code optimisation.
+                                                                                
+   for ( int i = 0; i < nbFrames; i++ )
+   {
+      for ( int j = 0; j < l; j++ )
+      {
+         R = 1.164 *(*a-16) + 1.596 *(*c -128) + 0.5;
+         G = 1.164 *(*a-16) - 0.813 *(*c -128) - 0.392 *(*b -128) + 0.5;
+         B = 1.164 *(*a-16) + 2.017 *(*b -128) + 0.5;
+                                                                                
+         if (R < 0.0)   R = 0.0;
+         if (G < 0.0)   G = 0.0;
+         if (B < 0.0)   B = 0.0;
+         if (R > 255.0) R = 255.0;
+         if (G > 255.0) G = 255.0;
+         if (B > 255.0) B = 255.0;
+                                                                                
+         *(destination++) = (uint8_t)R;
+         *(destination++) = (uint8_t)G;
+         *(destination++) = (uint8_t)B;
+         a++;
+         b++;
+         c++;
+      }
+   }
+   delete[] oldPixelZone;
+}
+
+/**
+ * \brief   Convert (Red plane, Green plane, Blue plane) to RGB pixels
+ * \warning Works on all the frames at a time
+ */
+void PixelConvert::ConvertRGBPlanesToRGBPixels(
+                          uint8_t* destination,
+                          size_t imageDataSize )
+{
+   uint8_t* oldPixelZone = new uint8_t[ imageDataSize ];
+   memmove( oldPixelZone, destination, imageDataSize );
+                                                                                
+   int l = XSize * YSize * ZSize;
+                                                                                
+   uint8_t* a = oldPixelZone;
+   uint8_t* b = oldPixelZone + l;
+   uint8_t* c = oldPixelZone + l + l;
+                                                                                
+   for (int j = 0; j < l; j++)
+   {
+      *(destination++) = *(a++);
+      *(destination++) = *(b++);
+      *(destination++) = *(c++);
+   }
+   delete[] oldPixelZone;
+}
+
+bool PixelConvert::ReadAndDecompressPixelData( void* destination, FILE* fp )
+{
+   if ( !fp )
+   {
+      return false;
+   }
+                                                                                
+   if ( fseek(fp, PixelOffset, SEEK_SET) == -1 )
+   {
+      return false;
+   }
+                                                                                
+   if ( BitsAllocated == 12 )
+   {
+      Decompress12BitsTo16Bits( (uint8_t*)destination, fp);
+      return true;
+   }
+                                                                                
+   //////////// Decompressed File
+   if ( IsUncompressed )
+   {
+      size_t ItemRead = fread( destination, PixelDataLength, 1, fp);
+      if ( ItemRead != 1 )
+      {
+         return false;
+      }
+      else
+      {
+         return true;
+      }
+   }
+                                                                                
+   ///////////// Run Length Encoding
+   if ( IsRLELossless )
+   {
+      return ReadAndDecompressRLEFile( destination, fp );
+   }
+                                                                                
+   ///////////// SingleFrame/Multiframe JPEG Lossless/Lossy/2000
+   return ReadAndDecompressJPEGFile( (uint8_t*)destination, fp );
+}
+
+void PixelConvert::ComputeDecompressedImageDataSize()
+{
+   int bitsAllocated;
+   // Number of "Bits Allocated" is fixed to 16 when it's 12, since
+   // in this case we will expand the image to 16 bits (see
+   //    \ref Decompress12BitsTo16Bits() )
+   if (  BitsAllocated == 12 )
+   {
+      bitsAllocated = 16;
+   }
+                                                                                
+   DecompressedSize = XSize * YSize * ZSize
+                    * ( bitsAllocated / 8 )
+                    * SamplesPerPixel;
+}
+
 } // end namespace gdcm
index 0ac94ca4131c66422e41f0da1ff699e8fcfb6e85..e0e2b818e52958fc644ed90981c8466b9104afeb 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmPixelConvert.h,v $
   Language:  C++
-  Date:      $Date: 2004/10/12 04:35:47 $
-  Version:   $Revision: 1.6 $
+  Date:      $Date: 2004/10/12 09:59:45 $
+  Version:   $Revision: 1.7 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -25,9 +25,9 @@
 #include "gdcmJPEGFragmentsInfo.h"
 #include "gdcmException.h"
 
-namespace gdcm 
+namespace gdcm
 {
-
+                                                                                
 /*
  * \brief Utility container for gathering the various forms the pixel data
  *        migth take during the user demanded processes.
@@ -38,77 +38,102 @@ friend class File;
    uint8_t* RGB;
    size_t   RGBSize;          //aka ImageDataSize
    /// Pixel data after decompression and bit/byte rearrangement.
-   uint8_t* Uncompressed;
-   size_t   UncompressedSize;
+   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;
+   
+private:
+   bool ReadAndUncompressRLEFragment(
+                  uint8_t* decodedZone,
+                  long fragmentSize,
+                  long uncompressedSegmentSize,
+                  FILE* fp );
 public:
    PixelConvert();
    ~PixelConvert();
 
+   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; }
+
    uint8_t* GetRGB() { return RGB; }
    void     SetRGBSize( size_t size ) { RGBSize = size; }
    size_t   GetRGBSize() { return RGBSize; }
    void     AllocateRGB();
 
-   uint8_t* GetUncompressed() { return Uncompressed; }
-   void     SetUncompressedSize( size_t size ) { UncompressedSize = size; }
-   size_t   GetUncompressedSize() { return UncompressedSize; }
-   void     AllocateUncompressed();
+   uint8_t* GetDecompressed() { return Decompressed; }
+   void     SetDecompressedSize( size_t size ) { DecompressedSize = size; }
+   size_t   GetDecompressedSize() { return DecompressedSize; }
+   void     AllocateDecompressed();
 
-   void Squeeze();
 //////////////////////////////////////////////////////////
 // In progress
-   static bool UncompressRLE16BitsFromRLE8Bits(
-                  int XSize,
-                  int YSize,
+private:
+   bool UncompressRLE16BitsFromRLE8Bits(
                   int NumberOfFrames,
                   uint8_t* fixMemUncompressed );
-   static bool ReadAndUncompressRLEFragment(
-                  uint8_t* decodedZone,
-                  long fragmentSize,
-                  long uncompressedSegmentSize,
-                  FILE* fp );
-   static bool ReadAndDecompressRLEFile(
-                  void* image_buffer,
-                  int XSize,
-                  int YSize,
-                  int ZSize,
-                  int BitsAllocated,
-                  RLEFramesInfo* RLEInfo,
-                  FILE* fp );
-   static void ConvertDecompress12BitsTo16Bits(
+   void ComputeDecompressedImageDataSize();
+   void Decompress12BitsTo16Bits(
                   uint8_t* pixelZone,
-                  int sizeX,
-                  int sizeY,
                   FILE* filePtr) throw ( FormatError );
-   static void SwapZone(void* im, int swap, int lgr, int nb);
-   static void ConvertReorderEndianity(
-                  uint8_t* pixelZone,
-                  size_t imageDataSize,
-                  int numberBitsStored,
-                  int numberBitsAllocated,
-                  int swapCode,
-                  bool signedPixel );
-   static bool ReadAndDecompressJPEGFile(
+   bool ReadAndDecompressRLEFile( void* image_buffer, FILE* fp );
+   bool ReadAndDecompressJPEGFile( uint8_t* destination, FILE* fp );
+   void SwapZone( uint8_t* im );
+public:
+   void ReorderEndianity( uint8_t* pixelZone );
+   bool ReArrangeBits( uint8_t* pixelZone ) throw ( FormatError );
+         void ConvertRGBPlanesToRGBPixels(
                   uint8_t* destination,
-                  int XSize,
-                  int YSize,
-                  int BitsAllocated,
-                  int BitsStored,
-                  int SamplesPerPixel,
-                  int PixelSize,
-                  bool isJPEG2000,
-                  bool isJPEGLossless,
-                  JPEGFragmentsInfo* JPEGInfo,
-                  FILE* fp );
-   static bool PixelConvert::ConvertReArrangeBits(
-                  uint8_t* pixelZone,
-                  size_t imageDataSize,
-                  int numberBitsStored,
-                  int numberBitsAllocated,
-                  int highBitPosition ) throw ( FormatError );
-
-
+                  size_t imageDataSize );
+          void ConvertYcBcRPlanesToRGBPixels(
+                  uint8_t* destination,
+                  size_t imageDataSize );
+          bool ReadAndDecompressPixelData( void* destination, FILE* fp );
+   void Squeeze();
 };
 } // end namespace gdcm
+
 //-----------------------------------------------------------------------------
 #endif