]> Creatis software - gdcm.git/commitdiff
First step to sync with v 1.2.2
authorjpr <jpr>
Fri, 13 Jul 2007 08:17:19 +0000 (08:17 +0000)
committerjpr <jpr>
Fri, 13 Jul 2007 08:17:19 +0000 (08:17 +0000)
Example/CMakeLists.txt
Example/RawToDicom.cxx
Example/ReWriteExtended.cxx
Example/WriteDicomAsJPEG2000.cxx
src/gdcmDirList.h
src/gdcmFileHelper.cxx
src/gdcmJpeg.cxx
src/gdcmJpeg2000.cxx
src/gdcmPixelWriteConvert.cxx
src/gdcmPixelWriteConvert.h
vtk/vtkGdcmReader.h

index 59317ac0e544e353a1c1449a732b9f7e3efc16a4..c7e2b0b70b5ecaf556a315aa1d948ed29a0ca2bb 100644 (file)
@@ -7,7 +7,8 @@ SET(EXAMPLE_SOURCES
   #names starting with 'ex' are examples  
   #Txt2Mat  
   #exDicomRTStructSetFile  
-  #exExtractCSA  
+  #exExtractCSA
+  Dense2007ToDicom  
   exReadPapyrus  
   exReadWriteFile  
   exColorToRGB  
@@ -38,7 +39,7 @@ SET(EXAMPLE_SOURCES
   PatchHeader  
   ToInTag  
   ReWrite  
-  ReWriteExtended  
+  #ReWriteExtended  
   RawToDicom  
   TestValidate  
   ToMRIregister
@@ -54,7 +55,8 @@ SET(EXAMPLE_SOURCES
   Volume2Dicom  
   WriteDicomSimple  
   WriteRead  
-  #WriteDicomAsJPEG  
+  WriteDicomAsJPEG2000
+  WriteDicomAsJPEG 
   exCTPET  
   #Slice
 )
index e39dc41673751ada4431adaf88445a51cbc8e306..b8227a23227b18fcf8522980a4a1c3133229335a 100755 (executable)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: RawToDicom.cxx,v $
   Language:  C++
-  Date:      $Date: 2007/07/05 13:17:26 $
-  Version:   $Revision: 1.11 $
+  Date:      $Date: 2007/07/13 08:17:20 $
+  Version:   $Revision: 1.12 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -192,7 +192,7 @@ int main(int argc, char *argv[])
       return 1;
    }
  
-    std::string strStudyUID;
+   std::string strStudyUID;
    std::string strSerieUID;
 
    if (userDefinedStudy)
@@ -222,8 +222,6 @@ int main(int argc, char *argv[])
  
  // Get the (empty) image header.  
    GDCM_NAME_SPACE::File *fileToBuild = fileH->GetFile();
-     
-   
 
    // 'Study Instance UID'
    // The user is allowed to create his own Study, 
index 6faf1fbcdbe408d14b19c0c4fb956af26a157354..a4aed09c3a252630688ba70e6113a332e214bdfd 100755 (executable)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: ReWriteExtended.cxx,v $
   Language:  C++
-  Date:      $Date: 2007/05/23 14:18:04 $
-  Version:   $Revision: 1.5 $
+  Date:      $Date: 2007/07/13 08:17:20 $
+  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
@@ -42,6 +42,7 @@ int main(int argc, char *argv[])
    "        noshadow : user doesn't want to load Private groups (odd number)",
    "        noseq    : user doesn't want to load Sequences                  ",
    "        rgb      : user wants to transform LUT (if any) to RGB pixels   ",
+   "        warning  : developper wants to run the program in 'warning mode'",
    "        debug    : developper wants to run the program in 'debug mode'  ",
    FINISH_USAGE
 
@@ -90,11 +91,10 @@ int main(int argc, char *argv[])
    if (am->ArgMgrDefined("debug"))
       GDCM_NAME_SPACE::Debug::DebugOn();
  
+   if (am->ArgMgrDefined("warning"))
+      GDCM_NAME_SPACE::Debug::WarningOn(); 
  
- // ======================================================================= 
-   bool fail = false;
+    bool fail = false;
       
    int *boundRoiVal;
    bool roi = false; 
@@ -113,11 +113,9 @@ int main(int argc, char *argv[])
         roi = true;   
    }
   
-   int beg = am->ArgMgrGetInt("firstFrame",0);
-   int end = am->ArgMgrGetInt("lastFrame",0);
- // =======================================================================
+   int beg = am->ArgMgrGetInt("firstFrame",-1);
+   int end = am->ArgMgrGetInt("lastFrame",-1);
+  
    // if unused Params we give up
    if ( am->ArgMgrPrintUnusedLabels() )
    { 
@@ -146,8 +144,7 @@ int main(int argc, char *argv[])
        f->Delete();
        return 0;
    }
-
-
+   
    //std::cout <<std::endl <<" dataSize " << dataSize << std::endl;
    int nX,nY,nZ,sPP,planarConfig;
    std::string pixelType, transferSyntaxName;
@@ -173,19 +170,14 @@ int main(int argc, char *argv[])
    transferSyntaxName = f->GetTransferSyntaxName();
    std::cout << " TransferSyntaxName= [" << transferSyntaxName << "]" 
              << std::endl;
-
-
-   
+  
    GDCM_NAME_SPACE::FileHelper *fh = GDCM_NAME_SPACE::FileHelper::New(f);
    void *imageData; 
    int dataSize;
  
-  // ======================================================================= 
     int subImDimX = nX;
     int subImDimY = nY;
     
-
     if (roi)
     {  
     std::cout << " " << boundRoiVal[0] << " " <<  boundRoiVal[1] << " " << boundRoiVal[2] << " " <<
@@ -255,14 +247,12 @@ int main(int argc, char *argv[])
       std::cout << "Was unable to read pixels " << std::endl;
    }
 
-
    // We trust user. (just an example; *never* trust an user !)  
    fh->SetContentType((GDCM_NAME_SPACE::ImageContentType)filecontent);
    
    /// \todo Here, give the detail of operations a 'decent' user should perform,
    ///       according to what *he* wants to do.
 
-
    // an user shouldn't add images to a 'native' serie.
    // He is allowed to create his own Serie, within a 'native' Study :
    // if he wants to do so, he has to call GDCM_NAME_SPACE::Util::GetUniqueUID 
@@ -355,4 +345,3 @@ int main(int argc, char *argv[])
    fh->Delete();
    return 0;
 }
-
index d864ea17202ce43ced18be930c858459919cd298..e60a9b4c92e1e85bbef8797bdac57f88fed6edcf 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: WriteDicomAsJPEG2000.cxx,v $
   Language:  C++
-  Date:      $Date: 2007/06/21 15:01:00 $
-  Version:   $Revision: 1.4 $
+  Date:      $Date: 2007/07/13 08:17:20 $
+  Version:   $Revision: 1.5 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -39,15 +39,11 @@ int main(int argc, char *argv[])
    std::cerr << "Using quality: " << quality << std::endl;
 
 // Step 1 : Create the header of the image
-   //GDCM_NAME_SPACE::File *f = new GDCM_NAME_SPACE::File();
-   // gdcm1.3 syntax. Sorry
    GDCM_NAME_SPACE::File *f = GDCM_NAME_SPACE::File::New();
    f->SetLoadMode ( GDCM_NAME_SPACE::LD_ALL ); // Load everything
    f->SetFileName( filename );
    f->Load();
 
-   //GDCM_NAME_SPACE::FileHelper *tested = new GDCM_NAME_SPACE::FileHelper( f );
-   // gdcm1.3 syntax. Sorry   
    GDCM_NAME_SPACE::FileHelper *tested = GDCM_NAME_SPACE::FileHelper::New( f );
    std::string PixelType = tested->GetFile()->GetPixelType();
    int xsize = f->GetXSize();
@@ -61,30 +57,21 @@ int main(int argc, char *argv[])
 
 // Step 1 : Create the header of the image
 
-//   GDCM_NAME_SPACE::File *fileToBuild = new GDCM_NAME_SPACE::File();
-   // gdcm1.3 syntax. Sorry !
    GDCM_NAME_SPACE::File *fileToBuild = GDCM_NAME_SPACE::File::New();
-   
    std::ostringstream str;
 
    // Set the image size
    str.str("");
    str << xsize;
-   //fileToBuild->InsertValEntry(str.str(),0x0028,0x0011); // Columns
-   // gdcm1.3 syntax. Sorry !
    fileToBuild->InsertEntryString(str.str(),0x0028,0x0011, "US"); // Columns
    str.str("");
    str << ysize;
-   //fileToBuild->InsertValEntry(str.str(),0x0028,0x0010); // Rows
-   // gdcm1.3 syntax. Sorry !
    fileToBuild->InsertEntryString(str.str(),0x0028,0x0010, "US"); // Rows
 
    if(zsize>1)
    {
       str.str("");
       str << zsize;
-      //fileToBuild->InsertValEntry(str.str(),0x0028,0x0008); // Number of Frames
-   // gdcm1.3 syntax. Sorry !
       fileToBuild->InsertEntryString(str.str(),0x0028,0x0008, "IS"); // Number of Frames
    }
    int bitsallocated = f->GetBitsAllocated();
@@ -96,39 +83,27 @@ int main(int argc, char *argv[])
    // Set the pixel type
    str.str("");
    str << bitsallocated;
-   //fileToBuild->InsertValEntry(str.str(),0x0028,0x0100); // Bits Allocated
-   // gdcm1.3 syntax. Sorry !
    fileToBuild->InsertEntryString(str.str(),0x0028,0x0100,"US"); // Bits Allocated
-   
+
    str.str("");
-   str << bitsstored;  
-   //fileToBuild->InsertValEntry(str.str(),0x0028,0x0101); // Bits Stored   
-   // gdcm1.3 syntax. Sorry !
+   str << bitsstored;
    fileToBuild->InsertEntryString(str.str(),0x0028,0x0101, "US"); // Bits Stored
+
    str.str("");
    str << highbit;
-   //fileToBuild->InsertValEntry(str.str(),0x0028,0x0102); // High Bit
-   // gdcm1.3 syntax. Sorry !
    fileToBuild->InsertEntryString(str.str(),0x0028,0x0102, "US"); // High Bit
 
    // Set the pixel representation
    str.str("");
    str << sign;
-   //fileToBuild->InsertValEntry(str.str(),0x0028,0x0103); // Pixel Representation
-   // gdcm1.3 syntax. Sorry !
    fileToBuild->InsertEntryString(str.str(),0x0028,0x0103, "US"); // Pixel Representation
 
-
    // Set the samples per pixel
    str.str("");
    str << samplesPerPixel; //img.components;
-   //fileToBuild->InsertValEntry(str.str(),0x0028,0x0002); // Samples per Pixel
-   // gdcm1.3 syntax. Sorry !
    fileToBuild->InsertEntryString(str.str(),0x0028,0x0002, "US"); // Samples per Pixel
 
 // Step 2 : Create the output image
-   //GDCM_NAME_SPACE::FileHelper *fileH = new GDCM_NAME_SPACE::FileHelper(fileToBuild);
-   // gdcm1.3 syntax. Sorry !
    GDCM_NAME_SPACE::FileHelper *fileH = GDCM_NAME_SPACE::FileHelper::New(fileToBuild);
    fileH->SetWriteTypeToJPEG2000(  );
    fileH->SetImageData(testedImageData, testedDataSize);
@@ -137,15 +112,11 @@ int main(int argc, char *argv[])
      std::cerr << "write fails" << std::endl;
      }
 
-   //delete f;
-   // gdcm1.3 syntax. Sorry !   
    f->Delete();
-   //delete tested;
    tested->Delete();
-   //delete fileToBuild;
    fileToBuild->Delete();
-   //delete fileH;
    fileH->Delete();
 
    return 0;
 }
+
index cda6dd317c78e1377a6549b5ed38fb756bf64ec8..658079ea3cedfae480b93ce7e3907ed1c8b21e62 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmDirList.h,v $
   Language:  C++
-  Date:      $Date: 2007/06/08 12:49:37 $
-  Version:   $Revision: 1.34 $
+  Date:      $Date: 2007/07/13 08:17:21 $
+  Version:   $Revision: 1.35 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -35,6 +35,8 @@ typedef std::vector<std::string> DirListType;
 
 // NOTE: Due to a M$VC6 'feature' we cannot export a std::list in a dll, 
 // so GDCM_EXPORT keyword was removed for this class only
+//
+// We have to supply accessors GetSize(), GetFirst(), GetNext() 
 
 /**
  * \brief   List containing the file headers of all the 'gdcm readable' files
index c45142e16cecb68c206e304bb33c1b9327c31182..32f79cb6e55e59fba9026f2684aac1d8027bea88 100644 (file)
@@ -4,8 +4,8 @@
   Module:    $RCSfile: gdcmFileHelper.cxx,v $
   Language:  C++
 
-  Date:      $Date: 2007/07/05 10:53:48 $
-  Version:   $Revision: 1.116 $
+  Date:      $Date: 2007/07/13 08:17:21 $
+  Version:   $Revision: 1.117 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -74,7 +74,10 @@ To re-write the image, user re-uses the gdcm::FileHelper
 fh->SetImageData( userPixels, userPixelsLength);
 fh->SetTypeToRaw(); // Even if it was possible to convert Palette to RGB
                     // (WriteMode is set)
+
+// If user wants to write the file as MONOCHROME1 (0=white)
+fh->SetPhotometricInterpretationToMonochrome1();
+
 fh->SetWriteTypeToDcmExpl();  // he wants Explicit Value Representation
                               // Little Endian is the default
                               // no other value is allowed
@@ -88,7 +91,6 @@ fh->WriteDcmExplVR(newFileName);
 
 // ----------------------------- WARNING -------------------------
 
-
 These lines will be moved to the document-to-be 'Developer's Guide'
 
 WriteMode : WMODE_RAW / WMODE_RGB
@@ -511,7 +513,18 @@ void FileHelper::SetImageData(uint8_t *inData, size_t expectedSize)
  */
 void FileHelper::SetUserData(uint8_t *inData, size_t expectedSize)
 {
-   PixelWriteConverter->SetUserData(inData, expectedSize);
+   if( WriteType == JPEG2000 )
+   {
+      PixelWriteConverter->SetCompressJPEG2000UserData(inData, expectedSize, FileInternal);
+   }
+   else if( WriteType == JPEG )
+   {
+      PixelWriteConverter->SetCompressJPEGUserData(inData, expectedSize, FileInternal);
+   }
+   else
+   {
+      PixelWriteConverter->SetUserData(inData, expectedSize);
+   }
 }
 
 /**
@@ -694,7 +707,6 @@ bool FileHelper::WriteAcr (std::string const &fileName)
  */
 bool FileHelper::Write(std::string const &fileName)
 {
-
    CheckMandatoryElements(); //called once, here !
    
    bool flag = false;
@@ -716,6 +728,7 @@ bool FileHelper::Write(std::string const &fileName)
    // Let's just *dream* about it; *never* trust a user !
    // We turn to Implicit VR if at least the VR of one element is unknown.
    
+   /// \TODO : better we put vr=UN for undocumented Shadow Groups !
  
          e = FileInternal->GetFirstEntry();
          while (e != 0)
@@ -758,7 +771,7 @@ bool FileHelper::Write(std::string const &fileName)
          SetWriteFileTypeToJPEG();
          break;
 
-       case JPEG2000:
+      case JPEG2000:
          SetWriteFileTypeToJPEG2000();
          break;
    }
@@ -793,16 +806,17 @@ bool FileHelper::Write(std::string const &fileName)
    }
 
    bool check = CheckWriteIntegrity(); // verifies length
-   if (WriteType == JPEG || WriteType == JPEG2000) check = true;
+   if (WriteType == JPEG || WriteType == JPEG2000) 
+      check = true;
+
    if (check)
    {
       check = FileInternal->Write(fileName,WriteType);
    }
 
-   RestoreWrite(); 
+   RestoreWrite();
   // RestoreWriteFileType();
   // RestoreWriteMandatory();
-   
 
    // --------------------------------------------------------------
    // Special Patch to allow gdcm to re-write ACR-LibIDO formated images
@@ -818,7 +832,7 @@ bool FileHelper::Write(std::string const &fileName)
 //-----------------------------------------------------------------------------
 // Protected
 /**
- * \brief  * \brief Verifies the size of the user given PixelData
+ * \brief Verifies the size of the user given PixelData
  * @return true if check is successfull
  */
 bool FileHelper::CheckWriteIntegrity()
@@ -866,7 +880,6 @@ bool FileHelper::CheckWriteIntegrity()
             break;
       }
    }
-
    return true;
 }
 
@@ -922,7 +935,7 @@ void FileHelper::SetWriteToRaw()
      
       if (!FileInternal->HasLUT() && GetPhotometricInterpretation() == 1)
       {
-         ConvertFixGreyLevels( pixel->GetBinArea(), pixel->GetLength() );  
+          ConvertFixGreyLevels( pixel->GetBinArea(), pixel->GetLength() );
       }      
 
       Archive->Push(photInt);
@@ -1032,7 +1045,6 @@ void FileHelper::SetWriteToRGB()
  */ 
 void FileHelper::RestoreWrite()
 {
-
    Archive->Restore(0x0028,0x0002);
    Archive->Restore(0x0028,0x0004);
    
@@ -1090,14 +1102,14 @@ void FileHelper::SetWriteFileTypeToACR()
    Archive->Push(0x0002,0x0102);
 }
 
- /**
 * \brief Sets in the File the TransferSyntax to 'JPEG2000'
 */
+/**
+ * \brief Sets in the File the TransferSyntax to 'JPEG2000'
+ */
 void FileHelper::SetWriteFileTypeToJPEG2000()
 {
    std::string ts = Util::DicomString(
    Global::GetTS()->GetSpecialTransferSyntax(TS::JPEG2000Lossless) );
-   
+
    DataEntry *tss = CopyDataEntry(0x0002,0x0010,"UI");
    tss->SetString(ts);
 
@@ -1107,11 +1119,11 @@ void FileHelper::SetWriteFileTypeToJPEG2000()
 
 /**
  * \brief Sets in the File the TransferSyntax to 'JPEG'
- */ 
+ */
 void FileHelper::SetWriteFileTypeToJPEG()
 {
-   std::string ts = Util::DicomString( 
-      Global::GetTS()->GetSpecialTransferSyntax(TS::JPEGBaselineProcess1) );
+   std::string ts = Util::DicomString(
+      Global::GetTS()->GetSpecialTransferSyntax(TS::JPEGLosslessProcess14_1) );
 
    DataEntry *tss = CopyDataEntry(0x0002,0x0010,"UI");
    tss->SetString(ts);
@@ -1159,9 +1171,6 @@ void FileHelper::SetWriteToLibido()
    if ( oldRow && oldCol )
    {
       std::string rows, columns; 
-
-      //DataEntry *newRow=DataEntry::New(oldRow->GetDictEntry());
-      //DataEntry *newCol=DataEntry::New(oldCol->GetDictEntry());
       
       DataEntry *newRow=DataEntry::New(0x0028, 0x0010, "US");
       DataEntry *newCol=DataEntry::New(0x0028, 0x0011, "US");
@@ -1238,7 +1247,6 @@ DataEntry *FileHelper::CopyDataEntry(uint16_t group, uint16_t elem,
 
    if ( oldE )
    {
-      //newE = DataEntry::New(oldE->GetDictEntry());
       newE = DataEntry::New(group, elem, vr);
       newE->Copy(oldE);
    }
@@ -1296,9 +1304,9 @@ We have to deal with 4 *very* different cases :
    FILTERED_IMAGE
 -3) user created a new image, using a set of existing images (eg MIP, MPR, cartography image)
    CREATED_IMAGE
--4) user modified/added some tags *without processing* the pixels (anonymization..
+-4) user modified/added some tags *without processing* the pixels (anonymization...)
    UNMODIFIED_PIXELS_IMAGE
--Probabely some more to be added  
+-Probabely some more to be added.  
  
 gdcm::FileHelper::CheckMandatoryElements() deals automatically with these cases.
 
@@ -1435,20 +1443,20 @@ void FileHelper::CheckMandatoryElements()
   
    //0002 0000 UL 1 Meta Group Length
    //0002 0001 OB 1 File Meta Information Version
-   //0002 0002 UI 1 Media Stored SOP Class UID
-   //0002 0003 UI 1 Media Stored SOP Instance UID
+   //0002 0002 UI 1 Media Storage SOP Class UID
+   //0002 0003 UI 1 Media Storage SOP Instance UID
    //0002 0010 UI 1 Transfer Syntax UID
    //0002 0012 UI 1 Implementation Class UID
    //0002 0013 SH 1 Implementation Version Name
    //0002 0016 AE 1 Source Application Entity Title
    //0002 0100 UI 1 Private Information Creator
    //0002 0102 OB 1 Private Information
+
    // Push out 'ACR-NEMA-special' entries, if any
       Archive->Push(0x0008,0x0001); // Length to End
       Archive->Push(0x0008,0x0010); // Recognition Code
-      Archive->Push(0x0028,0x0005); // Image Dimension  
-  
+      Archive->Push(0x0028,0x0005); // Image Dimension
+
    // Create them if not found
    // Always modify the value
    // Push the entries to the archive.
@@ -1691,17 +1699,17 @@ is only from (0020,0030) and (0020,0035)
       CopyMandatoryEntry(0x0020, 0x0032,imagePositionRet,"DS");
       Archive->Push(0x0020,0x0030); 
       CopyMandatoryEntry(0x0020, 0x0037,imageOrientationRet,"DS");
-      Archive->Push(0x0020,0x0035);        
-   }        
+      Archive->Push(0x0020,0x0035);
+   }
 */
-    
+
    // Samples Per Pixel (type 1) : default to grayscale 
    CheckMandatoryEntry(0x0028,0x0002,"1","US");
 
    // --- Check UID-related Entries ---
  
    // At the end, not to overwrite the original ones,
-   // needed by 'Referenced SOP Instance UID', 'Referenced SOP Class UID'   
+   // needed by 'Referenced SOP Instance UID', 'Referenced SOP Class UID'
    // 'SOP Instance UID'  
    CopyMandatoryEntry(0x0008,0x0018,sop,"UI");
 
@@ -1713,7 +1721,7 @@ is only from (0020,0030) and (0020,0035)
        // See PS 3.3, Page 408
    
        // DV = Digitized Video
-       // DI = Digital Interface   
+       // DI = Digital Interface 
        // DF = Digitized Film
        // WSD = Workstation
        // SD = Scanned Document
@@ -1730,7 +1738,7 @@ is only from (0020,0030) and (0020,0035)
    
    }
 */
-           
+  
    // ---- The user will never have to take any action on the following ----
 
    // new value for 'SOP Instance UID'
@@ -1739,7 +1747,7 @@ is only from (0020,0030) and (0020,0035)
    // Instance Creation Date
    const std::string &date = Util::GetCurrentDate();
    CopyMandatoryEntry(0x0008,0x0012,date,"DA");
+
    // Instance Creation Time
    const std::string &time = Util::GetCurrentTime();
    CopyMandatoryEntry(0x0008,0x0013,time,"TM");
@@ -1787,7 +1795,7 @@ is only from (0020,0030) and (0020,0035)
 
    // Instance Number
    CheckMandatoryEntry(0x0020,0x0013,"","IS");
-   
+
    // Patient Orientation
    // Can be computed from (0020|0037) :  Image Orientation (Patient)
    GDCM_NAME_SPACE::Orientation *o = GDCM_NAME_SPACE::Orientation::New();
@@ -1795,7 +1803,7 @@ is only from (0020,0030) and (0020,0035)
    o->Delete();
    if (ori != "\\" && ori != GDCM_UNFOUND)
       CheckMandatoryEntry(0x0020,0x0020,ori,"CS");
-   else   
+   else
       CheckMandatoryEntry(0x0020,0x0020,"","CS");
 
    // Default Patient Position to HFS
@@ -1842,7 +1850,7 @@ is only from (0020,0030) and (0020,0035)
       CheckMandatoryEntry(it->first, 0x0000, "0"); 
   }    
   // Third stage : update all 'zero level' groups length
-*/ 
+*/
 
 
    if (PhotometricInterpretation == 1)
@@ -1918,7 +1926,6 @@ void FileHelper::RestoreWriteMandatory()
    Archive->Restore(0x0020,0x000e);
 }
 
-
 /**
  * \brief   CallStartMethod
  */
@@ -1955,12 +1962,12 @@ void FileHelper::Initialize()
 {
    UserFunction = 0;
    ContentType = USER_OWN_IMAGE;
-   
+
    WriteMode = WMODE_RAW;
    WriteType = ExplicitVR;
    
    PhotometricInterpretation = 2; // Black = 0
-   
+
    PixelReadConverter  = new PixelReadConvert;
    PixelWriteConverter = new PixelWriteConvert;
    Archive = new DocEntryArchive( FileInternal );
@@ -1995,7 +2002,6 @@ uint8_t *FileHelper::GetRaw()
    return raw;
 }
 
-
 /**
  * \brief Deal with Grey levels i.e. re-arange them
  *        to have low values = dark, high values = bright
@@ -2209,9 +2215,7 @@ void RescaleFunction(TBuffer* buffer, TSource *source,
       case 1:      *buffer++ = (TBuffer)(*source++);
                  }  while (--n > 0);
       }
-    }
-    
-    
+   }   
 }
 
 
index eb6597fa2bf485cabfa23a284d551336ef9c62f7..9f869336912b8ea45c30ce506386a5eb48299007 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmJpeg.cxx,v $
   Language:  C++
-  Date:      $Date: 2007/05/23 14:18:10 $
-  Version:   $Revision: 1.56 $
+  Date:      $Date: 2007/07/13 08:17:21 $
+  Version:   $Revision: 1.57 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -42,7 +42,7 @@
 
 #if defined(__BORLANDC__)
    #include <mem.h> // for memset
-#endif 
+#endif
 
 #include "jdatasrc.cxx"
 #include "jdatadst.cxx"
@@ -51,21 +51,24 @@ namespace GDCM_NAME_SPACE
 {
 
  /**
- * \brief   routine for JPEG decompression 
- * @param fp pointer to an already open file descriptor 
+ * \brief   routine for JPEG decompression
+ * @param fp pointer to an already open file descriptor
  *                      8 significant bits per pixel
  * @param im_buf Points to array (of R,G,B-order) data to compress
  * @param quality compression quality
- * @param image_height Number of rows in image 
+ * @param image_height Number of rows in image
  * @param image_width Number of columns in image
  * @return 1 on success, 0 on error
  */
-bool gdcm_write_JPEG_file (std::ostream *fp, void *im_buf, 
-                           int image_width, int image_height, int quality)
+
+bool gdcm_write_JPEG_file (std::ostream *fp, char *inputdata, size_t inputlength,
+                           int image_width, int image_height, int numZ,
+                           int sample_pixel, int bitsallocated, int quality)
 {
 
-   JSAMPLE *image_buffer = (JSAMPLE*) im_buf;
+  (void)bitsallocated;
+  struct jpeg_compress_struct cinfo;
+  int row_stride;            /* physical row width in image buffer */
 
   /* This struct contains the JPEG compression parameters and pointers to
    * working space (which is allocated as needed by the JPEG library).
@@ -73,7 +76,7 @@ bool gdcm_write_JPEG_file (std::ostream *fp, void *im_buf,
    * compression/decompression processes, in existence at once.  We refer
    * to any one struct (and its associated working data) as a "JPEG object".
    */
-  struct jpeg_compress_struct cinfo;
+  //struct jpeg_compress_struct cinfo;
   /* This struct represents a JPEG error handler.  It is declared separately
    * because applications often want to supply a specialized error handler
    * (see the second half of this file for an example).  But here we just
@@ -84,9 +87,6 @@ bool gdcm_write_JPEG_file (std::ostream *fp, void *im_buf,
    */
   struct jpeg_error_mgr jerr;
   /* More stuff */
-  //FILE*  outfile;    /* target FILE* /
-  JSAMPROW row_pointer[1];   /* pointer to JSAMPLE row[s] */
-  int row_stride;            /* physical row width in image buffer */
 
   /* Step 1: allocate and initialize JPEG compression object */
 
@@ -102,19 +102,8 @@ bool gdcm_write_JPEG_file (std::ostream *fp, void *im_buf,
   /* Step 2: specify data destination (eg, a file) */
   /* Note: steps 2 and 3 can be done in either order. */
 
-  /* Here we use the library-supplied code to send compressed data to a
-   * stdio stream.  You can also write your own code to do something else.
-   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
-   * requires it in order to write binary files.
-   */
- // if ((outfile = fopen(filename, "wb")) == NULL) {
- //   fprintf(stderr, "can't open %s\n", filename);
- //   exit(1);
- //
- // }
-  assert( 0 );
-  (void)fp;
-  //jpeg_stdio_dest(&cinfo, fp, 0, 0, image_width, image_height, quality);
+  int fragment_size = inputlength;
+  jpeg_stdio_dest(&cinfo, fp, fragment_size, 1);
 
   /* Step 3: set parameters for compression */
 
@@ -123,13 +112,36 @@ bool gdcm_write_JPEG_file (std::ostream *fp, void *im_buf,
    */
   cinfo.image_width = image_width;/* image width and height, in pixels */
   cinfo.image_height = image_height;
-  cinfo.input_components = 3;     /* # of color components per pixel */
-  cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
+  if ( sample_pixel == 3 )
+    {
+    cinfo.input_components = 3;     /* # of color components per pixel */
+    cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
+    }
+  else
+    {
+    cinfo.input_components = 1;     /* # of color components per pixel */
+    cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
+    }
   /* Now use the library's routine to set default compression parameters.
    * (You must set at least cinfo.in_color_space before calling this,
    * since the defaults depend on the source color space.)
    */
   jpeg_set_defaults(&cinfo);
+  /*
+   * http://www.koders.com/c/fid80DBBF1D49D004EF71CE7C493C34610C4F17D3D3.aspx
+   * http://studio.imagemagick.org/pipermail/magick-users/2002-September/004685.html
+   * You need to set -quality 101 or greater.  If quality is 100 or less you
+   * get regular JPEG output.  This is not explained in the documentation, only
+   * in the comments in coder/jpeg.c.  When you have configured libjpeg with
+   * lossless support, then
+   * 
+   *    quality=predictor*100 + point_transform
+   * 
+   * If you don't know what these values should be, just use 101.
+   * They only affect the compression ratio, not the image appearance,
+   * which is lossless.
+   */
+  jpeg_simple_lossless (&cinfo, 1, 1);
   /* Now you can set any non-default parameters you wish to.
    * Here we just illustrate the use of quality (quantization table) scaling:
    */
@@ -150,25 +162,57 @@ bool gdcm_write_JPEG_file (std::ostream *fp, void *im_buf,
    * To keep things simple, we pass one scanline per call; you can pass
    * more if you wish, though.
    */
-  row_stride = image_width * 3;/* JSAMPLEs per row in image_buffer */
+  if (sample_pixel == 3)
+    {
+    row_stride = image_width * 3;/* JSAMPLEs per row in image_buffer */
+    }
+  else
+    {
+    assert( sample_pixel == 1 );
+    row_stride = image_width * 1;/* JSAMPLEs per row in image_buffer */
+    }
+
+  (void)numZ;
+
+  uint8_t* input_buffer = (uint8_t*)inputdata;
+  //uint8_t *pbuffer = input_buffer;
+  //int i;
+  //for(i=0; i<numZ; ++i)
+//    {
+  JSAMPLE *image_buffer = (JSAMPLE*) input_buffer;
+  JSAMPROW row_pointer[1];   /* pointer to JSAMPLE row[s] */
+  row_pointer[0] = image_buffer;
 
   while (cinfo.next_scanline < cinfo.image_height) {
     /* jpeg_write_scanlines expects an array of pointers to scanlines.
      * Here the array is only one element long, but you could pass
      * more than one scanline at a time if that's more convenient.
      */
-    row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
+    //row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
 
-    (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
+    if( jpeg_write_scanlines(&cinfo, row_pointer, 1) != 1)
+      {
+      //entering suspension mode, basically we wrote the whole jpeg fragment
+      // technically we could enforce that by checkig the value of row_pointer to
+      // actually be at the end of the image...TODO
+      return false;
+      }
+    row_pointer[0] += row_stride;
   }
+//    pbuffer+=fragment_size; //shift to next image
+
+    //Upodate frag size
+//    size_t end = fp->tellp();
+//    std::cerr << "DIFF: " << end-beg << std::endl;
+
+//    JpegPair &jp = v[i];
+//    jp.second = end-beg;
+    //beg = end; //
+ //   }
 
   /* Step 6: Finish compression */
 
   jpeg_finish_compress(&cinfo);
-  
-  /* After finish_compress, we can close the output file. */
-  
- // fclose(fp); --> the caller will close (multiframe treatement)
 
   /* Step 7: release JPEG compression object */
 
index ed0f09f2d19e9a808ccb09c82fdd38f80e8e629c..0f3dd173fd617cf0002170949f2f340b568176c3 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmJpeg2000.cxx,v $
   Language:  C++
-  Date:      $Date: 2007/05/23 14:18:10 $
-  Version:   $Revision: 1.43 $
+  Date:      $Date: 2007/07/13 08:17:21 $
+  Version:   $Revision: 1.44 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -59,6 +59,24 @@ namespace GDCM_NAME_SPACE
  * @return 1 on success, 0 on error
  */
 
+/**
+sample error callback expecting a FILE* client object
+*/
+void error_callback(const char *msg, void *) {
+  std::cerr << "Error in gdcmopenjpeg" << msg << std::endl;
+}
+/**
+sample warning callback expecting a FILE* client object
+*/
+void warning_callback(const char *msg, void *) {
+  std::cerr << "Warning in gdcmopenjpeg" << msg << std::endl;
+}
+/**
+sample debug callback expecting no client object
+*/
+void info_callback(const char *msg, void *) {
+  std::cerr << "Info in gdcmopenjpeg" << msg << std::endl;
+}
 
 #define J2K_CFMT 0
 #define JP2_CFMT 1
@@ -114,9 +132,9 @@ bool gdcm_read_JPEG2000_file (void* raw, char *inputdata, size_t inputlength)
 
       /* get a decoder handle */
       dinfo = opj_create_decompress(CODEC_J2K);
-      
+
       /* catch events using our callbacks and give a local context */
-      opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL);      
+      opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, NULL);
 
       /* setup the decoder decoding parameters using user parameters */
       opj_setup_decoder(dinfo, &parameters);
@@ -142,43 +160,46 @@ bool gdcm_read_JPEG2000_file (void* raw, char *inputdata, size_t inputlength)
    for (int compno = 0; compno < image->numcomps; compno++)
    {
       opj_image_comp_t *comp = &image->comps[compno];
-  
+
       int w = image->comps[compno].w;
       int wr = int_ceildivpow2(image->comps[compno].w, image->comps[compno].factor);
-  
+
       //int h = image.comps[compno].h;
       int hr = int_ceildivpow2(image->comps[compno].h, image->comps[compno].factor);
-  
+
       if (comp->prec <= 8)
       {
-         uint8_t *data8 = (uint8_t*)raw;
-         for (int i = 0; i < wr * hr; i++) 
+         uint8_t *data8 = (uint8_t*)raw + compno;
+         for (int i = 0; i < wr * hr; i++)
          {
             int v = image->comps[compno].data[i / wr * w + i % wr];
-            *data8++ = (uint8_t)v;
+            *data8 = (uint8_t)v;
+            data8 += image->numcomps;
          }
       }
       else if (comp->prec <= 16)
       {
-         uint16_t *data16 = (uint16_t*)raw;
-         for (int i = 0; i < wr * hr; i++) 
+         uint16_t *data16 = (uint16_t*)raw + compno;
+         for (int i = 0; i < wr * hr; i++)
          {
             int v = image->comps[compno].data[i / wr * w + i % wr];
-            *data16++ = (uint16_t)v;
+            *data16 = (uint16_t)v;
+            data16 += image->numcomps;
          }
       }
       else
       {
-         uint32_t *data32 = (uint32_t*)raw;
-         for (int i = 0; i < wr * hr; i++) 
+         uint32_t *data32 = (uint32_t*)raw + compno;
+         for (int i = 0; i < wr * hr; i++)
          {
             int v = image->comps[compno].data[i / wr * w + i % wr];
-            *data32++ = (uint32_t)v;
+            *data32 = (uint32_t)v;
+            data32 += image->numcomps;
          }
       }
       //free(image.comps[compno].data);
    }
+
 
   /* free remaining structures */
   if(dinfo) {
@@ -188,6 +209,246 @@ bool gdcm_read_JPEG2000_file (void* raw, char *inputdata, size_t inputlength)
   /* free image data structure */
   opj_image_destroy(image);
 
+  return true;
+}
+
+template<typename T>
+void rawtoimage_fill(T *inputbuffer, int w, int h, int numcomps, opj_image_t *image)
+{
+  T *p = inputbuffer;
+  for (int i = 0; i < w * h; i++)
+    {
+    for(int compno = 0; compno < numcomps; compno++)
+      {
+      /* compno : 0 = GREY, (0, 1, 2) = (R, G, B) */
+      image->comps[compno].data[i] = *p;
+      ++p;
+      }
+    }
+}
+
+opj_image_t* rawtoimage(char *inputbuffer, opj_cparameters_t *parameters,
+  int fragment_size, int image_width, int image_height, int sample_pixel,
+  int bitsallocated, int sign, int quality)
+{
+  (void)quality;
+  (void)fragment_size;
+  int w, h;
+  int numcomps;
+  OPJ_COLOR_SPACE color_space;
+  opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
+  opj_image_t * image = NULL;
+
+  assert( sample_pixel == 1 || sample_pixel == 3 );
+  if( sample_pixel == 1 )
+    {
+    numcomps = 1;
+    color_space = CLRSPC_GRAY;
+    }
+  else // sample_pixel == 3
+    {
+    numcomps = 3;
+    color_space = CLRSPC_SRGB;
+    }
+  int subsampling_dx = parameters->subsampling_dx;
+  int subsampling_dy = parameters->subsampling_dy;
+
+  // FIXME
+  w = image_width;
+  h = image_height;
+
+  /* initialize image components */
+  memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t));
+  //assert( bitsallocated == 8 );
+  for(int i = 0; i < numcomps; i++) {
+    cmptparm[i].prec = bitsallocated;
+    cmptparm[i].bpp = bitsallocated;
+    cmptparm[i].sgnd = sign;
+    cmptparm[i].dx = subsampling_dx;
+    cmptparm[i].dy = subsampling_dy;
+    cmptparm[i].w = w;
+    cmptparm[i].h = h;
+  }
+
+  /* create the image */
+  image = opj_image_create(numcomps, &cmptparm[0], color_space);
+  if(!image) {
+    return NULL;
+  }
+  /* set image offset and reference grid */
+  image->x0 = parameters->image_offset_x0;
+  image->y0 = parameters->image_offset_y0;
+  image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1;
+  image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1;
+
+  /* set image data */
+
+  //assert( fragment_size == numcomps*w*h*(bitsallocated/8) );
+  if (bitsallocated <= 8)
+    {
+    if( sign )
+      {
+      rawtoimage_fill<int8_t>((int8_t*)inputbuffer,w,h,numcomps,image);
+      }
+    else
+      {
+      rawtoimage_fill<uint8_t>((uint8_t*)inputbuffer,w,h,numcomps,image);
+      }
+    }
+  else if (bitsallocated <= 16)
+    {
+    if( sign )
+      {
+      rawtoimage_fill<int16_t>((int16_t*)inputbuffer,w,h,numcomps,image);
+      }
+    else
+      {
+      rawtoimage_fill<uint16_t>((uint16_t*)inputbuffer,w,h,numcomps,image);
+      }
+    }
+  else if (bitsallocated <= 32)
+    {
+    if( sign )
+      {
+      rawtoimage_fill<int32_t>((int32_t*)inputbuffer,w,h,numcomps,image);
+      }
+    else
+      {
+      rawtoimage_fill<uint32_t>((uint32_t*)inputbuffer,w,h,numcomps,image);
+      }
+    }
+  else
+    {
+    abort();
+    }
+
+  return image;
+}
+
+/*
+ * The following function was copy paste from image_to_j2k.c with part from convert.c
+ */
+bool gdcm_write_JPEG2000_file (std::ostream *fp, char *inputdata, size_t inputlength, 
+  int image_width, int image_height, int numZ, int sample_pixel, int bitsallocated,
+  int sign, int quality)
+{
+//// input_buffer is ONE image
+//// fragment_size is the size of this image (fragment)
+  (void)numZ;
+  bool bSuccess;
+  //bool delete_comment = true;
+  opj_cparameters_t parameters;  /* compression parameters */
+  opj_event_mgr_t event_mgr;    /* event manager */
+  opj_image_t *image = NULL;
+  //quality = 100;
+
+  /*
+  configure the event callbacks (not required)
+  setting of each callback is optionnal
+  */
+  memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
+  event_mgr.error_handler = error_callback;
+  event_mgr.warning_handler = warning_callback;
+  event_mgr.info_handler = info_callback;
+
+  /* set encoding parameters to default values */
+  memset(&parameters, 0, sizeof(parameters));
+  opj_set_default_encoder_parameters(&parameters);
+
+  /* if no rate entered, lossless by default */
+  parameters.tcp_rates[0] = 0;
+  parameters.tcp_numlayers = 1;
+  parameters.cp_disto_alloc = 1;
+
+  if(parameters.cp_comment == NULL) {
+    const char comment[] = "Created by GDCM/OpenJPEG version 1.0";
+    parameters.cp_comment = (char*)malloc(strlen(comment) + 1);
+    strcpy(parameters.cp_comment, comment);
+    /* no need to delete parameters.cp_comment on exit */
+    //delete_comment = false;
+  }
+
+  
+  /* decode the source image */
+  /* ----------------------- */
+
+  image = rawtoimage((char*)inputdata, &parameters, inputlength, 
+    image_width, image_height,
+    sample_pixel, bitsallocated, sign, quality);
+  if (!image) {
+    return 1;
+  }
+
+    /* encode the destination image */
+  /* ---------------------------- */
+   parameters.cod_format = J2K_CFMT; /* J2K format output */
+    int codestream_length;
+    opj_cio_t *cio = NULL;
+    //FILE *f = NULL;
+
+    /* get a J2K compressor handle */
+    opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);
+
+    /* catch events using our callbacks and give a local context */
+    opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
+
+    /* setup the encoder parameters using the current image and using user parameters */
+    opj_setup_encoder(cinfo, &parameters, image);
+
+    /* open a byte stream for writing */
+    /* allocate memory for all tiles */
+    cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
+
+    /* encode the image */
+    bSuccess = opj_encode(cinfo, cio, image, parameters.index);
+    if (!bSuccess) {
+      opj_cio_close(cio);
+      fprintf(stderr, "failed to encode image\n");
+      return 1;
+    }
+    codestream_length = cio_tell(cio);
+
+    /* write the buffer to disk */
+    //f = fopen(parameters.outfile, "wb");
+    //if (!f) {
+    //  fprintf(stderr, "failed to open %s for writing\n", parameters.outfile);
+    //  return 1;
+    //}
+    //fwrite(cio->buffer, 1, codestream_length, f);
+//#define MDEBUG
+#ifdef MDEBUG
+    static int c = 0;
+    std::ostringstream os;
+    os << "/tmp/debug";
+    os << c;
+    c++;
+    os << ".j2k";
+    std::ofstream debug(os.str().c_str());
+    debug.write((char*)(cio->buffer), codestream_length);
+    debug.close();
+#endif
+    fp->write((char*)(cio->buffer), codestream_length);
+    //fclose(f);
+
+    /* close and free the byte stream */
+    opj_cio_close(cio);
+
+    /* free remaining compression structures */
+    opj_destroy_compress(cinfo);
+
+
+      /* free user parameters structure */
+  //if(delete_comment) {
+    if(parameters.cp_comment) free(parameters.cp_comment);
+  //}
+  if(parameters.cp_matrice) free(parameters.cp_matrice);
+
+  /* free image data */
+  opj_image_destroy(image);
+
+
+
+
   return true;
 }
 
index 53de1044045d8debe8e54081ab0ae0865dfbd82d..94359049714d8376129e284d9cc42641dc87d16e 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmPixelWriteConvert.cxx,v $
   Language:  C++
-  Date:      $Date: 2007/07/04 10:40:56 $
-  Version:   $Revision: 1.13 $
+  Date:      $Date: 2007/07/13 08:17:21 $
+  Version:   $Revision: 1.14 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
 
 #include "gdcmDebug.h"
 #include "gdcmPixelWriteConvert.h"
+#include "gdcmFile.h"
+#include "gdcmUtil.h"
+
+#include <vector>
+
+#define WITHOFFSETTABLE 1
 
 namespace GDCM_NAME_SPACE
 {
 //-----------------------------------------------------------------------------
+// Public
+
+//-----------------------------------------------------------------------------
+// Protected
+
+//-----------------------------------------------------------------------------
+// Private
+
 // Constructor / Destructor
 /**
  * \brief Constructor
@@ -33,6 +47,7 @@ PixelWriteConvert::PixelWriteConvert()
 
    UserData     = 0;
    UserDataSize = 0;
+   Compressed   = false;
 }
 
 /**
@@ -40,10 +55,12 @@ PixelWriteConvert::PixelWriteConvert()
  */
 PixelWriteConvert::~PixelWriteConvert() 
 {
+   if( Compressed )
+     {
+     delete[] UserData;
+     }
 }
 
-//-----------------------------------------------------------------------------
-// Public
 /**
  * \brief   sets Read Data (and size)
  * @param   data data (uint8_t is for prototyping. if your data is not uint8_t
@@ -107,8 +124,291 @@ size_t PixelWriteConvert::GetDataSize()
    }
 }
 
+
+typedef std::pair<size_t, uint32_t> JpegPair; //offset, jpeg size
+typedef std::vector<JpegPair> JpegVector;
+
+bool gdcm_write_JPEG2000_file (std::ostream *of, char *inputdata, size_t inputlength, 
+  int image_width, int image_height, int numZ, int sample_pixel, int bitsallocated,
+  int sign, int quality);
+
+
+void WriteDICOMItems(std::ostream *fp, JpegVector &v)
+{
+  // Item tag:
+  uint16_t group = 0xfffe;
+  uint16_t elem  = 0xe000;
+  GDCM_NAME_SPACE::binary_write(*fp, group);
+  GDCM_NAME_SPACE::binary_write(*fp, elem);
+  // Item Length
+  uint32_t dummy = 0x12345678;
+  size_t offset = fp->tellp();
+  JpegPair jp;
+  jp.first = offset;
+  v.push_back(jp);
+  GDCM_NAME_SPACE::binary_write(*fp, dummy);
+}
+
+// PS 3.5, page 66
+void EncodeWithoutBasicOffsetTable(std::ostream *fp, int numFrag)// JpegVector& v) //, uint32_t length)
+{
+  assert( numFrag == 1);
+
+  // Item tag:
+  uint16_t group = 0xfffe;
+  uint16_t elem  = 0xe000;
+  GDCM_NAME_SPACE::binary_write(*fp, group);
+  GDCM_NAME_SPACE::binary_write(*fp, elem);
+  // Item Length
+  uint32_t item_length = 0x0000;
+  GDCM_NAME_SPACE::binary_write(*fp, item_length);
+
+}
+
+// PS 3.5, page 67
+void EncodeWithBasicOffsetTable(std::ostream *fp, int numFrag, size_t &start)
+{
+  // Item tag:
+  uint16_t group = 0xfffe;
+  uint16_t elem  = 0xe000;
+  GDCM_NAME_SPACE::binary_write(*fp, group);
+  GDCM_NAME_SPACE::binary_write(*fp, elem);
+  // Item Length
+  uint32_t item_length = numFrag*4; // sizeof(uint32_t)
+  GDCM_NAME_SPACE::binary_write(*fp, item_length);
+
+  // Just prepare the space
+  start = fp->tellp(); //to be able to rewind
+  for(int i=0; i<numFrag;++i)
+    {
+    uint32_t dummy = 0x0000;
+    GDCM_NAME_SPACE::binary_write(*fp, dummy);
+    }
+}
+
+void UpdateBasicOffsetTable(std::ostream *fp, JpegVector const &v, size_t pos)
+{
+  JpegVector::const_iterator i;
+  fp->seekp( pos );
+  const JpegPair &first = v[0];
+  for(i=v.begin(); i!=v.end(); ++i)
+    {
+    const JpegPair &jp = *i;
+    if(i == v.begin() ){ assert( jp.first - first.first == 0); }
+    uint32_t offset = jp.first - first.first;
+    GDCM_NAME_SPACE::binary_write(*fp, offset);
+    //std::cerr << "Updating Table:" << jp.first - first.first << std::endl;
+    }
+}
+
+void UpdateJpegFragmentSize(std::ostream *fp, JpegVector const &v)
+{
+  JpegVector::const_iterator i;
+  for(i= v.begin(); i!=v.end(); ++i)
+    {
+    const JpegPair &jp = *i;
+    fp->seekp( jp.first );
+    uint32_t length = jp.second;
+    GDCM_NAME_SPACE::binary_write(*fp, length);
+    //std::cerr << "Updating:" << jp.first << "," << jp.second << std::endl;
+    }
+}
+
+void CloseJpeg(std::ostream *fp, JpegVector &v)
+{
+  // sequence terminator
+  uint16_t group = 0xfffe;
+  uint16_t elem  = 0xe0dd;
+  GDCM_NAME_SPACE::binary_write(*fp, group);
+  GDCM_NAME_SPACE::binary_write(*fp, elem);
+
+  uint32_t length = 0x0;
+  GDCM_NAME_SPACE::binary_write(*fp, length);
+
+  // Jpeg is done, now update the frag length
+  UpdateJpegFragmentSize(fp, v);
+}
+
+// I need to pass the File*. I do not understand how PixelWriteConvert is supposed
+// to access this information otherwise
+// size can now be computer from File attributes (what an API...)
+void PixelWriteConvert::SetCompressJPEG2000UserData(uint8_t *data, size_t size, File *image)
+{
+  Compressed = true;
+  //char * userData = reinterpret_cast<char*>(UserData);
+
+   std::ostringstream *of = new std::ostringstream();
+    int xsize = image->GetXSize();
+   int ysize = image->GetYSize();
+  int zsize =  image->GetZSize();
+    int samplesPerPixel = image->GetSamplesPerPixel();
+   //std::cout << "X: " << xsize << std::endl;
+   //std::cout << "Y: " << ysize << std::endl;
+   //std::cout << "Sample: " << samplesPerPixel << std::endl;
+    int bitsallocated = image->GetBitsAllocated();
+    int sign = image->IsSignedPixelData();
+   unsigned int fragment_size = xsize*ysize*samplesPerPixel * (bitsallocated / 8);
+    assert( fragment_size*zsize == size );
+
+   JpegVector JpegFragmentSize;
+#if WITHOFFSETTABLE
+   size_t bots; //basic offset table start
+   EncodeWithBasicOffsetTable(of, zsize, bots);
+#else
+   EncodeWithoutBasicOffsetTable(of, 1);
+#endif
+   uint8_t *pImageData = data;
+   for(int i=0; i<zsize;i++)
+     {
+     WriteDICOMItems(of, JpegFragmentSize);
+     size_t beg = of->tellp();
+     gdcm_write_JPEG2000_file(of, (char*)pImageData,size, 
+       image->GetXSize(), image->GetYSize(), image->GetZSize(), image->GetSamplesPerPixel(),
+       image->GetBitsAllocated(), sign, 100);
+     //userData, UserDataSize);
+     //     CreateOneFrame(of, pImageData, fragment_size, xsize, ysize, zsize, 
+     //       samplesPerPixel, quality, JpegFragmentSize);
+     //assert( !(fragment_size % 2) );
+     // Update the JpegVector with offset
+     size_t end = of->tellp();
+     //static int i = 0;
+     JpegPair &jp = JpegFragmentSize[i];
+     jp.second = end-beg;
+     if( ((end-beg) % 2) )
+       {
+       of->put( '\0' );
+       jp.second += 1;
+       }
+     assert( !(jp.second % 2) );
+     //std::cerr << "DIFF: " << i <<" -> " << jp.second << std::endl;
+     //++i;
+     pImageData += fragment_size;
+     }
+   CloseJpeg(of, JpegFragmentSize);
+#if WITHOFFSETTABLE
+   UpdateBasicOffsetTable(of, JpegFragmentSize, bots);
+#endif
+
+
+   size_t of_size = of->str().size();
+   UserData = new uint8_t[of_size];
+   memcpy(UserData, of->str().c_str(), of_size);
+   UserDataSize = of_size;
+   
+}
+
+bool gdcm_write_JPEG_file8 (std::ostream *fp, char *inputdata, size_t inputlength,
+                           int image_width, int image_height, int numZ,
+                           int sample_pixel, int bitsallocated, int quality);
+bool gdcm_write_JPEG_file12 (std::ostream *fp, char *inputdata, size_t inputlength,
+                           int image_width, int image_height, int numZ,
+                           int sample_pixel, int bitsallocated, int quality);
+bool gdcm_write_JPEG_file16 (std::ostream *fp, char *inputdata, size_t inputlength,
+                           int image_width, int image_height, int numZ,
+                           int sample_pixel, int bitsallocated, int quality);
+
+void PixelWriteConvert::SetCompressJPEGUserData(uint8_t *data, size_t size, File *image)
+{
+
+ std::cerr << "entree ds PixelWriteConvert::SetCompressJPEGUserData" << std::endl; 
+  (void)data;
+  (void)size;
+  (void)image;
+  Compressed = true;
+  //char * userData = reinterpret_cast<char*>(UserData);
+
+   std::ostringstream *of = new std::ostringstream();
+    int xsize = image->GetXSize();
+   int ysize = image->GetYSize();
+  int zsize =  image->GetZSize();
+    int samplesPerPixel = image->GetSamplesPerPixel();
+   //std::cout << "X: " << xsize << std::endl;
+   //std::cout << "Y: " << ysize << std::endl;
+   //std::cout << "Sample: " << samplesPerPixel << std::endl;
+    int bitsallocated = image->GetBitsAllocated();
+   unsigned int fragment_size = xsize*ysize*samplesPerPixel * (bitsallocated / 8);
+    assert( fragment_size*zsize == size );
+
+   JpegVector JpegFragmentSize;
+#if WITHOFFSETTABLE
+   size_t bots; //basic offset table start
+   EncodeWithBasicOffsetTable(of, zsize, bots);
+#else
+   EncodeWithoutBasicOffsetTable(of, 1);
+#endif
+   uint8_t *pImageData = data;
+   for(int i=0; i<zsize;i++)
+     {
+     WriteDICOMItems(of, JpegFragmentSize);
+  size_t beg = of->tellp();
+     if( bitsallocated == 8 )
+       {
+       gdcm_write_JPEG_file8(of, (char*)pImageData,size, 
+         image->GetXSize(), image->GetYSize(), image->GetZSize(), image->GetSamplesPerPixel(),
+         image->GetBitsAllocated(), 100 );
+       }
+     else if (bitsallocated <= 12)
+       {
+       assert( bitsallocated >= 8 );
+       gdcm_write_JPEG_file12(of, (char*)pImageData,size, 
+         image->GetXSize(), image->GetYSize(), image->GetZSize(), image->GetSamplesPerPixel(),
+         image->GetBitsAllocated(), 100);
+       }
+     else if (bitsallocated <= 16)
+       {
+       assert( bitsallocated >= 12 );
+       gdcm_write_JPEG_file16(of, (char*)pImageData,size, 
+         image->GetXSize(), image->GetYSize(), image->GetZSize(), image->GetSamplesPerPixel(),
+         image->GetBitsAllocated(), 100);
+       }
+     else
+       {
+       abort();
+       }
+    size_t end = of->tellp();
+    //static int i = 0;
+    JpegPair &jp = JpegFragmentSize[i];
+      jp.second = end-beg;
+    if( ((end-beg) % 2) )
+      {
+      of->put( '\0' );
+      jp.second += 1;
+      }
+    assert( !(jp.second % 2) );
+    //std::cerr << "DIFF: " << i <<" -> " << jp.second << std::endl;
+    //++i;
+
+  //JpegPair &jp = v[0];
+  //jp.second = 15328;
+
+
+     //userData, UserDataSize);
+     //     CreateOneFrame(of, pImageData, fragment_size, xsize, ysize, zsize, 
+     //       samplesPerPixel, quality, JpegFragmentSize);
+     //assert( !(fragment_size % 2) );
+     pImageData += fragment_size;
+     }
+   CloseJpeg(of, JpegFragmentSize);
+#if WITHOFFSETTABLE
+   UpdateBasicOffsetTable(of, JpegFragmentSize, bots);
+#endif
+
+
+   size_t of_size = of->str().size();
+   UserData = new uint8_t[of_size];
+   memcpy(UserData, of->str().c_str(), of_size);
+   UserDataSize = of_size;
+
+ std::cerr << "Sortie ds PixelWriteConvert::SetCompressJPEGUserData" << std::endl; 
+}
+
+
 //-----------------------------------------------------------------------------
 // Protected
+//bool PixelWriteConvert::CompressJPEG2000(uint8_t *data, size_t size)
+//{
+//}
 
 //-----------------------------------------------------------------------------
 // Private
index 59ddb91409bd1f2e71bf1e0d74d68f7d933c71fd..c71ff5c9d04fdfbb7a207388c0ccd165f3851863 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: gdcmPixelWriteConvert.h,v $
   Language:  C++
-  Date:      $Date: 2007/05/23 14:18:11 $
-  Version:   $Revision: 1.9 $
+  Date:      $Date: 2007/07/13 08:17:21 $
+  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
@@ -31,6 +31,7 @@ namespace GDCM_NAME_SPACE
  * \warning None of the methods may be called by end user (they have no
  *          meaning outside the class FileHelper)
  */
+class File;
 class GDCM_EXPORT PixelWriteConvert : public Base
 {
 friend class FileHelper;
@@ -57,6 +58,9 @@ private:
    uint8_t *GetData();
    size_t   GetDataSize();
 
+   void SetCompressJPEG2000UserData(uint8_t *data, size_t size, File *image);
+   void SetCompressJPEGUserData(uint8_t *data, size_t size, File *image);
+
 // Variables
    /// Pixel data represented as RGB after LUT color interpretation.
    uint8_t *ReadData;
@@ -67,6 +71,9 @@ private:
    uint8_t *UserData;
    /// Size of User image.
    size_t   UserDataSize;
+
+   /// Whether we want to write compressed
+   bool Compressed;
 };
 } // end namespace gdcm
 
index c3da1302d5cc6a7921491ced01831619f26fddbc..620e7d5a20967074365ab439ec1f6b4204be8e08 100644 (file)
@@ -3,8 +3,8 @@
   Program:   gdcm
   Module:    $RCSfile: vtkGdcmReader.h,v $
   Language:  C++
-  Date:      $Date: 2007/06/19 13:09:45 $
-  Version:   $Revision: 1.33 $
+  Date:      $Date: 2007/07/13 08:17:22 $
+  Version:   $Revision: 1.34 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -55,7 +55,7 @@ public:
 
    //BTX
    
-   /// \TODO fix possible problems around VTK pipelining
+   /// \todo fix possible problems around VTK pipelining
    
    void SetUserFunction (VOID_FUNCTION_PUINT8_PFILE_POINTER userFunc )
                         { UserFunction = userFunc; }