Orthanc/OrthancFramework/Sources/DicomParsing/DicomModification.h
2025-06-23 19:07:37 +05:30

273 lines
7.4 KiB
C++

/**
* Orthanc - A Lightweight, RESTful DICOM Store
* Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
* Department, University Hospital of Liege, Belgium
* Copyright (C) 2017-2023 Osimis S.A., Belgium
* Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
* Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
**/
#pragma once
#include "ParsedDicomFile.h"
#include <list>
namespace Orthanc
{
class ORTHANC_PUBLIC DicomModification : public boost::noncopyable
{
/**
* Process:
* (1) Remove private tags
* (2) Remove tags specified by the user
* (3) Replace tags
**/
public:
class IDicomIdentifierGenerator : public boost::noncopyable
{
public:
virtual ~IDicomIdentifierGenerator()
{
}
virtual bool Apply(std::string& target,
const std::string& sourceIdentifier,
ResourceType level,
const DicomMap& sourceDicom) = 0;
};
private:
class RelationshipsVisitor;
class DicomTagRange
{
private:
uint16_t groupFrom_;
uint16_t groupTo_;
uint16_t elementFrom_;
uint16_t elementTo_;
public:
DicomTagRange(uint16_t groupFrom,
uint16_t groupTo,
uint16_t elementFrom,
uint16_t elementTo);
uint16_t GetGroupFrom() const
{
return groupFrom_;
}
uint16_t GetGroupTo() const
{
return groupTo_;
}
uint16_t GetElementFrom() const
{
return elementFrom_;
}
uint16_t GetElementTo() const
{
return elementTo_;
}
bool Contains(const DicomTag& tag) const;
};
class SequenceReplacement : public boost::noncopyable
{
private:
DicomPath path_;
Json::Value value_;
public:
SequenceReplacement(const DicomPath& path,
const Json::Value& value) :
path_(path),
value_(value)
{
}
const DicomPath& GetPath() const
{
return path_;
}
const Json::Value& GetValue() const
{
return value_;
}
};
typedef std::set<DicomTag> SetOfTags;
typedef std::map<DicomTag, Json::Value*> Replacements;
typedef std::list<DicomTagRange> RemovedRanges;
typedef std::list<DicomPath> ListOfPaths;
typedef std::list<SequenceReplacement*> SequenceReplacements;
typedef std::map< std::pair<ResourceType, std::string>, std::string> UidMap;
SetOfTags removals_;
SetOfTags clearings_;
SetOfTags keep_;
Replacements replacements_;
bool removePrivateTags_;
bool keepLabels_;
ResourceType level_;
UidMap uidMap_;
SetOfTags privateTagsToKeep_;
bool allowManualIdentifiers_;
bool keepStudyInstanceUid_;
bool keepSeriesInstanceUid_;
bool keepSopInstanceUid_;
bool updateReferencedRelationships_;
bool isAnonymization_;
DicomMap currentSource_;
std::string privateCreator_;
IDicomIdentifierGenerator* identifierGenerator_;
// New in Orthanc 1.9.4
SetOfTags uids_;
RemovedRanges removedRanges_;
ListOfPaths keepSequences_; // Can *possibly* be a path whose prefix is empty
ListOfPaths removeSequences_; // Must *never* be a path whose prefix is empty
SequenceReplacements sequenceReplacements_; // Must *never* be a path whose prefix is empty
std::string MapDicomIdentifier(const std::string& original,
ResourceType level);
void RegisterMappedDicomIdentifier(const std::string& original,
const std::string& mapped,
ResourceType level);
void MapDicomTags(ParsedDicomFile& dicom,
ResourceType level);
void MarkNotOrthancAnonymization();
void ClearReplacements();
void CancelReplacement(const DicomTag& tag);
void ReplaceInternal(const DicomTag& tag,
const Json::Value& value);
void SetupUidsFromOrthanc_1_9_3();
void SetupAnonymization2008();
void SetupAnonymization2017c();
void SetupAnonymization2021b();
void SetupAnonymization2023b();
void UnserializeUidMap(ResourceType level,
const Json::Value& serialized,
const char* field);
public:
DicomModification();
explicit DicomModification(const Json::Value& serialized);
~DicomModification();
void Keep(const DicomTag& tag);
void Remove(const DicomTag& tag);
// Replace the DICOM tag as a NULL/empty value (e.g. for anonymization)
void Clear(const DicomTag& tag);
bool IsRemoved(const DicomTag& tag) const;
bool IsCleared(const DicomTag& tag) const;
// "safeForAnonymization" tells Orthanc that this replacement does
// not break the anonymization process it implements (for internal use only)
void Replace(const DicomTag& tag,
const Json::Value& value, // Encoded using UTF-8
bool safeForAnonymization);
bool IsReplaced(const DicomTag& tag) const;
void GetReplacedTags(std::set<DicomTag>& target) const;
const Json::Value& GetReplacement(const DicomTag& tag) const;
std::string GetReplacementAsString(const DicomTag& tag) const;
bool IsKept(const DicomTag& tag) const;
void SetRemovePrivateTags(bool removed);
bool ArePrivateTagsRemoved() const;
void SetKeepLabels(bool keep);
bool AreLabelsKept() const;
void SetLevel(ResourceType level);
ResourceType GetLevel() const;
void SetupAnonymization(DicomVersion version);
void Apply(ParsedDicomFile& toModify);
void SetAllowManualIdentifiers(bool check);
bool AreAllowManualIdentifiers() const;
void ParseModifyRequest(const Json::Value& request);
// "patientNameOverridden" is set to "true" iff. the PatientName
// (0010,0010) tag is manually replaced, removed, cleared or kept
void ParseAnonymizationRequest(bool& patientNameOverridden /* out */,
const Json::Value& request);
void SetDicomIdentifierGenerator(IDicomIdentifierGenerator& generator);
void Serialize(Json::Value& value) const;
void SetPrivateCreator(const std::string& privateCreator);
const std::string& GetPrivateCreator() const;
// New in Orthanc 1.9.4
void Keep(const DicomPath& path);
// New in Orthanc 1.9.4
void Remove(const DicomPath& path);
// New in Orthanc 1.9.4
void Replace(const DicomPath& path,
const Json::Value& value, // Encoded using UTF-8
bool safeForAnonymization);
bool IsAlteredTag(const DicomTag& tag) const;
};
}