Bug #463 » useDictForLengthField2.patch
| dcmdata/include/dcmtk/dcmdata/dcobject.h | ||
|---|---|---|
|
*/
|
||
|
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmPreferVRFromDataDictionary; /* default OFFalse */
|
||
|
/** This flag defines how the element's length field is interpreted when reading
|
||
|
* from a dataset with explicit VR encoding and the data dictionary doesn't
|
||
|
* agree with the VR from the dataset. By default, the length field is assumed
|
||
|
* to match the size of the VR in the dataset. If this flag is enabled and the
|
||
|
* tag is defined in the data dictionary, the parser will use the size for the
|
||
|
* VR from the data dictionary (and ignore the one from the dataset). This flag
|
||
|
* is, therefore, useful for reading incorrectly encoded DICOM datasets.
|
||
|
*/
|
||
|
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmPreferLengthFieldSizeFromDataDictionary; /* default OFFalse */
|
||
|
/** This flag indicates, whether private attributes with implicit transfer
|
||
|
* syntax having a maximum length should be handled as sequences (ignoring
|
||
|
* any dictionary entries for that tag). This can happen, if for example
|
||
| dcmdata/libsrc/dcitem.cc | ||
|---|---|---|
|
newTag.setVR(vr);
|
||
|
}
|
||
|
/* determine VR read from dataset, because this VR specifies the number of bytes for the length-field */
|
||
|
newEVR = vr.getEVR();
|
||
|
if (!dcmPreferLengthFieldSizeFromDataDictionary.get() || newEVR == EVR_UNKNOWN || newEVR == EVR_UNKNOWN2B) {
|
||
|
/* determine VR read from dataset, because this VR specifies the number of bytes for the length-field */
|
||
|
newEVR = vr.getEVR();
|
||
|
} else {
|
||
|
/* use the VR from the dictionary for deciding the length of the length field */
|
||
|
}
|
||
|
/* increase counter by 2 */
|
||
|
bytesRead += 2;
|
||
| dcmdata/libsrc/dcobject.cc | ||
|---|---|---|
|
OFGlobal<OFBool> dcmAutoDetectDatasetXfer(OFFalse);
|
||
|
OFGlobal<OFBool> dcmAcceptUnexpectedImplicitEncoding(OFFalse);
|
||
|
OFGlobal<OFBool> dcmPreferVRFromDataDictionary(OFFalse);
|
||
|
OFGlobal<OFBool> dcmPreferLengthFieldSizeFromDataDictionary(OFFalse);
|
||
|
OFGlobal<OFBool> dcmReadImplPrivAttribMaxLengthAsSQ(OFFalse);
|
||
|
OFGlobal<OFBool> dcmIgnoreParsingErrors(OFFalse);
|
||
|
OFGlobal<DcmTagKey> dcmStopParsingAfterElement(DCM_UndefinedTagKey); // (0xffff,0xffff)
|
||
| dcmdata/tests/tparser.cc | ||
|---|---|---|
|
testOddLengthPartialValue(data, sizeof(data));
|
||
|
}
|
||
|
static const DcmTagKey wrongExplicitVRinDataset_unknownTag(0x0006, 0x0006);
|
||
|
static const Uint8 wrongExplicitVRinDataset_testData[] = {
|
||
|
/* This non-standard tag cannot be corrected (not in data dictionary) */
|
||
|
TAG_AND_LENGTH_SHORT(wrongExplicitVRinDataset_unknownTag, 'P', 'N', 4),
|
||
|
'A', 'B', 'C', 'D',
|
||
|
/* This standard tag has a wrong VR ("ST" instead of "PN") */
|
||
|
TAG_AND_LENGTH_SHORT(DCM_PatientName, 'S', 'T', 4),
|
||
|
'A', 'B', 'C', 'D',
|
||
|
/* This standard tag has a wrong VR ("UN") and uses a 4-byte length field */
|
||
|
TAG_AND_LENGTH(DCM_PatientID, 'U', 'N', 4),
|
||
|
'0', '8', '1', '5',
|
||
|
/* This standard tag has a correct VR, no modification required */
|
||
|
TAG_AND_LENGTH_SHORT(DCM_PatientSex, 'C', 'S', 2),
|
||
|
static const DcmTagKey wrongExplicitVRinDataset_unknownTag1(0x0006, 0x0006);
|
||
|
static const DcmTagKey wrongExplicitVRinDataset_unknownTag2(0x0006, 0x0008);
|
||
|
#define WRONG_EXPLICIT_VR_COMMON \
|
||
|
/* This non-standard tag cannot be corrected (not in data dictionary, short length field) */ \
|
||
|
TAG_AND_LENGTH_SHORT(wrongExplicitVRinDataset_unknownTag1, 'P', 'N', 4), \
|
||
|
'A', 'B', 'C', 'D', \
|
||
|
/* This non-standard tag cannot be corrected (not in data dictionary, long length field) */ \
|
||
|
TAG_AND_LENGTH(wrongExplicitVRinDataset_unknownTag2, 'U', 'T', 4), \
|
||
|
'E', 'F', 'G', 'H', \
|
||
|
/* This standard tag has a wrong VR ("ST" instead of "PN") */ \
|
||
|
TAG_AND_LENGTH_SHORT(DCM_PatientName, 'S', 'T', 4), \
|
||
|
'I', 'J', 'K', 'L', \
|
||
|
/* This standard tag has a correct VR, no modification required */ \
|
||
|
TAG_AND_LENGTH_SHORT(DCM_PatientSex, 'C', 'S', 2), \
|
||
|
'O', ' '
|
||
|
static const Uint8 wrongExplicitVRwithDatasetLen_testData[] = {
|
||
|
WRONG_EXPLICIT_VR_COMMON,
|
||
|
/* This standard tag has a wrong VR ("UN") and does not use the "PN" length field size */
|
||
|
TAG_AND_LENGTH(DCM_PatientBirthName, 'U', 'N', 4),
|
||
|
'0', '8', '1', '5',
|
||
|
/* This standard tag has a wrong VR ("LO") and does not use the "UT" length field size */
|
||
|
TAG_AND_LENGTH_SHORT(DCM_PixelDataProviderURL, 'L', 'O', 4),
|
||
|
'4', '2', '4', '2',
|
||
|
};
|
||
|
static const Uint8 wrongExplicitVRwithDictLen_testData[] = {
|
||
|
WRONG_EXPLICIT_VR_COMMON,
|
||
|
/* This standard tag has a wrong VR ("UN") and uses the "PN" length field size */
|
||
|
TAG_AND_LENGTH_SHORT(DCM_PatientBirthName, 'U', 'N', 4),
|
||
|
'0', '8', '1', '5',
|
||
|
/* This standard tag has a wrong VR ("LO") and uses the "UT" length field size */
|
||
|
TAG_AND_LENGTH(DCM_PixelDataProviderURL, 'L', 'O', 4),
|
||
|
'4', '2', '4', '2',
|
||
|
};
|
||
|
#undef WRONG_EXPLICIT_VR_COMMON
|
||
|
static void testForExpectedVR(DcmDataset &dset, const DcmTagKey &tag, const DcmEVR vr)
|
||
|
{
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
OFTEST(dcmdata_parser_wrongExplicitVRinDataset_default)
|
||
|
static void expectReadError(const Uint8* buffer, size_t length, E_TransferSyntax ts)
|
||
|
{
|
||
|
DcmDataset dset;
|
||
|
OFCondition cond = readDataset(dset, buffer, length, TRANSFER_SYNTAX);
|
||
|
if (cond != EC_InvalidStream)
|
||
|
{
|
||
|
OFCHECK_FAIL("Dataset should fail with invalid stream, but got: " << cond.text());
|
||
|
if (cond.good())
|
||
|
OFLOG_DEBUG(tparserLogger, DcmObject::PrintHelper(dset));
|
||
|
}
|
||
|
}
|
||
|
static void testExplicitVRinDataset(OFBool useDictionaryVR, OFBool useDictionaryVRLen)
|
||
|
{
|
||
|
DcmDataset dset;
|
||
|
OFCondition cond;
|
||
|
const Uint8 *broken, *working;
|
||
|
size_t brokenLength, workingLength;
|
||
|
if (useDictionaryVRLen) {
|
||
|
broken = wrongExplicitVRwithDatasetLen_testData;
|
||
|
brokenLength = sizeof(wrongExplicitVRwithDatasetLen_testData);
|
||
|
working = wrongExplicitVRwithDictLen_testData;
|
||
|
workingLength = sizeof(wrongExplicitVRwithDictLen_testData);
|
||
|
} else {
|
||
|
working = wrongExplicitVRwithDatasetLen_testData;
|
||
|
workingLength = sizeof(wrongExplicitVRwithDatasetLen_testData);
|
||
|
broken = wrongExplicitVRwithDictLen_testData;
|
||
|
brokenLength = sizeof(wrongExplicitVRwithDictLen_testData);
|
||
|
}
|
||
|
dcmPreferLengthFieldSizeFromDataDictionary.set(useDictionaryVRLen);
|
||
|
dcmPreferVRFromDataDictionary.set(useDictionaryVR);
|
||
|
// This should use the VR from the dataset (default)
|
||
|
expectReadError(broken, brokenLength, TRANSFER_SYNTAX);
|
||
|
cond = readDataset(dset, working, workingLength, TRANSFER_SYNTAX);
|
||
|
// Reset to the default values
|
||
|
dcmPreferLengthFieldSizeFromDataDictionary.set(OFFalse);
|
||
|
dcmPreferVRFromDataDictionary.set(OFFalse);
|
||
|
cond = readDataset(dset, wrongExplicitVRinDataset_testData, sizeof(wrongExplicitVRinDataset_testData), TRANSFER_SYNTAX);
|
||
|
if (cond.good())
|
||
|
{
|
||
|
OFLOG_DEBUG(tparserLogger, DcmObject::PrintHelper(dset));
|
||
|
testForExpectedVR(dset, wrongExplicitVRinDataset_unknownTag, EVR_PN);
|
||
|
testForExpectedVR(dset, DCM_PatientName, EVR_ST);
|
||
|
testForExpectedVR(dset, DCM_PatientID, EVR_UN);
|
||
|
testForExpectedVR(dset, DCM_PatientSex, EVR_CS);
|
||
|
} else {
|
||
|
if (cond.bad()) {
|
||
|
OFCHECK_FAIL(cond.text());
|
||
|
return;
|
||
|
}
|
||
|
OFLOG_DEBUG(tparserLogger, DcmObject::PrintHelper(dset));
|
||
|
testForExpectedVR(dset, wrongExplicitVRinDataset_unknownTag1, EVR_PN);
|
||
|
testForExpectedVR(dset, wrongExplicitVRinDataset_unknownTag2, EVR_UT);
|
||
|
testForExpectedVR(dset, DCM_PatientName, useDictionaryVR ? EVR_PN : EVR_ST);
|
||
|
testForExpectedVR(dset, DCM_PatientBirthName, useDictionaryVR ? EVR_PN : EVR_UN);
|
||
|
testForExpectedVR(dset, DCM_PixelDataProviderURL, useDictionaryVR ? EVR_UT : EVR_LO);
|
||
|
}
|
||
|
// TODO make test name and testData-name match
|
||
|
OFTEST(dcmdata_parser_wrongExplicitVRinDataset_default)
|
||
|
{
|
||
|
DcmDataset dset;
|
||
|
OFCondition cond;
|
||
|
// TODO: Split this up into multiple tests
|
||
|
testExplicitVRinDataset(OFFalse, OFFalse);
|
||
|
testExplicitVRinDataset(OFFalse, OFTrue);
|
||
|
testExplicitVRinDataset(OFTrue, OFFalse);
|
||
|
testExplicitVRinDataset(OFTrue, OFTrue);
|
||
|
}
|
||
|
OFTEST(dcmdata_parser_wrongExplicitVRinDataset_preferDataDict)
|
||
| ... | ... | |
|
DcmDataset dset;
|
||
|
OFCondition cond;
|
||
|
// This should use the VR from the data dictionary
|
||
|
dcmPreferVRFromDataDictionary.set(OFTrue);
|
||
|
cond = readDataset(dset, wrongExplicitVRinDataset_testData, sizeof(wrongExplicitVRinDataset_testData), TRANSFER_SYNTAX);
|
||
|
if (cond.good())
|
||
|
{
|
||
|
OFLOG_DEBUG(tparserLogger, DcmObject::PrintHelper(dset));
|
||
|
testForExpectedVR(dset, wrongExplicitVRinDataset_unknownTag, EVR_PN);
|
||
|
testForExpectedVR(dset, DCM_PatientName, EVR_PN);
|
||
|
testForExpectedVR(dset, DCM_PatientID, EVR_LO);
|
||
|
testForExpectedVR(dset, DCM_PatientSex, EVR_CS);
|
||
|
} else {
|
||
|
OFCHECK_FAIL(cond.text());
|
||
|
}
|
||
|
// Reset to the default value
|
||
|
dcmPreferVRFromDataDictionary.set(OFFalse);
|
||
|
}
|
||
|
OFTEST(dcmdata_parser_undefinedLengthUNSequence)
|
||
- « Previous
- 1
- 2
- Next »