Skip to content

Commit

Permalink
Provide a new API for DcmItem to delete a private attribute
Browse files Browse the repository at this point in the history
Extend DcmItem with findAndDeletePrivateElement to allow user to delete
a private tag directly (reservation number is computed internally).
  • Loading branch information
malaterre committed Feb 8, 2022
1 parent aca0e8e commit abb31ee
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 0 deletions.
13 changes: 13 additions & 0 deletions dcmdata/include/dcmtk/dcmdata/dcitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,19 @@ class DCMTK_DCMDATA_EXPORT DcmItem
const OFBool allOccurrences = OFFalse,
const OFBool searchIntoSub = OFFalse);

/** find private element, remove it from the dataset and free the associated memory.
* Applicable to all DICOM value representations (VR).
* @param tag DICOM tag specifying the private attribute to be searched for
* @param allOccurrences flag indicating whether to delete all occurrences of the
* attribute tag or the first one only (implies 'searchIntoSub' to be true)
* @param searchIntoSub flag indicating whether to search into sequences or not
* @return EC_Normal upon success, an error code otherwise.
*/
OFCondition findAndDeletePrivateElement(const DcmTag &tag,
const OFBool allOccurrences = OFFalse,
const OFBool searchIntoSub = OFFalse);


/** looks up the given sequence in the current dataset and deletes the given item.
* Applicable to the following VRs: SQ, (pixelSQ).
* @param seqTagKey DICOM tag specifying the sequence attribute to be searched for
Expand Down
40 changes: 40 additions & 0 deletions dcmdata/libsrc/dcitem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3202,6 +3202,46 @@ OFCondition DcmItem::findAndDeleteElement(const DcmTagKey &tagKey,
return status;
}

OFCondition DcmItem::findAndDeletePrivateElement(const DcmTag &privTag,
const OFBool allOccurrences,
const OFBool searchIntoSub)
{
OFCondition status = EC_TagNotFound;
DcmStack stack;
DcmObject *object = NULL;
OFBool intoSub = OFTrue;
/* make sure private tag */
if( !privTag.isPrivate() || privTag.getPrivateCreator() == NULL || privTag.getElement() >= 0x1000)
return status;
DcmTagKey curTag;
/* iterate over all elements */
while (nextObject(stack, intoSub).good())
{
/* get element */
object = stack.top();
curTag = object->getTag();
if (curTag.getGroup() == privTag.getGroup() && (curTag.getElement() > 0 && curTag.getElement() <= 0xff)) {
DcmElement *elem;
elem = OFstatic_cast(DcmElement *, stack.top());
OFString value;
if (elem->getOFStringArray(value).good()) {
if (value.compare(privTag.getPrivateCreator()) == 0) {
const Uint16 actualElement = OFstatic_cast(
Uint16, (curTag.getElement() << 8) | privTag.getElement());
const DcmTagKey tagKey(curTag.getGroup(), actualElement);
status = findAndDeleteElement(tagKey, allOccurrences, searchIntoSub);
/* delete only the first element? */
if (!allOccurrences)
break;
}
}
}
intoSub = searchIntoSub || allOccurrences;
}
return status;
}



OFCondition DcmItem::findAndDeleteSequenceItem(const DcmTagKey &seqTagKey,
const signed long itemNum)
Expand Down
1 change: 1 addition & 0 deletions dcmdata/tests/tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ OFTEST_REGISTER(dcmdata_sequenceInsert);
OFTEST_REGISTER(dcmdata_pixelSequenceInsert);
OFTEST_REGISTER(dcmdata_findAndGetSequenceItem);
OFTEST_REGISTER(dcmdata_findAndGetUint16Array);
OFTEST_REGISTER(dcmdata_findAndDeletePrivateElement);
OFTEST_REGISTER(dcmdata_parser_missingDelimitationItems);
OFTEST_REGISTER(dcmdata_parser_missingSequenceDelimitationItem_1);
OFTEST_REGISTER(dcmdata_parser_missingSequenceDelimitationItem_2);
Expand Down
24 changes: 24 additions & 0 deletions dcmdata/tests/titem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "dcmtk/dcmdata/dcitem.h"
#include "dcmtk/dcmdata/dcvrat.h"
#include "dcmtk/dcmdata/dcvrus.h"
#include "dcmtk/dcmdata/dcvrlo.h"
#include "dcmtk/dcmdata/dcdeftag.h"


Expand All @@ -48,3 +49,26 @@ OFTEST(dcmdata_findAndGetUint16Array)
OFCHECK(item.findAndGetUint16Array(DCM_FrameIncrementPointer, uintVals, &numUints).good());
OFCHECK_EQUAL(numUints, 2);
}

OFTEST(dcmdata_findAndDeletePrivateElement)
{
DcmItem item;
const DcmTag privTag(0x0009,0x0042,"PRIVATE CREATOR");
/* create data elements with values */
const Uint16 reservationElem = 0x0070;
/* reservation */
const DcmTagKey reservationTag(privTag.getGroup(), reservationElem);
DcmLongString loValue( reservationTag );
loValue.putString(privTag.getPrivateCreator());
item.insert(new DcmLongString(loValue));

/* actual private element */
const DcmTagKey privTagKey( privTag.getGroup(), (reservationElem << 8) | privTag.getElement());
DcmUnsignedShort usValue(privTagKey);
usValue.putString("1");
item.insert(new DcmUnsignedShort(usValue));
OFCHECK(item.tagExists (privTagKey));
/* remove it */
item.findAndDeletePrivateElement(privTag);
OFCHECK(!item.tagExists (privTagKey));
}

0 comments on commit abb31ee

Please sign in to comment.