- // Number of Bits actually used
- std::string str_nbu = Header->GetEntryByNumber(0x0028,0x0101);
- if ( str_nbu == GDCM_UNFOUND )
- {
- nbu = nb;
- }
- else
- {
- nbu = atoi( str_nbu.c_str() );
- }
-
- // High Bit Position
- std::string str_highBit = Header->GetEntryByNumber(0x0028,0x0102);
- if ( str_highBit == GDCM_UNFOUND )
- {
- highBit = nb - 1;
- }
- else
- {
- highBit = atoi( str_highBit.c_str() );
- }
-
- // Pixel sign
- // 0 = Unsigned
- // 1 = Signed
- std::string str_sign = Header->GetEntryByNumber(0x0028,0x0103);
- if ( str_sign == GDCM_UNFOUND )
- {
- sign = 0; // default is unsigned
- }
- else
- {
- sign = atoi( str_sign.c_str() );
- }
-
- // re arange bytes inside the integer (processor endianity)
- if ( nb != 8 )
- {
- SwapZone(destination, Header->GetSwapCode(), ImageDataSize, nb);
- }
-
- // to avoid pb with some xmedcon breakers images
- if ( nb == 16 && nbu < nb && sign == 0)
- {
- int l = (int)(ImageDataSize / (nb/8));
- uint16_t *deb = (uint16_t *)destination;
- for(int i = 0; i<l; i++)
- {
- if( *deb == 0xffff )
- {
- *deb = 0;
- }
- deb++;
- }
- }
-
- // re arange bits inside the bytes
- if ( nbu != nb )
- {
- int l = (int)(ImageDataSize / (nb/8));
- if ( nb == 16 )
- {
- uint16_t mask = 0xffff;
- mask = mask >> (nb-nbu);
- uint16_t *deb = (uint16_t *)destination;
- for(int i = 0; i<l; i++)
- {
- *deb = (*deb >> (nbu - highBit - 1)) & mask;
- deb++;
- }
- }
- else if ( nb == 32 )
- {
- uint32_t mask = 0xffffffff;
- mask = mask >> (nb - nbu);
- uint32_t *deb = (uint32_t *)destination;
- for(int i = 0; i<l; i++)
- {
- *deb = (*deb >> (nbu - highBit - 1)) & mask;
- deb++;
- }
- }
- else
- {
- dbg.Verbose(0, "gdcmFile::GetImageDataIntoVector: weird image");
- return 0;
- }
- }
-// DO NOT remove this code commented out.
-// Nobody knows what's expecting you ...
-// Just to 'see' what was actually read on disk :-(
-
-// FILE * f2;
-// f2 = fopen("SpuriousFile.RAW","wb");
-// fwrite(destination,ImageDataSize,1,f2);
-// fclose(f2);
-
- // Deal with the color
- // -------------------
-
- std::string str_PhotometricInterpretation =
- Header->GetEntryByNumber(0x0028,0x0004);
-
- if ( str_PhotometricInterpretation == "MONOCHROME1 "
- || str_PhotometricInterpretation == "MONOCHROME2 " )
- {
- 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 = Header->GetPlanarConfiguration(); // 0028,0006
-
- // Whatever Planar Configuration is,
- // "PALETTE COLOR " implies that we deal with the palette.
- if ( str_PhotometricInterpretation == "PALETTE COLOR ")
- {
- planConf = 2;
- }
-
- switch ( planConf )
- {
- case 0:
- // Pixels are already RGB
- break;
- case 1:
- if (str_PhotometricInterpretation == "YBR_FULL")
- {
- // Warning : YBR_FULL_422 acts as RGB
- // : we need to make RGB Pixels from Planes Y,cB,cR
-
- // to see the tricks about YBR_FULL, YBR_FULL_422,
- // YBR_PARTIAL_422, YBR_ICT, YBR_RCT have a look at :
- // ftp://medical.nema.org/medical/dicom/final/sup61_ft.pdf
- // and be *very* affraid
- //
- int l = Header->GetXSize() * Header->GetYSize();
- int nbFrames = Header->GetZSize();
-
- uint8_t* newDest = new uint8_t[ImageDataSize];
- uint8_t* x = newDest;
- uint8_t* a = (uint8_t*)destination;
- uint8_t* b = a + l;
- uint8_t* c = b + l;
- double R,G,B;
-
- /// \todo : Replace by the 'well known' integer computation
- /// counterpart
- /// see http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf
- /// for code optimisation
-
- for (int i = 0; i < nbFrames; i++)
- {
- for (int j = 0; j < l; j++)
- {
- R = 1.164 *(*a-16) + 1.596 *(*c -128) + 0.5;
- G = 1.164 *(*a-16) - 0.813 *(*c -128) - 0.392 *(*b -128) + 0.5;
- B = 1.164 *(*a-16) + 2.017 *(*b -128) + 0.5;
-
- if (R < 0.0) R = 0.0;
- if (G < 0.0) G = 0.0;
- if (B < 0.0) B = 0.0;
- if (R > 255.0) R = 255.0;
- if (G > 255.0) G = 255.0;
- if (B > 255.0) B = 255.0;
-
- *(x++) = (uint8_t)R;
- *(x++) = (uint8_t)G;
- *(x++) = (uint8_t)B;
- a++; b++; c++;
- }
- }
- memmove(destination, newDest, ImageDataSize);
- delete[] newDest;
- }
- else
- {
- // need to make RGB Pixels from R,G,B Planes
- // (all the Frames at a time)
-
- int l = Header->GetXSize() * Header->GetYSize() * Header->GetZSize();
-
- uint8_t *newDest = new uint8_t[ImageDataSize];
- uint8_t *x = newDest;
- uint8_t *a = (uint8_t *)destination;
- uint8_t *b = a + l;
- uint8_t *c = b + l;
-
- for (int j = 0; j < l; j++)
- {
- *(x++) = *(a++);
- *(x++) = *(b++);
- *(x++) = *(c++);
- }
- memmove(destination, newDest, ImageDataSize);
- delete[] newDest;
- }
- break;
- case 2:
- // Palettes were found
- // Let the user deal with them !
- return ImageDataSize;
- }