Skip to content

Commit

Permalink
Handle enhanced DICOM using syntax 1.2.840.10008.1.2.4.70
Browse files Browse the repository at this point in the history
  • Loading branch information
neurolabusc committed Oct 2, 2021
1 parent 532655c commit c5a5baa
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 deletions.
23 changes: 16 additions & 7 deletions console/nii_dicom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1691,6 +1691,7 @@ struct TDICOMdata nii_readParRec(char *parname, int isVerbose, struct TDTI4D *dt
dti4D->volumeOnsetTime[0] = -1;
dti4D->decayFactor[0] = -1;
dti4D->frameDuration[0] = -1;
//dti4D->fragmentOffset[0] = -1;
dti4D->intenScale[0] = 0.0;
strcpy(d.protocolName, ""); //erase dummy with empty
strcpy(d.seriesDescription, ""); //erase dummy with empty
Expand Down Expand Up @@ -3111,7 +3112,7 @@ struct TJPEG {
long size;
};

TJPEG *decode_JPEG_SOF_0XC3_stack(const char *fn, int skipBytes, bool isVerbose, int frames, bool isLittleEndian) {
TJPEG *decode_JPEG_SOF_0XC3_stack(const char *fn, int skipBytes, int isVerbose, int frames, bool isLittleEndian) {
#define abortGoto() free(lOffsetRA); return NULL;
TJPEG *lOffsetRA = (TJPEG *)malloc(frames * sizeof(TJPEG));
FILE *reader = fopen(fn, "rb");
Expand All @@ -3137,7 +3138,7 @@ TJPEG *decode_JPEG_SOF_0XC3_stack(const char *fn, int skipBytes, bool isVerbose,
int tagLength = dcmInt(4, &lRawRA[lRawPos], isLittleEndian);
long tagEnd = lRawPos + tagLength + 4;
if (isVerbose)
printMessage("Tag %#x length %d end at %ld\n", tag, tagLength, tagEnd + skipBytes);
printMessage("Frame %d Tag %#x length %d end at %ld\n", frame + 1, tag, tagLength, tagEnd + skipBytes);
lRawPos += 4; //read tag length
if ((lRawRA[lRawPos] != 0xFF) || (lRawRA[lRawPos + 1] != 0xD8) || (lRawRA[lRawPos + 2] != 0xFF)) {
if (isVerbose)
Expand All @@ -3157,7 +3158,7 @@ TJPEG *decode_JPEG_SOF_0XC3_stack(const char *fn, int skipBytes, bool isVerbose,
return lOffsetRA;
}

unsigned char *nii_loadImgJPEGC3(char *imgname, struct nifti_1_header hdr, struct TDICOMdata dcm, bool isVerbose) {
unsigned char *nii_loadImgJPEGC3(char *imgname, struct nifti_1_header hdr, struct TDICOMdata dcm, int isVerbose) {
//arcane and inefficient lossless compression method popularized by dcmcjpeg, examples at http://www.osirix-viewer.com/resources/dicom-image-library/
int dimX, dimY, bits, frames;
//clock_t start = clock();
Expand All @@ -3178,7 +3179,6 @@ unsigned char *nii_loadImgJPEGC3(char *imgname, struct nifti_1_header hdr, struc
printMessage("Unable to decode JPEG. Please use dcmdjpeg to uncompress data.\n");
return NULL;
}
//printMessage("JPEG %fms\n", ((double)(clock()-start))/1000);
if (hdr.dim[3] != frames) { //multi-slice image saved as multiple image fragments rather than a single image
//printMessage("Unable to decode all slices (%d/%d). Please use dcmdjpeg to uncompress data.\n", frames, hdr.dim[3]);
if (ret != NULL)
Expand Down Expand Up @@ -3595,7 +3595,7 @@ unsigned char *nii_loadImgXL(char *imgname, struct nifti_1_header *hdr, struct T
if (hdr->datatype == DT_RGB24) //convert to planar
img = nii_rgb2planar(img, hdr, dcm.isPlanarRGB); //do this BEFORE Y-Flip, or RGB order can be flipped
} else if (dcm.compressionScheme == kCompressC3)
img = nii_loadImgJPEGC3(imgname, *hdr, dcm, (isVerbose > 0));
img = nii_loadImgJPEGC3(imgname, *hdr, dcm, isVerbose);
else
#ifndef myDisableOpenJPEG
if (((dcm.compressionScheme == kCompress50) || (dcm.compressionScheme == kCompressYes)) && (compressFlag != kCompressNone))
Expand Down Expand Up @@ -4043,6 +4043,7 @@ struct TDICOMdata readDICOMx(char *fname, struct TDCMprefs *prefs, struct TDTI4D
dti4D->volumeOnsetTime[0] = -1;
dti4D->decayFactor[0] = -1;
dti4D->frameDuration[0] = -1;
//dti4D->fragmentOffset[0] = -1;
dti4D->intenScale[0] = 0.0;
struct TVolumeDiffusion volDiffusion = initTVolumeDiffusion(&d, dti4D);
struct stat s;
Expand Down Expand Up @@ -4810,6 +4811,10 @@ const uint32_t kEffectiveTE = 0x0018 + (0x9082 << 16);
lPos = lPos + 4;
lLength = d.imageBytes;
if (d.imageBytes > 128) {
/*if (encapsulatedDataFragments < kMaxDTI4D) {
dti4D->fragmentOffset[encapsulatedDataFragments] = (int)lPos + (int)lFileOffset;
dti4D->fragmentLength[encapsulatedDataFragments] = lLength;
}*/
encapsulatedDataFragments++;
if (encapsulatedDataFragmentStart == 0)
encapsulatedDataFragmentStart = (int)lPos + (int)lFileOffset;
Expand Down Expand Up @@ -6754,9 +6759,9 @@ const uint32_t kEffectiveTE = 0x0018 + (0x9082 << 16);
//http://www.dclunie.com/medical-image-faq/html/part6.html
//unlike raw data, Encapsulated data is stored as Fragments contained in Items that are the Value field of Pixel Data
if ((d.compressionScheme != kCompressNone) && (!isIconImageSequence)) {
lLength = 0;
isEncapsulatedData = true;
encapsulatedDataImageStart = (int)lPos + (int)lFileOffset;
lLength = 0;
}
isIconImageSequence = false;
break;
Expand Down Expand Up @@ -6914,10 +6919,14 @@ const uint32_t kEffectiveTE = 0x0018 + (0x9082 << 16);
//printf("%d bval=%g bvec=%g %g %g<<<\n", d.CSA.numDti, d.CSA.dtiV[0], d.CSA.dtiV[1], d.CSA.dtiV[2], d.CSA.dtiV[3]);
//printMessage("><>< DWI bxyz %g %g %g %g\n", d.CSA.dtiV[0], d.CSA.dtiV[1], d.CSA.dtiV[2], d.CSA.dtiV[3]);
if (encapsulatedDataFragmentStart > 0) {
if (encapsulatedDataFragments > 1) {
if ((encapsulatedDataFragments > 1) && (encapsulatedDataFragments == numberOfFrames) && (encapsulatedDataFragments < kMaxDTI4D)) {
printWarning("Compressed image stored as %d fragments: if conversion fails decompress with gdcmconv, Osirix, dcmdjpeg or dcmjp2k %s\n", encapsulatedDataFragments, fname);
d.imageStart = encapsulatedDataFragmentStart;
} else if (encapsulatedDataFragments > 1) {
printError("Compressed image stored as %d fragments: decompress with gdcmconv, Osirix, dcmdjpeg or dcmjp2k %s\n", encapsulatedDataFragments, fname);
} else {
d.imageStart = encapsulatedDataFragmentStart;
//dti4D->fragmentOffset[0] = -1;
}
} else if ((isEncapsulatedData) && (d.imageStart < 128)) {
//http://www.dclunie.com/medical-image-faq/html/part6.html
Expand Down
1 change: 1 addition & 0 deletions console/nii_dicom.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ static const uint8_t MAX_NUMBER_OF_DIMENSIONS = 8;
struct TDTI S[kMaxDTI4D];
int sliceOrder[kMaxSlice2D]; // [7,3,2] means the first slice on disk should be moved to 7th position
int gradDynVol[kMaxDTI4D]; //used to parse dimensions of Philips data, e.g. file with multiple dynamics, echoes, phase+magnitude
//int fragmentOffset[kMaxDTI4D], fragmentLength[kMaxDTI4D]; //for images with multiple compressed fragments
float frameDuration[kMaxDTI4D], decayFactor[kMaxDTI4D], volumeOnsetTime[kMaxDTI4D], triggerDelayTime[kMaxDTI4D], TE[kMaxDTI4D], RWVScale[kMaxDTI4D], RWVIntercept[kMaxDTI4D], intenScale[kMaxDTI4D], intenIntercept[kMaxDTI4D], intenScalePhilips[kMaxDTI4D];
bool isReal[kMaxDTI4D];
bool isImaginary[kMaxDTI4D];
Expand Down

0 comments on commit c5a5baa

Please sign in to comment.