From: frog Date: Wed, 13 Oct 2004 14:15:28 +0000 (+0000) Subject: * Doc/Website/MailingList.html added (Sidebar.html changed accordingly). X-Git-Tag: Version0.6.bp~78 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=4672e071f29ed17f7258b27e40d47642abfbb53f;p=gdcm.git * Doc/Website/MailingList.html added (Sidebar.html changed accordingly). * gdcmPython/gdcm.i: fix for compilation of wrappers (Note: %include order matters, as stated in warning note at begining of %include section). * src/gdcmDicomDir*.[cxx|h]: coding style * src/gdcmDocument.h: doxygen \ref seems uncompatible with \todo. * src/gdcmJpeg8.cxx: doxygen fix. * CLEANUP_ROUND (12) for gdcmPixelConvert (seing the ligth stage) src/gdcmFile.[cxx|h] and gdcmPixelConvert.[cxx|h]: color handling moved from File:: to PixelConvert::. --- diff --git a/ChangeLog b/ChangeLog index 8e7d99fc..3339fbb7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2004-10-13 Eric Boix + * Doc/Website/MailingList.html added (Sidebar.html changed accordingly). + * gdcmPython/gdcm.i: fix for compilation of wrappers (Note: %include order + matters, as stated in warning note at begining of %include section). + * src/gdcmDicomDir*.[cxx|h]: coding style + * src/gdcmDocument.h: doxygen \ref seems uncompatible with \todo. + * src/gdcmJpeg8.cxx: doxygen fix. + * CLEANUP_ROUND (12) for gdcmPixelConvert (seing the ligth stage) + src/gdcmFile.[cxx|h] and gdcmPixelConvert.[cxx|h]: color handling moved + from File:: to PixelConvert::. + 2004-10-12 Eric Boix * CLEANUP_ROUND (11) for gdcmPixelConvert (cafeine is my friend stage) src/gdcmFile.[cxx|h] and gdcmPixelConvert.[cxx|h]: diff --git a/Doc/Website/MailingList.html b/Doc/Website/MailingList.html new file mode 100644 index 00000000..a548b0fd --- /dev/null +++ b/Doc/Website/MailingList.html @@ -0,0 +1,42 @@ + + + + + Gdcm mailing list + + + + + +

+ Gdcm mailing list +

+
+ + +The + +gdcm mailing list +has currently two flaws (unitl we fix that) +
    +
  • it is awkwardly named + Dcmlib@creatis.insa-lyon.fr + (i.e. Dcmlib as opposed to the expected gdcm), +
  • +
  • since the developpers are mainly french (sorry) the + + archives are in french (sorry again). But if you post + a question in english we'll promiss to answer in basic english ! +
  • +
+ +Gdcm mailing list web page +allows you subscribe and/or to perform any administrative task on this +mailing list. +
+ + +
+ + + diff --git a/Doc/Website/Main.html b/Doc/Website/Main.html index 42dfebdb..cdb7fb58 100644 --- a/Doc/Website/Main.html +++ b/Doc/Website/Main.html @@ -107,7 +107,9 @@ Gdcm also still needs
  • the python wrappers to be fixed,
  • -
  • a simple wxWdiget Dicom file editor. +
  • a simple + wxWidgets + Dicom file editor.
  • diff --git a/Doc/Website/Sidebar.html b/Doc/Website/Sidebar.html index 91a29910..9e502b3c 100644 --- a/Doc/Website/Sidebar.html +++ b/Doc/Website/Sidebar.html @@ -80,6 +80,12 @@ + + + Mailing list + + diff --git a/gdcmPython/gdcm.i b/gdcmPython/gdcm.i index cdd38532..27a7b02a 100644 --- a/gdcmPython/gdcm.i +++ b/gdcmPython/gdcm.i @@ -236,11 +236,12 @@ typedef unsigned int guint32; %include "gdcmTS.h" %include "gdcmVR.h" %include "gdcmSQItem.h" +%include "gdcmDicomDirElement.h" %include "gdcmDicomDirObject.h" +%include "gdcmDicomDirImage.h" +%include "gdcmDicomDirSerie.h" %include "gdcmDicomDirStudy.h" %include "gdcmDicomDirPatient.h" -%include "gdcmDicomDirSerie.h" -%include "gdcmDicomDirElement.h" %include "gdcmDicomDirMeta.h" %include "gdcmDocument.h" %include "gdcmHeader.h" @@ -249,5 +250,3 @@ typedef unsigned int guint32; %include "gdcmUtil.h" %include "gdcmGlobal.h" %include "gdcmDicomDir.h" -%include "gdcmDicomDirElement.h" -%include "gdcmDicomDirImage.h" diff --git a/src/gdcmDebug.cxx b/src/gdcmDebug.cxx index a2e8f3d3..ffa95ed3 100644 --- a/src/gdcmDebug.cxx +++ b/src/gdcmDebug.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDebug.cxx,v $ Language: C++ - Date: $Date: 2004/10/12 04:35:44 $ - Version: $Revision: 1.8 $ + Date: $Date: 2004/10/13 14:15:29 $ + 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 @@ -53,7 +53,7 @@ void Debug::Verbose(int level, const char * msg1, const char * msg2) { return ; } - std::cerr << msg1 << ' ' << msg2 << std::endl; + std::cerr << "gdcm::" << msg1 << ' ' << msg2 << std::endl; } /** @@ -68,7 +68,7 @@ void Debug::Error(bool test, const char * msg1, const char * msg2) { return; } - std::cerr << msg1 << ' ' << msg2 << std::endl; + std::cerr << "gdcm::" << msg1 << ' ' << msg2 << std::endl; Exit(1); } @@ -81,7 +81,7 @@ void Debug::Error(bool test, const char * msg1, const char * msg2) void Debug::Error(const char* msg1, const char* msg2, const char* msg3) { - std::cerr << msg1 << ' ' << msg2 << ' ' << msg3 << std::endl; + std::cerr << "gdcm::" << msg1 << ' ' << msg2 << ' ' << msg3 << std::endl; Exit(1); } @@ -101,7 +101,7 @@ void Debug::Assert(int level, bool test, const char * msg1, } if (!test) { - std::cerr << msg1 << ' ' << msg2 << std::endl; + std::cerr << "gdcm::" << msg1 << ' ' << msg2 << std::endl; } } diff --git a/src/gdcmDicomDirElement.h b/src/gdcmDicomDirElement.h index 551ca61e..b744729d 100644 --- a/src/gdcmDicomDirElement.h +++ b/src/gdcmDicomDirElement.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDicomDirElement.h,v $ Language: C++ - Date: $Date: 2004/10/12 04:35:44 $ - Version: $Revision: 1.12 $ + Date: $Date: 2004/10/13 14:15:29 $ + Version: $Revision: 1.13 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -66,7 +66,7 @@ public: * \brief returns a reference to the chained List * related to the META Elements of a DICOMDIR. */ - ListDicomDirMetaElem &GetDicomDirMetaElements() + ListDicomDirMetaElem& GetDicomDirMetaElements() { return DicomDirMetaList; }; /** diff --git a/src/gdcmDicomDirObject.cxx b/src/gdcmDicomDirObject.cxx index bf3ff5ec..0a623225 100644 --- a/src/gdcmDicomDirObject.cxx +++ b/src/gdcmDicomDirObject.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDicomDirObject.cxx,v $ Language: C++ - Date: $Date: 2004/10/12 04:35:45 $ - Version: $Revision: 1.4 $ + Date: $Date: 2004/10/13 14:15:29 $ + 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 @@ -79,7 +79,7 @@ TagDocEntryHT DicomDirObject::GetEntry() * \brief add the 'Object' related Dicom Elements to the listEntries * of a partially created DICOMDIR */ -void DicomDirObject::FillObject(std::list elemList) +void DicomDirObject::FillObject(ListDicomDirMetaElem elemList) { // FillObject rempli le SQItem qui sera accroche au bon endroit diff --git a/src/gdcmDicomDirObject.h b/src/gdcmDicomDirObject.h index 9695adaa..c3d014a6 100644 --- a/src/gdcmDicomDirObject.h +++ b/src/gdcmDicomDirObject.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDicomDirObject.h,v $ Language: C++ - Date: $Date: 2004/10/12 04:35:45 $ - Version: $Revision: 1.4 $ + Date: $Date: 2004/10/13 14:15:29 $ + 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 @@ -50,7 +50,7 @@ public: void SetPrintLevel(int level) { PrintLevel = level; }; TagDocEntryHT GetEntry(); - void FillObject(std::list elemList); + void FillObject(ListDicomDirMetaElem elemList); protected: diff --git a/src/gdcmDicomDirSerie.h b/src/gdcmDicomDirSerie.h index 8e26cff3..8e73240d 100644 --- a/src/gdcmDicomDirSerie.h +++ b/src/gdcmDicomDirSerie.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDicomDirSerie.h,v $ Language: C++ - Date: $Date: 2004/10/12 04:35:45 $ - Version: $Revision: 1.10 $ + Date: $Date: 2004/10/13 14:15:29 $ + Version: $Revision: 1.11 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -31,18 +31,18 @@ typedef std::list ListDicomDirImage; class GDCM_EXPORT DicomDirSerie : public DicomDirObject { public: - DicomDirSerie(SQItem *s, TagDocEntryHT *ptagHT); - DicomDirSerie(TagDocEntryHT *ptagHT); + DicomDirSerie( SQItem* s, TagDocEntryHT* ptagHT ); + DicomDirSerie( TagDocEntryHT* ptagHT ); ~DicomDirSerie(); - virtual void Print(std::ostream &os = std::cout); - virtual void Write(FILE *fp, FileType t); + virtual void Print( std::ostream& os = std::cout ); + virtual void Write( FILE* fp, FileType t ); /** * \ingroup DicomDirSerie * \brief returns the IMAGE chained List for this SERIE. */ - ListDicomDirImage &GetDicomDirImages() { return images; }; + ListDicomDirImage& GetDicomDirImages() { return images; }; /** * \ingroup DicomDirSerie * \brief adds the passed IMAGE to the IMAGE chained List for this SERIE. diff --git a/src/gdcmDocEntry.h b/src/gdcmDocEntry.h index e3ea3ccf..d48d9bef 100644 --- a/src/gdcmDocEntry.h +++ b/src/gdcmDocEntry.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocEntry.h,v $ Language: C++ - Date: $Date: 2004/10/12 04:35:45 $ - Version: $Revision: 1.25 $ + Date: $Date: 2004/10/13 14:15:29 $ + Version: $Revision: 1.26 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -33,7 +33,6 @@ namespace gdcm //----------------------------------------------------------------------------- /** - * \ingroup DocEntry * \brief The dicom header of a Dicom file contains a set of such entries * (when successfuly parsed against a given Dicom dictionary) */ diff --git a/src/gdcmDocument.h b/src/gdcmDocument.h index a024bdef..657fe8c2 100644 --- a/src/gdcmDocument.h +++ b/src/gdcmDocument.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmDocument.h,v $ Language: C++ - Date: $Date: 2004/10/12 04:35:45 $ - Version: $Revision: 1.50 $ + Date: $Date: 2004/10/13 14:15:29 $ + Version: $Revision: 1.51 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -90,8 +90,8 @@ protected: /// \brief Elements whose value is longer than MAX_SIZE_PRINT_ELEMENT_VALUE /// are NOT printed. /// \todo Currently not used since collides with #define in - /// \ref DocEntry.cxx. See also - /// \ref Document::SetMaxSizePrintEntry() + /// class DocEntry . See also + /// method ref Document::SetMaxSizePrintEntry() static const unsigned int MAX_SIZE_PRINT_ELEMENT_VALUE; /// Store the RLE frames info obtained during parsing of pixels. diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index 78fcd420..10869d7a 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFile.cxx,v $ Language: C++ - Date: $Date: 2004/10/13 04:05:04 $ - Version: $Revision: 1.141 $ + Date: $Date: 2004/10/13 14:15:29 $ + Version: $Revision: 1.142 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -139,6 +139,12 @@ void File::Initialise() PixelConverter.SetRLEInfo( &(HeaderInternal->RLEInfo) ); PixelConverter.SetJPEGInfo( &(HeaderInternal->JPEGInfo) ); PixelConverter.SetDecompressedSize( ImageDataSize ); + + PixelConverter.SetPlanarConfiguration( + HeaderInternal->GetPlanarConfiguration() ); + PixelConverter.SetIsMonochrome( HeaderInternal->IsMonochrome() ); + PixelConverter.SetIsPaletteColor( HeaderInternal->IsPaletteColor() ); + PixelConverter.SetIsYBRFull( HeaderInternal->IsYBRFull() ); HeaderInternal->CloseFile(); @@ -537,7 +543,7 @@ uint8_t* File::GetImageDataRaw () * @return On success, the number of bytes actually copied. Zero on * failure e.g. MaxSize is lower than necessary. */ -size_t File::GetImageDataIntoVectorRaw (void* destination, size_t maxSize) +void File::GetImageDataIntoVectorRaw (void* destination, size_t maxSize) { // we save the initial values of the following // in order to be able to restore the header in a disk-consistent state @@ -554,74 +560,16 @@ size_t File::GetImageDataIntoVectorRaw (void* destination, size_t maxSize) { dbg.Verbose(0, "File::GetImageDataIntoVector: pixel data bigger" "than caller's expected MaxSize"); - return (size_t)0; + return; } 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; - DebugFile = fopen( "SpuriousFile.RAW", "wb" ); - fwrite( PixelConvertor.GetUncompressed(), - PixelConvertor.GetUncompressedsSize(), - 1, DebugFile ); - fclose( DebugFile ); -#endif //GDCM_DEBUG - -// SPLIT ME -////////////////////////////////// -// Deal with the color - - // Monochrome pictures don't require color intervention - if ( HeaderInternal->IsMonochrome() ) - { - return ImageDataSize; - } - - // Planar configuration = 0 : Pixels are already RGB - // Planar configuration = 1 : 3 planes : R, G, B - // Planar configuration = 2 : 1 gray Plane + 3 LUT - - // Well ... supposed to be ! - // See US-PAL-8-10x-echo.dcm: PlanarConfiguration=0, - // PhotometricInterpretation=PALETTE COLOR - // and heuristic has to be found :-( - - int planConf = HeaderInternal->GetPlanarConfiguration(); - - // Planar configuration = 2 ==> 1 gray Plane + 3 LUT - // ...and... - // whatever the Planar Configuration might be, "PALETTE COLOR " - // implies that we deal with the palette. - if ( ( planConf == 2 ) || HeaderInternal->IsPaletteColor() ) - { - return ImageDataSize; - } - - // When planConf is 0, pixels are allready in RGB - - if ( planConf == 1 ) + if ( ! PixelConverter.HandleColor( (uint8_t*)destination ) ) { - // Warning : YBR_FULL_422 acts as RGB - if ( HeaderInternal->IsYBRFull() ) - { - PixelConverter.ConvertYcBcRPlanesToRGBPixels( - (uint8_t*)destination, - ImageDataSize ); - } - else - { - PixelConverter.ConvertRGBPlanesToRGBPixels( - (uint8_t*)destination, - ImageDataSize ); - } - + return; } /////////////////////////////////////////////////// @@ -644,7 +592,7 @@ size_t File::GetImageDataIntoVectorRaw (void* destination, size_t maxSize) HeaderInternal->SetEntryByNumber(photInt,0x0028,0x0004); HeaderInternal->SetEntryByNumber(planConfig,0x0028,0x0006); - return ImageDataSize; + return; } /** diff --git a/src/gdcmFile.h b/src/gdcmFile.h index 31c51a35..eb430a8c 100644 --- a/src/gdcmFile.h +++ b/src/gdcmFile.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmFile.h,v $ Language: C++ - Date: $Date: 2004/10/12 09:59:45 $ - Version: $Revision: 1.61 $ + Date: $Date: 2004/10/13 14:15:30 $ + 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 @@ -35,7 +35,7 @@ namespace gdcm class GDCM_EXPORT File { public: - File( Header *header ); + File( Header* header ); File( std::string const& filename ); virtual ~File(); @@ -54,7 +54,7 @@ public: uint8_t* GetImageData(); size_t GetImageDataIntoVector(void* destination, size_t maxSize); uint8_t* GetImageDataRaw(); - size_t GetImageDataIntoVectorRaw(void* destination, size_t maxSize); + void GetImageDataIntoVectorRaw(void* destination, size_t maxSize); // see also Header::SetImageDataSize ?!? bool SetImageData (uint8_t* data, size_t expectedSize); diff --git a/src/gdcmJpeg8.cxx b/src/gdcmJpeg8.cxx index fab29603..4f146c2a 100644 --- a/src/gdcmJpeg8.cxx +++ b/src/gdcmJpeg8.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmJpeg8.cxx,v $ Language: C++ - Date: $Date: 2004/10/12 04:35:46 $ - Version: $Revision: 1.6 $ + Date: $Date: 2004/10/13 14:15:30 $ + 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 @@ -135,7 +135,7 @@ namespace gdcm * \brief routine for JPEG decompression * @param fp pointer to an already open file descriptor * 8 significant bits per pixel - * @param image_buffer Points to array (of R,G,B-order) data to compress + * @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_width Number of columns in image diff --git a/src/gdcmPixelConvert.cxx b/src/gdcmPixelConvert.cxx index dca4533c..0b6133cf 100644 --- a/src/gdcmPixelConvert.cxx +++ b/src/gdcmPixelConvert.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelConvert.cxx,v $ Language: C++ - Date: $Date: 2004/10/13 04:05:04 $ - Version: $Revision: 1.10 $ + Date: $Date: 2004/10/13 14:15:30 $ + Version: $Revision: 1.11 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -91,7 +91,7 @@ void PixelConvert::AllocateDecompressed() * \brief Read from file a 12 bits per pixel image and uncompress it * into a 16 bits per pixel image. */ -void PixelConvert::Decompress12BitsTo16Bits( +void PixelConvert::ReadAndDecompress12BitsTo16Bits( uint8_t* pixelZone, FILE* filePtr) throw ( FormatError ) @@ -107,21 +107,21 @@ void PixelConvert::Decompress12BitsTo16Bits( ItemRead = fread( &b0, 1, 1, filePtr); if ( ItemRead != 1 ) { - throw FormatError( "File::Decompress12BitsTo16Bits()", + throw FormatError( "File::ReadAndDecompress12BitsTo16Bits()", "Unfound first block" ); } ItemRead = fread( &b1, 1, 1, filePtr); if ( ItemRead != 1 ) { - throw FormatError( "File::Decompress12BitsTo16Bits()", + throw FormatError( "File::ReadAndDecompress12BitsTo16Bits()", "Unfound second block" ); } ItemRead = fread( &b2, 1, 1, filePtr); if ( ItemRead != 1 ) { - throw FormatError( "File::Decompress12BitsTo16Bits()", + throw FormatError( "File::ReadAndDecompress12BitsTo16Bits()", "Unfound second block" ); } @@ -457,8 +457,7 @@ bool PixelConvert::ReadAndDecompressJPEGFile( /** * \brief Re-arrange the bits within the bytes. - * @param fp already open File Pointer - * @param destination Where decompressed fragments should end up + * @param pixelZone zone * @return Boolean */ bool PixelConvert::ReArrangeBits( uint8_t* pixelZone ) @@ -503,12 +502,10 @@ bool PixelConvert::ReArrangeBits( uint8_t* pixelZone ) * \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 ) +void PixelConvert::ConvertYcBcRPlanesToRGBPixels( uint8_t* destination ) { - uint8_t* oldPixelZone = new uint8_t[ imageDataSize ]; - memmove( oldPixelZone, destination, imageDataSize ); + uint8_t* oldPixelZone = new uint8_t[ DecompressedSize ]; + memmove( oldPixelZone, destination, DecompressedSize ); // to see the tricks about YBR_FULL, YBR_FULL_422, // YBR_PARTIAL_422, YBR_ICT, YBR_RCT have a look at : @@ -558,12 +555,10 @@ void PixelConvert::ConvertYcBcRPlanesToRGBPixels( * \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 ) +void PixelConvert::ConvertRGBPlanesToRGBPixels( uint8_t* destination ) { - uint8_t* oldPixelZone = new uint8_t[ imageDataSize ]; - memmove( oldPixelZone, destination, imageDataSize ); + uint8_t* oldPixelZone = new uint8_t[ DecompressedSize ]; + memmove( oldPixelZone, destination, DecompressedSize ); int l = XSize * YSize * ZSize; @@ -582,44 +577,129 @@ void PixelConvert::ConvertRGBPlanesToRGBPixels( bool PixelConvert::ReadAndDecompressPixelData( void* destination, FILE* fp ) { + ////////////////////////////////////////////////// + //// First stage: get our hands on the Pixel Data. if ( !fp ) { + dbg.Verbose( 0, "PixelConvert::ReadAndDecompressPixelData: " + "unavailable file pointer." ); return false; } if ( fseek(fp, PixelOffset, SEEK_SET) == -1 ) { + dbg.Verbose( 0, "PixelConvert::ReadAndDecompressPixelData: " + "unable to find PixelOffset in file." ); return false; } + ////////////////////////////////////////////////// + //// Second stage: read from disk dans uncompress. if ( BitsAllocated == 12 ) { - Decompress12BitsTo16Bits( (uint8_t*)destination, fp); - return true; + ReadAndDecompress12BitsTo16Bits( (uint8_t*)destination, fp); } - - //////////// Decompressed File - if ( IsUncompressed ) + else if ( IsUncompressed ) { size_t ItemRead = fread( destination, PixelDataLength, 1, fp); if ( ItemRead != 1 ) { + dbg.Verbose( 0, "PixelConvert::ReadAndDecompressPixelData: " + "reading of uncompressed pixel data failed." ); return false; } - else + } + else if ( IsRLELossless ) + { + if ( ! ReadAndDecompressRLEFile( destination, fp ) ) { - return true; + dbg.Verbose( 0, "PixelConvert::ReadAndDecompressPixelData: " + "RLE decompressor failed." ); + return false; } } + else + { + // Default case concerns JPEG family + if ( ! ReadAndDecompressJPEGFile( (uint8_t*)destination, fp ) ) + { + dbg.Verbose( 0, "PixelConvert::ReadAndDecompressPixelData: " + "JPEG decompressor failed." ); + return false; + } + } + + //////////////////////////////////////////// + //// Third stage: twigle the bytes and bits. + ReorderEndianity( (uint8_t*) destination ); + ReArrangeBits( (uint8_t*) destination ); + +} + +bool PixelConvert::HandleColor( uint8_t* destination ) +{ + ////////////////////////////////// + // Deal with the color decoding i.e. handle: + // - R, G, B planes (as opposed to RGB pixels) + // - YBR (various) encodings. + // - LUT[s] (or "PALETTE COLOR"). + // + // The classification in the color decoding schema is based on the blending + // of two Dicom tags values: + // * "Photometric Interpretation" for which we have the cases: + // - [Photo A] MONOCHROME[1|2] pictures, + // - [Photo B] RGB or YBR_FULL_422 (which acts as RGB), + // - [Photo C] YBR_* (with the above exception of YBR_FULL_422) + // - [Photo D] "PALETTE COLOR" which indicates the presence of LUT[s]. + // * "Planar Configuration" for which we have the cases: + // - [Planar 0] 0 then Pixels are already RGB + // - [Planar 1] 1 then we have 3 planes : R, G, B, + // - [Planar 2] 2 then we have 1 gray Plane and 3 LUTs + // + // Now in theory, one could expect some coherence when blending the above + // cases. For example we should not encounter files belonging at the + // time to case [Planar 0] and case [Photo D]. + // Alas, this was only theory ! Because in practice some odd (read ill + // formated Dicom) files (e.g. gdcmData/US-PAL-8-10x-echo.dcm) we encounter: + // - "Planar Configuration" = 0, + // - "Photometric Interpretation" = "PALETTE COLOR". + // Hence gdcm shall use the folowing "heuristic" in order to be tolerant + // towards Dicom-non-conformance files: + // << whatever the "Planar Configuration" value might be, a + // "Photometric Interpretation" set to "PALETTE COLOR" forces + // a LUT intervention >> + // + // Now we are left with the following handling of the cases: + // - [Planar 0] OR [Photo A] no color decoding (since respectively + // Pixels are already RGB and monochrome pictures have no color :), + // - [Planar 1] AND [Photo B] handled with ConvertRGBPlanesToRGBPixels() + // - [Planar 1] AND [Photo C] handled with ConvertYcBcRPlanesToRGBPixels() + // - [Planar 2] OR [Photo D] requires LUT intervention. + + if ( IsMonochrome + || ( PlanarConfiguration == 2 ) + || IsPaletteColor ) + { + // [Planar 2] OR [Photo D]: LUT intervention done outside + return false; + } - ///////////// Run Length Encoding - if ( IsRLELossless ) + if ( PlanarConfiguration == 1 ) { - return ReadAndDecompressRLEFile( destination, fp ); + if ( IsYBRFull ) + { + // [Planar 1] AND [Photo C] (remember YBR_FULL_422 acts as RGB) + ConvertYcBcRPlanesToRGBPixels( (uint8_t*)destination ); + } + else + { + // [Planar 1] AND [Photo C] + ConvertRGBPlanesToRGBPixels( (uint8_t*)destination ); + } } - ///////////// SingleFrame/Multiframe JPEG Lossless/Lossy/2000 - return ReadAndDecompressJPEGFile( (uint8_t*)destination, fp ); + // When planarConf is 0, pixels are allready in RGB + return true; } void PixelConvert::ComputeDecompressedImageDataSize() @@ -627,7 +707,7 @@ 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() ) + // \ref ReadAndDecompress12BitsTo16Bits() ) if ( BitsAllocated == 12 ) { bitsAllocated = 16; @@ -639,3 +719,13 @@ void PixelConvert::ComputeDecompressedImageDataSize() } } // end namespace gdcm + +// NOTES on File internal calls +// User +// ---> GetImageData +// ---> GetImageDataIntoVector +// |---> GetImageDataIntoVectorRaw +// | lut intervention +// User +// ---> GetImageDataRaw +// ---> GetImageDataIntoVectorRaw diff --git a/src/gdcmPixelConvert.h b/src/gdcmPixelConvert.h index e0e2b818..9c67e06a 100644 --- a/src/gdcmPixelConvert.h +++ b/src/gdcmPixelConvert.h @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmPixelConvert.h,v $ Language: C++ - Date: $Date: 2004/10/12 09:59:45 $ - Version: $Revision: 1.7 $ + Date: $Date: 2004/10/13 14:15:30 $ + Version: $Revision: 1.8 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -54,13 +54,21 @@ friend class File; int PixelSize; bool PixelSign; int SwapCode; + bool IsUncompressed; bool IsJPEG2000; bool IsJPEGLossless; bool IsRLELossless; + RLEFramesInfo* RLEInfo; JPEGFragmentsInfo* JPEGInfo; - + + // For handling color stage + int PlanarConfiguration; + bool IsMonochrome; + bool IsPaletteColor; + bool IsYBRFull; + private: bool ReadAndUncompressRLEFragment( uint8_t* decodedZone, @@ -98,6 +106,13 @@ public: void SetJPEGInfo( JPEGFragmentsInfo* inJPEGFragmentsInfo ) { JPEGInfo = inJPEGFragmentsInfo; } + void SetPlanarConfiguration( size_t planarConfiguration ) + { PlanarConfiguration = planarConfiguration; } + void SetIsMonochrome( bool isMonochrome ) { IsMonochrome = isMonochrome; } + void SetIsPaletteColor( bool isPaletteColor ) + { IsPaletteColor = isPaletteColor; } + void SetIsYBRFull( bool isYBRFull ) { IsYBRFull = isYBRFull; } + uint8_t* GetRGB() { return RGB; } void SetRGBSize( size_t size ) { RGBSize = size; } size_t GetRGBSize() { return RGBSize; } @@ -115,22 +130,19 @@ private: int NumberOfFrames, uint8_t* fixMemUncompressed ); void ComputeDecompressedImageDataSize(); - void Decompress12BitsTo16Bits( + void ReadAndDecompress12BitsTo16Bits( uint8_t* pixelZone, FILE* filePtr) throw ( FormatError ); 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, - size_t imageDataSize ); - void ConvertYcBcRPlanesToRGBPixels( - uint8_t* destination, - size_t imageDataSize ); - bool ReadAndDecompressPixelData( void* destination, FILE* fp ); + void ConvertRGBPlanesToRGBPixels( uint8_t* destination ); + void ConvertYcBcRPlanesToRGBPixels( uint8_t* destination ); +public: + bool ReadAndDecompressPixelData( void* destination, FILE* fp ); + bool HandleColor( uint8_t* destination ); void Squeeze(); }; } // end namespace gdcm