why does DcmFileFormat::loadFile perform differently in Vista and XP?

All other questions regarding DCMTK

Moderator: Moderator Team

Message
Author
richardander
Posts: 16
Joined: Tue, 2007-08-14, 08:05

#16 Post by richardander »

Is there any parameter that I can set in function loadFile() to make it work under XP?
"Jörg Riesmeier"]Thank you for the file. I don't know why different versions of the Windows OS should behave differently, but the file you've sent us seems to be corrupted: There is some "garbage" data after the PixelData element. So when you use dcmdump from DCMTK 3.6.0, option "--stop-after-elem PixelData" or "--ignor
Some additional information:

The image was acquired from Philips MRI scanner with format called "advanced DICOM". It is a multiframe dicom file.

I could open it with ezDicom viewer ( free download from : http://www.cabiatl.com/mricro/ezdicom/index.html ).

Any thoughts?

Thank you

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#17 Post by Jörg Riesmeier »

This is a good question. I had to check the source code, and here is the answer:

Code: Select all

void DcmVR::setVR(const char* vrName)
{
    vr = EVR_UNKNOWN;   /* default */
    if ( vrName != NULL)
    {
        int found = OFFalse;
        int i = 0;
        for (i=0;  (!found && (i < DcmVRDict_DIM)); i++)
        {
            if (strncmp(vrName, DcmVRDict[i].vrName, 2) == 0)
            {
                found = OFTrue;
                vr = DcmVRDict[i].vr;
            }
        }
        /* Workaround: There have been reports of systems transmitting
         * illegal VR strings in explicit VR (i.e. "??") without using
         * extended length fields. This is particularly bad because the
         * DICOM committee has announced that all future VRs will use
         * extended length. In order to distinguish between these two
         * variants, we treat all unknown VRs consisting of uppercase
         * letters as "real" future VRs (and thus assume extended length).
         * All other VR strings are treated as "illegal" VRs.
         */
        register char c1 = *vrName;
        register char c2 = (c1)?(*(vrName+1)):('\0');
        if ((c1=='?')&&(c2=='?')) vr = EVR_UNKNOWN2B;
        if (!found && ((c1<'A')||(c1>'Z')||(c2<'A')||(c2>'Z'))) vr = EVR_UNKNOWN2B;
    }
}

Michael Onken
DCMTK Developer
Posts: 2049
Joined: Fri, 2004-11-05, 13:47
Location: Oldenburg, Germany
Contact:

#18 Post by Michael Onken »

Hi Per,

good question. I looked into the code. Actually, if the code encounters unknown VRs, it checks whether the VR implicates a 4 byte length field which is the (expected) behaviour for unknown VR as you pointed out.

However, there is indeed a little heuristic which was introduced because a large german company (...) has built systems in the past which entered "??" as explicit VR followed by a 2 byte length field. We are able to read those encodings.

Thus, if the parser finds an unknown VR, it checks for "??", but as an extended version of that, also checks whether one of the two VR characters is outside the range of normal letters (A-Z) which could give a hint that something is fishy here. In this case, internally the VR is mapped to the special VR EVR_UNKNOWN2B (aiming mostly at ??) which is associated with a 2 bytes length field. This is the case for the discussed wrongly encoded VRs in this thread. This is the code from dcmvr.cc for this

Code: Select all

  register char c1 = *vrName;
  register char c2 = (c1)?(*(vrName+1)):('\0');
  if ((c1=='?')&&(c2=='?')) vr = EVR_UNKNOWN2B;
  if (!found && ((c1<'A')||(c1>'Z')||(c2<'A')||(c2>'Z'))) vr = EVR_UNKNOWN2B;
If the letters turn out to be in A-Z, a 4 bytes length field is assumed.

Best regards,
Michael

P.S: However, did not try in the debugger

Michael Onken
DCMTK Developer
Posts: 2049
Joined: Fri, 2004-11-05, 13:47
Location: Oldenburg, Germany
Contact:

#19 Post by Michael Onken »

Well, I think Jörg and I cross-posted :-)

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#20 Post by Jörg Riesmeier »

To "richardander": When you look into the source code of dcmdump, you'll find out that the following code line enables the "--stop-after-elem PixelData" option:

Code: Select all

dcmStopParsingAfterElement.set(DCM_PixelData);
Is there any parameter that I can set in function loadFile() to make it work under XP?
I still cannot see any reasons why the same executable binary should behave differently on Windows XP and Vista (with the above mentioned restrictions).

richardander
Posts: 16
Joined: Tue, 2007-08-14, 08:05

#21 Post by richardander »

Hi Jörg and Michael,

Thank you for the investigation. However, it is weird that dcmdump can work in vista environment.

Anyway, if DcmFileFormat::loadFile can not load the sample dicom that I sent to you, is there any other way to load this dicom image with DCMTK library?

Thank you!

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#22 Post by Jörg Riesmeier »

Anyway, if DcmFileFormat::loadFile can not load the sample dicom that I sent to you, is there any other way to load this dicom image with DCMTK library?
No, we didn't say that. However, since this DICOM file is corrupted, the loadFile() method usually returns an error code.
There are multiple ways to handle this: One is to stop parsing after the PixelData element (see above), the other one is to ignore parse errors (use "dcmIgnoreParsingErrors.set(OFTrue);" in your code).

Here's the documentation from the source code:

Code: Select all

/** This flag indicates, whether parsing errors during reading
 *  should be ignored, ie whether the parser should try to recover and
 *  parse the rest of the stream.
 *  This flag does not work for all parsing errors (at this time)
 *  making sense but was introduced afterwards.
 */
extern OFGlobal<OFBool> dcmIgnoreParsingErrors; /* default OFFalse */

/** This flag indicates, whether parsing should stop after a certain
 *  element in the stream was parsed. This is especially useful for
 *  datasets containing garbage at the end, usually after the Pixel
 *  Data attribute. To prevent the parser for "stumbling" over that
 *  garbage, it is possible to tell the parser to stop after a
 *  specific element. The flag is only sensitive to elements on
 *  dataset level, ie. inside sequence any occurence of the specified
 *  tag is ignored. Caution: Note that if Pixel Data is chosen
 *  as stop element, any attributes behind will not be parsed, e. g.
 *  any digital signature attributes coming after.
 *  Default is (0xffff,0xffff), which means that the feature is
 *  disabled.
 */
extern OFGlobal<DcmTagKey> dcmStopParsingAfterElement; /* default OFTrue */

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest