+/**
+ * \ingroup gdcmFile
+ * \brief Read pixel data from disk (optionaly decompressing) into the
+ * caller specified memory location.
+ * @param destination where the pixel data should be stored.
+ *
+ */
+bool gdcmFile::ReadPixelData(void* destination) {
+
+ FILE *fp;
+
+ if ( !(fp=Header->OpenFile()))
+ return false;
+
+ if ( fseek(fp, Header->GetPixelOffset(), SEEK_SET) == -1 ) {
+ Header->CloseFile();
+ return false;
+ }
+
+
+ // ---------------------- Compacted File (12 Bits Per Pixel)
+ /* unpack 12 Bits pixels into 16 Bits pixels */
+ /* 2 pixels 12bit = [0xABCDEF] */
+ /* 2 pixels 16bit = [0x0ABD] + [0x0FCE] */
+ if (Header->GetBitsAllocated()==12) {
+ int nbPixels = Header->GetXSize() * Header->GetYSize();
+ unsigned char b0, b1, b2;
+
+ unsigned short int* pdestination = (unsigned short int*)destination;
+ for(int p=0;p<nbPixels;p+=2) {
+ fread(&b0,1,1,fp);
+ fread(&b1,1,1,fp);
+ fread(&b2,1,1,fp);
+ //Two steps is necessary to please VC++
+ *pdestination++ = ((b0 >> 4) << 8) + ((b0 & 0x0f) << 4) + (b1 & 0x0f);
+ /* A */ /* B */ /* D */
+ *pdestination++ = ((b2 & 0x0f) << 8) + ((b1 >> 4) << 4) + (b2 >> 4);
+ /* F */ /* C */ /* E */
+
+ // Troubles expected on Big-Endian processors ?
+ }
+ return(true);
+ }
+
+ // ---------------------- Uncompressed File
+ if ( !Header->IsDicomV3() ||
+ Header->IsImplicitVRLittleEndianTransferSyntax() ||
+ Header->IsExplicitVRLittleEndianTransferSyntax() ||
+ Header->IsExplicitVRBigEndianTransferSyntax() ||
+ Header->IsDeflatedExplicitVRLittleEndianTransferSyntax() ) {
+
+ size_t ItemRead = fread(destination, Header->GetPixelAreaLength(), 1, fp);
+
+ if ( ItemRead != 1 ) {
+ Header->CloseFile();
+ return false;
+ } else {
+ Header->CloseFile();
+ return true;
+ }
+ }
+
+ // ---------------------- Run Length Encoding
+ if (Header->IsRLELossLessTransferSyntax()) {
+ bool res = (bool)gdcm_read_RLE_file (fp,destination);
+ return res;
+ }
+
+ // --------------- SingleFrame/Multiframe JPEG Lossless/Lossy/2000
+ int nb;
+ std::string str_nb=Header->GetPubEntryByNumber(0x0028,0x0100);
+ if (str_nb == GDCM_UNFOUND ) {
+ nb = 16;
+ } else {
+ nb = atoi(str_nb.c_str() );
+ if (nb == 12) nb =16; // ?? 12 should be ACR-NEMA only ?
+ }
+
+ int nBytes= nb/8;
+
+ int taille = Header->GetXSize() * Header->GetYSize()
+ * Header->GetSamplesPerPixel();
+ long fragmentBegining; // for ftell, fseek
+
+ bool jpg2000 = Header->IsJPEG2000();
+ bool jpgLossless = Header->IsJPEGLossless();
+
+ bool res = true;
+ guint16 ItemTagGr,ItemTagEl;
+ int ln;
+
+ // Position on begining of Jpeg Pixels
+
+ fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
+ fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
+ if(Header->GetSwapCode()) {
+ ItemTagGr=Header->SwapShort(ItemTagGr);
+ ItemTagEl=Header->SwapShort(ItemTagEl);
+ }
+ fread(&ln,4,1,fp);
+ if(Header->GetSwapCode())
+ ln=Header->SwapLong(ln); // Basic Offset Table Item length
+
+ if (ln != 0) {
+ // What is it used for ?!?
+ char *BasicOffsetTableItemValue = (char *)malloc(ln+1);
+ fread(BasicOffsetTableItemValue,ln,1,fp);
+ }
+
+ // first Fragment initialisation
+ fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
+ fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
+ if(Header->GetSwapCode()) {
+ ItemTagGr=Header->SwapShort(ItemTagGr);
+ ItemTagEl=Header->SwapShort(ItemTagEl);
+ }
+
+ // parsing fragments until Sequence Delim. Tag found
+ while ( ( ItemTagGr == 0xfffe) && (ItemTagEl != 0xe0dd) ) {
+ // --- for each Fragment
+
+ fread(&ln,4,1,fp);
+ if(Header->GetSwapCode())
+ ln=Header->SwapLong(ln); // Fragment Item length
+
+ fragmentBegining=ftell(fp);
+
+ if (jpg2000) { // JPEG 2000 : call to ???
+
+ res = (bool)gdcm_read_JPEG2000_file (fp,destination); // Not Yet written
+
+ } // ------------------------------------- endif (JPEG2000)
+
+ else if (jpgLossless) { // JPEG LossLess : call to xmedcom JPEG
+
+ JPEGLosslessDecodeImage (fp, // Reading Fragment pixels
+ (unsigned short *)destination,
+ Header->GetPixelSize()*8* Header->GetSamplesPerPixel(),
+ ln);
+ res=1; // in order not to break the loop
+
+ } // ------------------------------------- endif (JPEGLossless)
+
+ else { // JPEG Lossy : call to IJG 6b
+
+ if (Header->GetBitsStored() == 8) {
+ res = (bool)gdcm_read_JPEG_file (fp,destination); // Reading Fragment pixels
+ } else {
+ res = (bool)gdcm_read_JPEG_file12 (fp,destination);// Reading Fragment pixels
+ }
+ } // ------------------------------------- endif (JPEGLossy)
+
+ if (!res) break;
+
+ destination = (char *)destination + taille * nBytes; // location in user's memory
+ // for next fragment (if any)
+
+ fseek(fp,fragmentBegining,SEEK_SET); // To be sure we start
+ fseek(fp,ln,SEEK_CUR); // at the begining of next fragment
+
+ ItemTagGr = ItemTagEl =0;
+ fread(&ItemTagGr,2,1,fp); // Reading (fffe) : Item Tag Gr
+ fread(&ItemTagEl,2,1,fp); // Reading (e000) : Item Tag El
+ if(Header->GetSwapCode()) {
+ ItemTagGr=Header->SwapShort(ItemTagGr);
+ ItemTagEl=Header->SwapShort(ItemTagEl);
+ }
+
+ } // endWhile parsing fragments until Sequence Delim. Tag found
+
+ Header->CloseFile();
+ return res;