X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmFile.cxx;h=69fba75867b02e30d7db4318657454647e97c8d6;hb=f3985ba6c7bb644767b1f190d6c679b71a281582;hp=af62cd8f545a8856958298eca0e2e1668bb5b47c;hpb=33413fc6fb41f4fd7efbce32083f943f252e8b6f;p=gdcm.git diff --git a/src/gdcmFile.cxx b/src/gdcmFile.cxx index af62cd8f..69fba758 100644 --- a/src/gdcmFile.cxx +++ b/src/gdcmFile.cxx @@ -2,7 +2,6 @@ #include "gdcmFile.h" #include "gdcmUtil.h" -#include "iddcmjpeg.h" // for the 'LibIDO' Jpeg LossLess #include "jpeg/ljpg/jpegless.h" ///////////////////////////////////////////////////////////////// @@ -40,17 +39,16 @@ gdcmFile::gdcmFile(const char * filename) /** * \ingroup gdcmFile * \brief calcule la longueur (in bytes) A ALLOUER pour recevoir les - * pixels de l'image - * ou DES images dans le cas d'un multiframe - * ATTENTION : il ne s'agit PAS de la longueur du groupe des Pixels - * (dans le cas d'images compressees, elle n'a pas de sens). + * pixels de l'image ou DES images dans le cas d'un multiframe + * + * ATTENTION : il ne s'agit PAS de la longueur du groupe des Pixels + * (dans le cas d'images compressees, elle n'a pas de sens). * * @return longueur a allouer */ void gdcmFile::SetPixelDataSizeFromHeader(void) { int nb; std::string str_nb; - str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100); if (str_nb == GDCM_UNFOUND ) { nb = 16; @@ -58,12 +56,19 @@ void gdcmFile::SetPixelDataSizeFromHeader(void) { nb = atoi(str_nb.c_str() ); if (nb == 12) nb =16; } - lgrTotale = GetXSize() * GetYSize() * GetZSize() * (nb/8)* GetSamplesPerPixel(); - std::string str_PhotometricInterpretation = gdcmHeader::GetPubElValByNumber(0x0028,0x0004); - if ( str_PhotometricInterpretation == "PALETTE COLOR " ) { + lgrTotale = lgrTotaleRaw = GetXSize() * GetYSize() * GetZSize() + * (nb/8)* GetSamplesPerPixel(); + std::string str_PhotometricInterpretation = + gdcmHeader::GetPubElValByNumber(0x0028,0x0004); + + /*if ( str_PhotometricInterpretation == "PALETTE COLOR " )*/ + // pb when undealt Segmented Palette Color + + if (HasLUT()) { lgrTotale*=3; } } + // see PS 3.3-2003 : C.7.6.3.2.1 // // MONOCHROME1 @@ -85,17 +90,27 @@ void gdcmFile::SetPixelDataSizeFromHeader(void) { // 0028|1222 [OW] [Segmented Green Palette Color Lookup Table Data] // 0028|1223 [OW] [Segmented Blue Palette Color Lookup Table Data] - // ex : US-PAL-8-10x-echo.dcm, 8BitsRunLengthColor.dcm - // 0028|1201 [OW] [Red Palette Color Lookup Table Data] - // 0028|1202 [OW] [Green Palette Color Lookup Table Data] - // 0028|1203 [OW] [Blue Palette Color Lookup Table Data] - // ex : OT-PAL-8-face.dcm // 0028|1201 [US] [Red Palette Color Lookup Table Data] // 0028|1202 [US] [Green Palette Color Lookup Table Data] // 0028|1203 [US] [Blue Palette Color Lookup Table Data] +///////////////////////////////////////////////////////////////// +/** + * \ingroup gdcmFile + * \brief Returns the size (in bytes) of required memory to hold + * \ the pixel data represented in this file, when user DOESN'T want + * \ to get RGB pixels image when it's stored as a PALETTE COLOR image + * \ - the (vtk) user is supposed to know how deal with LUTs - + * \ warning to be used with GetImagePixelsRaw() + * @return The size of pixel data in bytes. + */ + +size_t gdcmFile::GetImageDataSizeRaw(void) { + return (lgrTotaleRaw); +} + ///////////////////////////////////////////////////////////////// /** * \ingroup gdcmFile @@ -126,8 +141,9 @@ bool gdcmFile::ReadPixelData(void* destination) { CloseFile(); return false; } + -// ------------------------- Compacted File (12 Bits Per Pixel) + // ---------------------- Compacted File (12 Bits Per Pixel) /* unpack 12 Bits pixels into 16 Bits pixels */ /* 2 pixels 12bit = [0xABCDEF] */ @@ -137,32 +153,32 @@ bool gdcmFile::ReadPixelData(void* destination) { int nbPixels = GetXSize()*GetYSize(); unsigned char b0, b1, b2; + unsigned short int* pdestination = (unsigned short int*)destination; for(int p=0;p> 4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f); + //Two steps is necessary to please VC++ + *pdestination++ = ((b0 >> 4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f); /* A */ /* B */ /* D */ - *((unsigned short int*)destination)++ = - ((b2 & 0x0f) << 8) + ((b1 >> 4) << 4) + (b2 >> 4); + *pdestination++ = ((b2 & 0x0f) << 8) + ((b1 >> 4) << 4) + (b2 >> 4); /* F */ /* C */ /* E */ // Troubles expected on Big-Endian processors ? } return(true); - } - + } -// ------------------------- Uncompressed File + // ---------------------- Uncompressed File if ( !IsDicomV3() || IsImplicitVRLittleEndianTransferSyntax() || IsExplicitVRLittleEndianTransferSyntax() || IsExplicitVRBigEndianTransferSyntax() || - IsDeflatedExplicitVRLittleEndianTransferSyntax() ) { - - size_t ItemRead = fread(destination, lgrTotale, 1, fp); + IsDeflatedExplicitVRLittleEndianTransferSyntax() ) { + + size_t ItemRead = fread(destination, GetPixelAreaLength(), 1, fp); + if ( ItemRead != 1 ) { CloseFile(); return false; @@ -172,17 +188,14 @@ bool gdcmFile::ReadPixelData(void* destination) { } } - -// ------------------------- Run Length Encoding + // ---------------------- Run Length Encoding if (gdcmHeader::IsRLELossLessTransferSyntax()) { int res = (bool)gdcm_read_RLE_file (destination); return res; } - - -// ----------------- SingleFrame/Multiframe JPEG Lossless/Lossy/2000 + // --------------- SingleFrame/Multiframe JPEG Lossless/Lossy/2000 int nb; std::string str_nb=gdcmHeader::GetPubElValByNumber(0x0028,0x0100); @@ -292,6 +305,9 @@ bool gdcmFile::ReadPixelData(void* destination) { * \ingroup gdcmFile * \brief Allocates necessary memory, copies the pixel data * (image[s]/volume[s]) to newly allocated zone. + * Transforms YBR pixels into RGB pixels if any + Transforms 3 planes R, G, B into a single RGB Plane + Transforms single Grey plane + 3 Palettes into a RGB Plane * @return Pointer to newly allocated pixel data. * \ NULL if alloc fails */ @@ -302,10 +318,40 @@ void * gdcmFile::GetImageData (void) { return(PixelData); } +/** + * \ingroup gdcmFile + * \brief Allocates necessary memory, copies the pixel data + * (image[s]/volume[s]) to newly allocated zone. + * Transforms YBR pixels into RGB pixels if any + Transforms 3 planes R, G, B into a single RGB Plane + DOES NOT transform Grey plane + 3 Palettes into a RGB Plane + * @return Pointer to newly allocated pixel data. + * \ NULL if alloc fails + */ +void * gdcmFile::GetImageDataRaw (void) { + if (HasLUT()) + lgrTotale /= 3; // TODO Let gdcmHeadar user a chance + // to get the right value + // Create a member lgrTotaleRaw ??? + PixelData = (void *) malloc(lgrTotale); + if (PixelData) + GetImageDataIntoVectorRaw(PixelData, lgrTotale); + return(PixelData); +} + /** * \ingroup gdcmFile * \brief Copies at most MaxSize bytes of pixel data to caller's * memory space. + * \warning This function was designed to avoid people that want to build + * a volume from an image stack to need first to get the image pixels + * and then move them to the volume area. + * It's absolutely useless for any VTK user since vtk chooses + * to invert the lines of an image, that is the last line comes first + * (for some axis related reasons?). Hence he will have + * to load the image line by line, starting from the end. + * VTK users have to call GetImageData + * * @param destination Address (in caller's memory space) at which the * pixel data should be copied * @param MaxSize Maximum number of bytes to be copied. When MaxSize @@ -317,6 +363,92 @@ void * gdcmFile::GetImageData (void) { size_t gdcmFile::GetImageDataIntoVector (void* destination, size_t MaxSize) { + size_t l = GetImageDataIntoVectorRaw (destination, MaxSize); + + if (!HasLUT()) + return lgrTotale; + + // from Lut R + Lut G + Lut B + + unsigned char * newDest = (unsigned char *)malloc(lgrTotale); + unsigned char * a = (unsigned char *)destination; + unsigned char * lutRGBA = GetLUTRGBA(); + if (lutRGBA) { + int l = lgrTotaleRaw; + memmove(newDest, destination, l);// move Gray pixels to temp area + int j; + for (int i=0;i