-/**
- * \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 hace to call GetImageData
- * \warning DOES NOT transform the Grey Plane + Palette Color (if any)
- * into a single RGB Pixels Plane
- * the (VTK) user will manage the palettes
- *
- * @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
- * is not sufficient to hold the pixel data the copy is not
- * executed (i.e. no partial copy).
- * @return On success, the number of bytes actually copied. Zero on
- * failure e.g. MaxSize is lower than necessary.
- */
-size_t gdcmFile::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
- // (if user asks twice to get the pixels from disk)
-
- if ( PixelRead != -1 ) // File was "read" before
- {
- RestoreInitialValues();
- }
-
- PixelRead = 1 ; // PixelRaw
-
- if ( ImageDataSize > maxSize )
- {
- dbg.Verbose(0, "gdcmFile::GetImageDataIntoVector: pixel data bigger"
- "than caller's expected MaxSize");
- return (size_t)0;
- }
-
- ReadPixelData( destination );
-
- // Number of Bits Allocated for storing a Pixel
- int numberBitsAllocated = Header->GetBitsAllocated();
- if ( numberBitsAllocated == 0 )
- {
- numberBitsAllocated = 16;
- }
-
- // Number of Bits actually used
- int numberBitsStored = Header->GetBitsStored();
- if ( numberBitsStored == 0 )
- {
- numberBitsStored = numberBitsAllocated;
- }
-
- // High Bit Position
- int highBitPosition = Header->GetHighBitPosition();
- if ( highBitPosition == 0 )
- {
- highBitPosition = numberBitsAllocated - 1;
- }
-
- bool signedPixel = Header->IsSignedPixelData();
-
- ConvertReorderEndianity( (uint8_t*) destination,
- ImageDataSize,
- numberBitsStored,
- numberBitsAllocated,
- signedPixel );
-
- ConvertReArrangeBits( (uint8_t*) destination,
- ImageDataSize,
- numberBitsStored,
- numberBitsAllocated,
- highBitPosition );
-
-#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 ( Header->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 = Header->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 ) || Header->IsPaletteColor() )
- {
- return ImageDataSize;
- }
-
- // When planConf is 0, pixels are allready in RGB
-
- if ( planConf == 1 )
- {
- uint8_t* newDest = new uint8_t[ImageDataSize];
- // Warning : YBR_FULL_422 acts as RGB
- if ( Header->IsYBRFull() )
- {
- ConvertYcBcRPlanesToRGBPixels((uint8_t*)destination, newDest);
- }
- else
- {
- ConvertRGBPlanesToRGBPixels((uint8_t*)destination, newDest);
- }
- memmove(destination, newDest, ImageDataSize);
- delete[] newDest;
- }
-
-///////////////////////////////////////////////////
- // now, it's an RGB image
- // Lets's write it in the Header
-
- // Droping Palette Color out of the Header
- // has been moved to the Write process.
-
- // TODO : move 'values' modification to the write process
- // : save also (in order to be able to restore)
- // : 'high bit' -when not equal to 'bits stored' + 1
- // : 'bits allocated', when it's equal to 12 ?!
-
- std::string spp = "3"; // Samples Per Pixel
- std::string photInt = "RGB "; // Photometric Interpretation
- std::string planConfig = "0"; // Planar Configuration
-
- Header->SetEntryByNumber(spp,0x0028,0x0002);
- Header->SetEntryByNumber(photInt,0x0028,0x0004);
- Header->SetEntryByNumber(planConfig,0x0028,0x0006);
-
- return ImageDataSize;
-}
-
-/**
- * \brief Re-arrange the bits within the bytes.
- */
-void gdcmFile::ConvertReArrangeBits( uint8_t* pixelZone,
- size_t imageDataSize,
- int numberBitsStored,
- int numberBitsAllocated,
- int highBitPosition)
- throw ( gdcmFormatError )
-{
- if ( numberBitsStored != numberBitsAllocated )
- {
- int l = (int)(imageDataSize / (numberBitsAllocated/8));
- if ( numberBitsAllocated == 16 )
- {
- uint16_t mask = 0xffff;
- mask = mask >> ( numberBitsAllocated - numberBitsStored );
- uint16_t* deb = (uint16_t*)pixelZone;
- for(int i = 0; i<l; i++)
- {
- *deb = (*deb >> (numberBitsStored - highBitPosition - 1)) & mask;
- deb++;
- }
- }
- else if ( numberBitsAllocated == 32 )
- {
- uint32_t mask = 0xffffffff;
- mask = mask >> ( numberBitsAllocated - numberBitsStored );
- uint32_t* deb = (uint32_t*)pixelZone;
- for(int i = 0; i<l; i++)
- {
- *deb = (*deb >> (numberBitsStored - highBitPosition - 1)) & mask;
- deb++;
- }
- }
- else
- {
- dbg.Verbose(0, "gdcmFile::ConvertReArrangeBits: weird image");
- throw gdcmFormatError( "gdcmFile::ConvertReArrangeBits()",
- "weird image !?" );
- }
- }
-}
-
-/**
- * \brief Deal with endianity i.e. re-arange bytes inside the integer
- */
-void gdcmFile::ConvertReorderEndianity( uint8_t* pixelZone,
- size_t imageDataSize,
- int numberBitsStored,
- int numberBitsAllocated,
- bool signedPixel)