X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=Testing%2FTestAllReadCompareDicom.cxx;h=5d08ea35740eac6483365f0e6819b3ab63608e5a;hb=HEAD;hp=bb428fd0903b006f0668f019cf88ece83c7c53fe;hpb=bc69950a406d06c50f0fb75a96572784965cb534;p=gdcm.git diff --git a/Testing/TestAllReadCompareDicom.cxx b/Testing/TestAllReadCompareDicom.cxx index bb428fd0..5d08ea35 100644 --- a/Testing/TestAllReadCompareDicom.cxx +++ b/Testing/TestAllReadCompareDicom.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: TestAllReadCompareDicom.cxx,v $ Language: C++ - Date: $Date: 2005/10/18 08:35:46 $ - Version: $Revision: 1.48 $ + Date: $Date: 2008/09/15 15:49:21 $ + Version: $Revision: 1.62 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -21,12 +21,17 @@ #include "gdcmGlobal.h" #include "gdcmTS.h" #include "gdcmDebug.h" +#include "gdcmUtil.h" #include //Generated file: #include "gdcmDataImages.h" +//--> +//--> WARNING : +//--> The .tst files *must* be generated on a Little Endian based computer. +//--> /** * /brief File Read/Writer specific for the TestAllReadCompareDicom test * /remarks The Test file format is (only in little endian) : @@ -34,46 +39,51 @@ * - 4 bytes : size X * - 4 bytes : size Y * - 4 bytes : size Z - * - 2 bytes : scalar size (8,16,32) - * - 2 bytes : number of components per pixel (1,2,3) - * - n bytes : datas + * - 2 bytes : scalar size (8,16,32) --> ?!? 1 or 2 only in DICOM V3 ! + * - 2 bytes : number of components per pixel (1,2,3) ---> 1 or 3 only in DICOMV3 ! + * - n bytes : data */ class TestFile { public: - TestFile(void); - ~TestFile(void); - - bool IsReadable(void) {return readable;} - int GetXSize(void) {return sizeX;}; - void SetXSize(int size) {sizeX = size;}; - int GetYSize(void) {return sizeY;}; - void SetYSize(int size) {sizeY = size;}; - int GetZSize(void) {return sizeZ;}; - void SetZSize(int size) {sizeZ = size;}; - int GetScalarSize(void) {return scalarSize;}; - void SetScalarSize(int size) {scalarSize = size;}; - int GetNumberOfComponents(void) {return components;}; - void SetNumberOfComponents(int size) {components = size;}; - - unsigned long GetDataSize(void) {return GetLineSize()*sizeY*sizeZ;} - uint8_t *GetData(void) {return data;} + TestFile(); + ~TestFile(); + + bool IsReadable() {return readable;} + + int GetXSize() {return SizeX;} + int GetYSize() {return SizeY;} + int GetZSize() {return SizeZ;} + + void SetXSize(int size) {SizeX = size;} + void SetYSize(int size) {SizeY = size;} + void SetZSize(int size) {SizeZ = size;} + + int GetScalarSize() {return ScalarSize;} + void SetScalarSize(int size) {ScalarSize = size;} + + int GetNumberOfComponents() {return Components;} + void SetNumberOfComponents(int size) {Components = size;} + int GetSwapCode() {return SwapCode;} + + unsigned long GetDataSize() {return GetLineSize()*SizeY*SizeZ;} + uint8_t *GetData() {return Data;} void SetData(const uint8_t *newData); void Load(const std::string &filename); void Write(const std::string &filename); private: - unsigned long GetLineSize(void) {return sizeX*scalarSize*components;} - int GetSwapCode(uint32_t tag); + unsigned long GetLineSize() {return SizeX*ScalarSize*Components;} + int ComputeSwapCode(uint32_t tag); - void NewData(void); - void DeleteData(void); + void NewData(); + void DeleteData(); - void ReadFile(void); + void ReadFile(); bool ReadFileHeader(std::ifstream *fp); bool ReadFileData(std::ifstream *fp); - void WriteFile(void); + void WriteFile(); bool WriteFileHeader(std::ofstream *fp); bool WriteFileData(std::ofstream *fp); @@ -102,13 +112,13 @@ private: std::string fileName; bool readable; - int sizeX; - int sizeY; - int sizeZ; - uint16_t scalarSize; - uint16_t components; - uint8_t *data; - int swapCode; + int SizeX; + int SizeY; + int SizeZ; + uint16_t ScalarSize; + uint16_t Components; + uint8_t *Data; + int SwapCode; static const unsigned int HEADER_SIZE; }; @@ -121,17 +131,17 @@ TestFile::TestFile() fileName = ""; readable=false; - sizeX = 0; - sizeY = 0; - sizeZ = 0; - scalarSize = 0; - components = 0; - data = NULL; + SizeX = 0; + SizeY = 0; + SizeZ = 0; + ScalarSize = 0; + Components = 0; + Data = NULL; - swapCode = 1234; + //SwapCode = 1234; } -TestFile::~TestFile(void) +TestFile::~TestFile() { DeleteData(); } @@ -140,8 +150,8 @@ void TestFile::SetData(const uint8_t *newData) { DeleteData(); NewData(); - if( data ) - memcpy(data,newData,GetDataSize()); + if( Data ) + memcpy(Data,newData,GetDataSize()); } void TestFile::Load(const std::string &filename) @@ -156,9 +166,16 @@ void TestFile::Write(const std::string &filename) WriteFile(); } -int TestFile::GetSwapCode(uint32_t tag) +int TestFile::ComputeSwapCode(uint32_t tag) { +// FIXME : 100 % useless method ! +// "gdcm" was written on disc byte per byte. +// when you fread it, you'll get *always* "gdcm" +// whatever the processor indianess is ! + int swap = 0; + //std::cout << std::hex << "0x(" << tag << ")" << std::dec << std::endl; + for(int i=0;i<4;i++) { switch(tag&0x000000FF) @@ -180,25 +197,26 @@ int TestFile::GetSwapCode(uint32_t tag) } tag >>= 8; } + //std::cout << std::hex << "0x(" << tag << ")" << std::dec << tag << std::endl; return swap; } -void TestFile::NewData(void) +void TestFile::NewData() { DeleteData(); if( GetDataSize() == 0 ) return; - data = new uint8_t[GetDataSize()]; + Data = new uint8_t[GetDataSize()]; } -void TestFile::DeleteData(void) +void TestFile::DeleteData() { - if( data ) - delete[] data; - data = NULL; + if( Data ) + delete[] Data; + Data = NULL; } -void TestFile::ReadFile(void) +void TestFile::ReadFile() { readable=true; std::ifstream fp(fileName.c_str(),std::ios::in | std::ios::binary); @@ -222,7 +240,7 @@ void TestFile::ReadFile(void) readable=ReadFileData(&fp); if(!readable) { - std::cout << "Problems when reading datas" << std::endl; + std::cout << "Problems when reading data" << std::endl; fp.close(); return; } @@ -240,18 +258,19 @@ void TestFile::ReadFile(void) bool TestFile::ReadFileHeader(std::ifstream *fp) { uint32_t tag = ReadInt32(fp); - swapCode = GetSwapCode(tag); - if( swapCode == 0 ) + SwapCode = ComputeSwapCode(tag); + if( SwapCode == 0 ) { + // We shall *never* come here! std::cout << "TestFile: Bad tag - Must be 'gdcm'" << std::endl; return(false); } - sizeX = ReadInt32(fp); // Size X - sizeY = ReadInt32(fp); // Size Y - sizeZ = ReadInt32(fp); // Size Z - scalarSize = ReadInt16(fp)/8; // bits per scalar - components = ReadInt16(fp); // Number of components + SizeX = ReadInt32(fp); // Size X + SizeY = ReadInt32(fp); // Size Y + SizeZ = ReadInt32(fp); // Size Z + ScalarSize = ReadInt16(fp)/8; // bytes per scalar + Components = ReadInt16(fp); // Number of components return(true); } @@ -260,18 +279,42 @@ bool TestFile::ReadFileData(std::ifstream *fp) { DeleteData(); - // Allocate datas + // Allocate data NewData(); - if( !data ) + if( !Data ) return(false); - // Read datas - fp->read((char *)data,GetDataSize()); - + // Read data Note : .tst images are *always* created + // on little endian processor ! + fp->read((char *)Data,GetDataSize()); + + // Track BigEndian troubles + std::cout << " ScalarSize : " << GetScalarSize() + << " IsCurrentProcessorBigEndian:" + << GDCM_NAME_SPACE::Util::IsCurrentProcessorBigEndian() + << std::endl; + + //if (GetScalarSize() == 1 || GetSwapCode() == 1234) + if (GetScalarSize() == 1 || !GDCM_NAME_SPACE::Util::IsCurrentProcessorBigEndian() ) + { + return true; + } + // We *know* the .tst files are written in 'Little Endian' format. + // We *know* DataSize may be 1 or 2 ! + uint16_t g; + + std::cout << " Let's swap Pixels" <> 8 ); + ((uint16_t *)Data)[i] = g; + } return(true); } -void TestFile::WriteFile(void) +void TestFile::WriteFile() { std::ofstream fp(fileName.c_str(),std::ios::out | std::ios::binary); @@ -293,18 +336,23 @@ bool TestFile::WriteFileHeader(std::ofstream *fp) WriteInt8(fp,'d'); // Bitmap tag - must be 'd' WriteInt8(fp,'c'); // Bitmap tag - must be 'c' WriteInt8(fp,'m'); // Bitmap tag - must be 'm' - WriteInt32(fp,sizeX); // Size X - WriteInt32(fp,sizeY); // Size Y - WriteInt32(fp,sizeZ); // Size Z - WriteInt16(fp,scalarSize*8); // bits per scalar - WriteInt16(fp,components); // number of components + + // FIXME : Think of writting an int32, better ! + // (('g' << 8 + 'd') << 8 + 'c') + 'm' + // if you want to use it to check the endianess. + // (and upload again *all* the .tst files ...) + WriteInt32(fp,SizeX); // Size X + WriteInt32(fp,SizeY); // Size Y + WriteInt32(fp,SizeZ); // Size Z + WriteInt16(fp,ScalarSize*8); // bits per scalar + WriteInt16(fp,Components); // number of components return(true); } bool TestFile::WriteFileData(std::ofstream *fp) { - fp->write((char *)data,GetDataSize()); + fp->write((char *)Data,GetDataSize()); return(true); } @@ -398,8 +446,8 @@ int InternalTest(std::string const &filename, std::cout << "1..."; // new style - gdcm::File *f = new gdcm::File(); - f->SetLoadMode ( gdcm::LD_ALL ); // Load everything + GDCM_NAME_SPACE::File *f = GDCM_NAME_SPACE::File::New(); + f->SetLoadMode ( GDCM_NAME_SPACE::LD_ALL ); // Load everything f->SetFileName( filename ); f->Load(); @@ -408,10 +456,10 @@ int InternalTest(std::string const &filename, std::cout << " Failed" << std::endl << " Image not gdcm compatible:" << filename << std::endl; - delete f; + f->Delete(); return 1; } - gdcm::FileHelper *tested = new gdcm::FileHelper( f ); + GDCM_NAME_SPACE::FileHelper *tested = GDCM_NAME_SPACE::FileHelper::New( f ); ////// Step 2: ////// Check for existence of reference baseline dicom file: @@ -443,8 +491,8 @@ int InternalTest(std::string const &filename, << " Image not Testing compatible:" << filename << std::endl; delete reference; - delete tested; - delete f; + tested->Delete(); + f->Delete(); return 1; } @@ -471,8 +519,8 @@ int InternalTest(std::string const &filename, << "Z: " << tested->GetFile()->GetZSize() << " # " << reference->GetZSize() << std::endl; delete reference; - delete tested; - delete f; + tested->Delete(); + f->Delete(); return 1; } @@ -488,13 +536,15 @@ int InternalTest(std::string const &filename, << reference->GetNumberOfComponents() << std::endl << " Pixel type: " << tested->GetFile()->GetPixelType() << std::endl; delete reference; - delete tested; - delete f; + tested->Delete(); + f->Delete(); return 1; } // Test the data size - if (testedDataSize != referenceDataSize) + // *actual* image length may differ to 1 with Pixel Data Element length! + if ((testedDataSize+testedDataSize%2) != + (referenceDataSize+referenceDataSize%2) ) { std::cout << " Failed" << std::endl << " pixel (" @@ -505,19 +555,25 @@ int InternalTest(std::string const &filename, << " Image size: (" << tested->GetFile()->GetXSize() << "," << tested->GetFile()->GetYSize() << "," - << tested->GetFile()->GetZSize() << ")" + << tested->GetFile()->GetZSize() << ") nb of scalar components " + << tested->GetFile()->GetNumberOfScalarComponents() << std::endl; - delete tested; + tested->Delete(); delete reference; - delete f; + f->Delete(); return 1; } // Test the data content - if (int res = memcmp(testedImageData, referenceImageData, - testedDataSize) != 0 ) + int length = tested->GetFile()->GetXSize()*tested->GetFile()->GetYSize()*tested->GetFile()->GetZSize() + *reference->GetScalarSize()*tested->GetFile()->GetNumberOfScalarComponents(); + + // *actual* image length may differ to 1 with Pixel Data Element length! + if (length != testedDataSize) + std::cout <<"--------------------length " << length << " != testedDataSize " << testedDataSize << std::endl; + if ( memcmp(testedImageData, referenceImageData, + length/*testedDataSize*/) != 0 ) { - (void)res; std::string ts = tested->GetFile()->GetTransferSyntax(); std::cout << " Failed" << std::endl @@ -526,7 +582,7 @@ int InternalTest(std::string const &filename, << ") differ (as expanded in memory)." << std::endl << " compression : " - << gdcm::Global::GetTS()->GetValue(ts) << std::endl; + << GDCM_NAME_SPACE::Global::GetTS()->GetValue(ts) << std::endl; std::cout << " list of the first " << MAX_NUMBER_OF_DIFFERENCE << " pixels differing (pos : test - ref) :" @@ -546,16 +602,16 @@ int InternalTest(std::string const &filename, } std::cout << std::endl; - delete tested; + tested->Delete(); delete reference; - delete f; + f->Delete(); return 1; } //////////////// Clean up: - delete tested; + tested->Delete(); delete reference; - delete f; + f->Delete(); std::cout << "OK." << std::endl; @@ -564,8 +620,11 @@ int InternalTest(std::string const &filename, int TestAllReadCompareDicom(int argc, char *argv[]) { +// Temporarily added, to track BigEndian troubles +GDCM_NAME_SPACE::Debug::WarningOn(); + if (argc == 4) - gdcm::Debug::DebugOn(); + GDCM_NAME_SPACE::Debug::DebugOn(); if ( argc >= 3 ) { @@ -599,14 +658,14 @@ int TestAllReadCompareDicom(int argc, char *argv[]) << std::endl << " special internal file format containing the" << std::endl - << " caracteristic of the image and the pixel datas " + << " caracteristic of the image and the pixel data " << "(uncompressed). This file is written if it's not found." << std::endl; std::cout << " step 3: compare the DICOM image with the reference image" << std::endl << " (.tst file). The test is made on the caracteristics" << std::endl - << " of the image and the pixel datas" + << " of the image and the pixel data" << std::endl << std::endl; int i = 0; @@ -618,7 +677,7 @@ int TestAllReadCompareDicom(int argc, char *argv[]) std::string baseLineDir = GDCM_DATA_ROOT; baseLineDir += "/BaselineDicom"; - if( !gdcm::DirList::IsDirectory(baseLineDir) ) + if( !GDCM_NAME_SPACE::DirList::IsDirectory(baseLineDir) ) { std::cerr << " The reference baseline directory " << std::endl << " " @@ -628,6 +687,11 @@ int TestAllReadCompareDicom(int argc, char *argv[]) return 1; } +//if (gdcmDataImages[i] == "D_CLUNIE_CT2_RLE.dcm") +// GDCM_NAME_SPACE::Debug::DebugOn(); // track pb on BigEndian Proc +//else + GDCM_NAME_SPACE::Debug::DebugOff(); + ////// Step 1 (see above description): std::string filename = GDCM_DATA_ROOT; filename += "/";