]> Creatis software - gdcm.git/blobdiff - src/gdcmPixelReadConvert.cxx
To prepare use of progression bar in all types of Document
[gdcm.git] / src / gdcmPixelReadConvert.cxx
index efe00f20a80361887e3694c4b0f091eddff623bd..c8c76c22d2f12747c805bd1fa1043d47c88423d7 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmPixelReadConvert.cxx,v $
   Language:  C++
-  Date:      $Date: 2005/10/26 13:16:45 $
-  Version:   $Revision: 1.91 $
+  Date:      $Date: 2005/11/29 17:21:35 $
+  Version:   $Revision: 1.106 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -31,7 +31,7 @@
 namespace gdcm
 {
 
-//bool ReadMPEGFile (std::ifstream *fp, void *image_buffer, size_t lenght);
+//bool ReadMPEGFile (std::ifstream *fp, char *inputdata, size_t lenght); 
 bool gdcm_read_JPEG2000_file (void* raw, 
                               char *inputdata, size_t inputlength);
 //-----------------------------------------------------------------------------
@@ -82,7 +82,8 @@ bool PixelReadConvert::IsRawRGB()
  * \brief Gets various usefull informations from the file header
  * @param file gdcm::File pointer
  */
-void PixelReadConvert::GrabInformationsFromFile( File *file )
+void PixelReadConvert::GrabInformationsFromFile( File *file, 
+                                                 FileHelper *fileHelper )
 {
    // Number of Bits Allocated for storing a Pixel is defaulted to 16
    // when absent from the file.
@@ -114,47 +115,53 @@ void PixelReadConvert::GrabInformationsFromFile( File *file )
    //PixelSize       = file->GetPixelSize();  Useless
    PixelSign       = file->IsSignedPixelData();
    SwapCode        = file->GetSwapCode();
-   
-   if (! file->IsDicomV3() )  // Should be ACR-NEMA file
-   {
-      IsRaw = true;
-      // Don't loose time checking unexistant Transfer Syntax !
-      IsPrivateGETransferSyntax = IsMPEG
+   IsPrivateGETransferSyntax = IsMPEG
              = IsJPEG2000 = IsJPEGLS = IsJPEGLossy  
              = IsJPEGLossless = IsRLELossless 
              = false;
+     
+   if (! file->IsDicomV3() )  // Should be ACR-NEMA file
+   {
+      IsRaw = true;
    }
    else
    {
       std::string ts = file->GetTransferSyntax();
 
-   
-//   if ( ts == GDCM_UNKNOWN )
-//   {
-//     gdcmErrorMacro( "Could someone tell me how in the world could this happen !" );
-// -->
-//--> on ALL acr-nema images ! JPRx
-//-->
-//     abort(); // DO NOT REMOVE.  WE SHOULD NEVER READ SUCH IMAGE EVER (only gdcm can write such broekn dicom file)
-//   }
-
-      IsRaw =
-           ( ! file->IsDicomV3() )  // Should be ACR-NEMA file
-        || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian
-        || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE
-        || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRLittleEndian
-        || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian
-        || Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::DeflatedExplicitVRLittleEndian;
-     
+      IsRaw = false;
+      while (true) // short to write than if elseif elseif elseif ...
+      {
+         // mind the order : check the most usual first.
+         if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRLittleEndian)         break;
+         if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRLittleEndian )        break;
+         if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ExplicitVRBigEndian)            break;
+         if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE)   break;
+         if( IsRaw = Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::DeflatedExplicitVRLittleEndian) break;
+         break;
+      }
+      // cache whether this is a strange GE transfer syntax (which uses
+      // a little endian transfer syntax for the header and a big endian
+      // transfer syntax for the pixel data). 
       IsPrivateGETransferSyntax = 
                 ( Global::GetTS()->GetSpecialTransferSyntax(ts) == TS::ImplicitVRBigEndianPrivateGE );
 
-      IsMPEG          = Global::GetTS()->IsMPEG(ts);
-      IsJPEG2000      = Global::GetTS()->IsJPEG2000(ts);
-      IsJPEGLS        = Global::GetTS()->IsJPEGLS(ts);
-      IsJPEGLossy     = Global::GetTS()->IsJPEGLossy(ts);
-      IsJPEGLossless  = Global::GetTS()->IsJPEGLossless(ts);
-      IsRLELossless   = Global::GetTS()->IsRLELossless(ts);
+      IsMPEG =  IsJPEG2000 =  IsJPEGLS =  IsJPEGLossy =  IsJPEGLossless = IsRLELossless = false;  
+      if (!IsRaw)
+      {     
+         while(true)
+         {
+            // mind the order : check the most usual first.
+            if( IsJPEGLossy     = Global::GetTS()->IsJPEGLossy(ts) )    break;
+            if( IsJPEGLossless  = Global::GetTS()->IsJPEGLossless(ts) ) break;
+            if( IsRLELossless   = Global::GetTS()->IsRLELossless(ts) )  break;
+            if( IsJPEG2000      = Global::GetTS()->IsJPEG2000(ts) )     break;
+            if( IsMPEG          = Global::GetTS()->IsMPEG(ts) )         break;
+            if( IsJPEGLS        = Global::GetTS()->IsJPEGLS(ts) )       break;
+            gdcmWarningMacro("Unexpected Transfer Syntax :[" << ts << "]");
+            break;
+         } 
+      }
    }
 
    PixelOffset     = file->GetPixelOffset();
@@ -179,7 +186,7 @@ void PixelReadConvert::GrabInformationsFromFile( File *file )
       LutGreenDescriptor = file->GetEntryString( 0x0028, 0x1102 );
       LutBlueDescriptor  = file->GetEntryString( 0x0028, 0x1103 );
    
-      // The following comment is probabely meaningless, since LUT are *always*
+      // FIXME : The following comment is probabely meaningless, since LUT are *always*
       // loaded at parsing time, whatever their length is.
          
       // Depending on the value of Document::MAX_SIZE_LOAD_ELEMENT_VALUE
@@ -221,7 +228,7 @@ void PixelReadConvert::GrabInformationsFromFile( File *file )
       }
    }
    FileInternal = file;   
-
+   FH = fileHelper;
    ComputeRawAndRGBSizes();
 }
 
@@ -251,8 +258,18 @@ bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp )
    AllocateRaw();
 
    //////////////////////////////////////////////////
+   
+   CallStartMethod(); // for progress bar
+   unsigned int count = 0;
+   unsigned int frameSize;
+   unsigned int bitsAllocated = BitsAllocated;
+   if(bitsAllocated == 12)
+      bitsAllocated = 16;
+   frameSize = XSize*YSize*SamplesPerPixel*bitsAllocated/8;
+   
    //// Second stage: read from disk and decompress.
-   if ( BitsAllocated == 12 )
+   
+   if ( BitsAllocated == 12 ) // We suppose 'BitsAllocated' = 12 only exist for uncompressed files
    {
       ReadAndDecompress12BitsTo16Bits( fp);
    }
@@ -265,16 +282,40 @@ bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp )
       if ( PixelDataLength != RawSize )
       {
          gdcmWarningMacro( "Mismatch between PixelReadConvert : "
-                          << PixelDataLength << " and RawSize : " << RawSize );
+                              << PixelDataLength << " and RawSize : " << RawSize );
       }
+      
+      //todo : is it the right patch?
+      char *raw = (char*)Raw;
+      uint32_t remainingLength;
+      unsigned int i; 
+      unsigned int lengthToRead;
+       
       if ( PixelDataLength > RawSize )
-      {
-         fp->read( (char*)Raw, RawSize);
-      }
+        lengthToRead =  RawSize;
       else
+        lengthToRead = PixelDataLength;
+      // perform a frame by frame reading
+      remainingLength = lengthToRead;
+      unsigned int nbFrames = lengthToRead / frameSize;
+      for (i=0;i<nbFrames; i++)
       {
-         fp->read( (char*)Raw, PixelDataLength);
+         fp->read( raw, frameSize);
+         raw +=  frameSize;
+         remainingLength -=  frameSize;
       }
+      if (remainingLength !=0 )
+        fp->read( raw, remainingLength);
+                 
+      //if ( PixelDataLength > RawSize )
+      //{
+      //   fp->read( (char*)Raw, RawSize); // Read all the frames with a single fread    
+      //}
+      //else
+      //{
+      //   fp->read( (char*)Raw, PixelDataLength); // Read all the frames with a single fread
+      //}
 
       if ( fp->fail() || fp->eof())
       {
@@ -296,7 +337,7 @@ bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp )
       //gdcmWarningMacro( "Sorry, MPEG not yet taken into account" );
       //return false;
       // fp has already been seek to start of mpeg
-      //ReadMPEGFile(fp, Raw, PixelDataLength); 
+      //ReadMPEGFile(fp, (char*)Raw, PixelDataLength); 
       return true;
    }
    else
@@ -304,7 +345,8 @@ bool PixelReadConvert::ReadAndDecompressPixelData( std::ifstream *fp )
       // Default case concerns JPEG family
       if ( ! ReadAndDecompressJPEGFile( fp ) )
       {
-         gdcmWarningMacro( "JPEG decompressor failed." );
+         gdcmWarningMacro( "JPEG decompressor ( ReadAndDecompressJPEGFile()"
+                              << " method ) failed." );
          return false;
       }
    }
@@ -361,7 +403,7 @@ bool PixelReadConvert::BuildRGBImage()
       return false;
    }
 
-   gdcmWarningMacro( "--> BuildRGBImage" );
+   gdcmDebugMacro( "--> BuildRGBImage" );
                                                                                 
    // Build RGB Pixels
    AllocateRGB();
@@ -488,6 +530,7 @@ bool PixelReadConvert::ReadAndDecompressJPEGFile( std::ifstream *fp )
          return true;
       }
       // wow what happen, must be an error
+      gdcmWarningMacro( "gdcm_read_JPEG2000_file() failed "); 
       return false;
    }
    else if ( IsJPEGLS )
@@ -631,12 +674,12 @@ void PixelReadConvert::BuildLUTRGBA()
       gdcmWarningMacro( "Wrong Blue LUT descriptor" );
    }
  
-   gdcmWarningMacro(" lengthR " << lengthR << " debR " 
-                 << debR << " nbitsR " << nbitsR);
-   gdcmWarningMacro(" lengthG " << lengthG << " debG " 
-                 << debG << " nbitsG " << nbitsG);
-   gdcmWarningMacro(" lengthB " << lengthB << " debB " 
-                 << debB << " nbitsB " << nbitsB);
+   gdcmDebugMacro(" lengthR " << lengthR << " debR " 
+                << debR << " nbitsR " << nbitsR);
+   gdcmDebugMacro(" lengthG " << lengthG << " debG " 
+                << debG << " nbitsG " << nbitsG);
+   gdcmDebugMacro(" lengthB " << lengthB << " debB " 
+                << debB << " nbitsB " << nbitsB);
 
    if ( !lengthR ) // if = 2^16, this shall be 0 see : CP-143
       lengthR=65536;
@@ -792,7 +835,6 @@ void PixelReadConvert::BuildLUTRGBA()
 void PixelReadConvert::ConvertSwapZone()
 {
    unsigned int i;
-   uint16_t localSwapCode = SwapCode;
    
    // If this file is 'ImplicitVR BigEndian PrivateGE Transfer Syntax', 
    // then the header is in little endian format and the pixel data is in 
@@ -820,28 +862,27 @@ void PixelReadConvert::ConvertSwapZone()
    // Therefore, in either case, if the file is in
    // 'ImplicitVR BigEndian PrivateGE Transfer Syntax', then GDCM needs to switch
    // the byte swapping code when entering the pixel data.
-
-/* //Let me check something.
-   //I wait for the Dashboard !   
+   
+   int tempSwapCode = SwapCode;
    if ( IsPrivateGETransferSyntax )
    {
+      gdcmWarningMacro(" IsPrivateGETransferSyntax found; turn the SwapCode"); 
       // PrivateGETransferSyntax only exists for 'true' Dicom images
       // we assume there is no 'exotic' 32 bits endianess!
-      switch (localSwapCode)
+      if (SwapCode == 1234) 
       {
-         case 1234:
-            localSwapCode = 4321;
-            break;
-         case 4321:
-            localSwapCode = 1234;
-            break;
-      }  
+         tempSwapCode = 4321;
+      }
+      else if (SwapCode == 4321)
+      {
+         tempSwapCode = 1234;
+      }
    }
-*/   
+    
    if ( BitsAllocated == 16 )
    {
       uint16_t *im16 = (uint16_t*)Raw;
-      switch( localSwapCode )
+      switch( tempSwapCode )
       {
          case 1234:
             break;
@@ -854,7 +895,8 @@ void PixelReadConvert::ConvertSwapZone()
             }
             break;
          default:
-            gdcmWarningMacro("SwapCode value (16 bits) not allowed.");
+            gdcmWarningMacro("SwapCode value (16 bits) not allowed." 
+                        << tempSwapCode);
       }
    }
    else if ( BitsAllocated == 32 )
@@ -863,7 +905,7 @@ void PixelReadConvert::ConvertSwapZone()
       uint16_t high;
       uint16_t low;
       uint32_t *im32 = (uint32_t*)Raw;
-      switch ( localSwapCode )
+      switch ( tempSwapCode )
       {
          case 1234:
             break;
@@ -899,7 +941,7 @@ void PixelReadConvert::ConvertSwapZone()
             }
             break;
          default:
-            gdcmWarningMacro("SwapCode value (32 bits) not allowed." );
+            gdcmWarningMacro("SwapCode value (32 bits) not allowed." << tempSwapCode );
       }
    }
 }
@@ -1238,13 +1280,13 @@ void PixelReadConvert::ConvertHandleColor()
    // - [Planar 1] AND [Photo C] handled with ConvertYcBcRPlanesToRGBPixels()
    // - [Planar 2] OR  [Photo D] requires LUT intervention.
 
-   gdcmWarningMacro("--> ConvertHandleColor"
-                    << "Planar Configuration " << PlanarConfiguration );
+   gdcmDebugMacro("--> ConvertHandleColor "
+                     << "Planar Configuration " << PlanarConfiguration );
 
    if ( ! IsRawRGB() )
    {
       // [Planar 2] OR  [Photo D]: LUT intervention done outside
-      gdcmWarningMacro("--> RawRGB : LUT intervention done outside");
+      gdcmDebugMacro("--> RawRGB : LUT intervention done outside");
       return;
    }
                                                                                 
@@ -1253,13 +1295,13 @@ void PixelReadConvert::ConvertHandleColor()
       if ( IsYBRFull )
       {
          // [Planar 1] AND [Photo C] (remember YBR_FULL_422 acts as RGB)
-         gdcmWarningMacro("--> YBRFull");
+         gdcmDebugMacro("--> YBRFull");
          ConvertYcBcRPlanesToRGBPixels();
       }
       else
       {
          // [Planar 1] AND [Photo C]
-         gdcmWarningMacro("--> YBRFull");
+         gdcmDebugMacro("--> YBRFull");
          ConvertRGBPlanesToRGBPixels();
       }
       return;
@@ -1270,7 +1312,7 @@ void PixelReadConvert::ConvertHandleColor()
 
    if (IsRLELossless)
    { 
-     gdcmWarningMacro("--> RLE Lossless");
+     gdcmDebugMacro("--> RLE Lossless");
      ConvertRGBPlanesToRGBPixels();
    }
 
@@ -1362,6 +1404,34 @@ void PixelReadConvert::Print( std::ostream &os, std::string const &indent )
    }
 }
 
+/**
+ * \brief   CallStartMethod
+ */
+void PixelReadConvert::CallStartMethod()
+{
+   Progress = 0.0f;
+   Abort    = false;
+   CommandManager::ExecuteCommand(FH,CMD_STARTPROGRESS);
+}
+
+/**
+ * \brief   CallProgressMethod
+ */
+void PixelReadConvert::CallProgressMethod()
+{
+   CommandManager::ExecuteCommand(FH,CMD_PROGRESS);
+}
+
+/**
+ * \brief   CallEndMethod
+ */
+void PixelReadConvert::CallEndMethod()
+{
+   Progress = 1.0f;
+   CommandManager::ExecuteCommand(FH,CMD_ENDPROGRESS);
+}
+
+
 //-----------------------------------------------------------------------------
 } // end namespace gdcm