1 /*
2  *
3  *  Copyright (C) 2015-2019, Open Connections GmbH
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation are maintained by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module:  dcmfg
15  *
16  *  Author:  Michael Onken
17  *
18  *  Purpose: Class for managing Frame VOI LUT Functional Group
19  *
20  */
21 
22 #include "dcmtk/config/osconfig.h"
23 
24 #include "dcmtk/dcmdata/dcdeftag.h"
25 #include "dcmtk/dcmfg/fgframevoilut.h"
26 #include "dcmtk/dcmfg/fgtypes.h"
27 #include "dcmtk/dcmiod/iodutil.h"
28 
29 const OFString FGFrameVOILUT::DT_CT_WindowCenterWidthExplanation_Brain      = "BRAIN";
30 const OFString FGFrameVOILUT::DT_CT_WindowCenterWidthExplanation_SoftTissue = "SOFT_TISSUE";
31 const OFString FGFrameVOILUT::DT_CT_WindowCenterWidthExplanation_Lung       = "LUNG";
32 const OFString FGFrameVOILUT::DT_CT_WindowCenterWidthExplanation_Bone       = "BONE";
33 
34 // Constructor
FGFrameVOILUT()35 FGFrameVOILUT::FGFrameVOILUT()
36     : FGBase(DcmFGTypes::EFG_FRAMEVOILUTMETA)
37     , m_WindowCenter(DCM_WindowCenter)
38     , m_WindowWidth(DCM_WindowWidth)
39     , m_WindowCenterWindowWidthExplanation(DCM_WindowCenterWidthExplanation)
40     , m_VOILUTFunction(DCM_VOILUTFunction)
41 {
42 }
43 
~FGFrameVOILUT()44 FGFrameVOILUT::~FGFrameVOILUT()
45 {
46     // nothing to do
47 }
48 
clone() const49 FGBase* FGFrameVOILUT::clone() const
50 {
51     FGFrameVOILUT* copy = new FGFrameVOILUT();
52     if (copy)
53     {
54         copy->m_WindowCenter                       = this->m_WindowCenter;
55         copy->m_WindowWidth                        = this->m_WindowWidth;
56         copy->m_WindowCenterWindowWidthExplanation = this->m_WindowCenterWindowWidthExplanation;
57         copy->m_VOILUTFunction                     = this->m_VOILUTFunction;
58     }
59     return copy;
60 }
61 
clearData()62 void FGFrameVOILUT::clearData()
63 {
64     m_WindowCenter.clear();
65     m_WindowWidth.clear();
66     m_WindowCenterWindowWidthExplanation.clear();
67     m_VOILUTFunction.clear();
68 }
69 
check() const70 OFCondition FGFrameVOILUT::check() const
71 {
72     // For now attribute-based checks in read() and write() are sufficient
73     return EC_Normal;
74 }
75 
76 // --- get() functionality ---
77 
getWindowCenter(Float64 & value,const unsigned long pos)78 OFCondition FGFrameVOILUT::getWindowCenter(Float64& value, const unsigned long pos)
79 {
80     return m_WindowCenter.getFloat64(value, pos);
81 }
82 
getWindowWidth(Float64 & value,const unsigned long pos)83 OFCondition FGFrameVOILUT::getWindowWidth(Float64& value, const unsigned long pos)
84 {
85     return m_WindowWidth.getFloat64(value, pos);
86 }
87 
getWindowCenterAndWindowWidthExplanation(OFString & value,const unsigned long pos)88 OFCondition FGFrameVOILUT::getWindowCenterAndWindowWidthExplanation(OFString& value, const unsigned long pos)
89 {
90     return m_WindowCenterWindowWidthExplanation.getOFString(value, pos);
91 }
92 
getCenterWidthExplanation(Float64 & windowCenter,Float64 & windowWidth,OFString & explanation)93 OFCondition FGFrameVOILUT::getCenterWidthExplanation(Float64& windowCenter, Float64& windowWidth, OFString& explanation)
94 {
95     OFCondition result = m_WindowCenter.getFloat64(windowCenter);
96     if (result.good())
97         result = m_WindowWidth.getFloat64(windowWidth);
98     if (result.good())
99         result = m_WindowCenterWindowWidthExplanation.getOFString(explanation, 0);
100     return result;
101 }
102 
getVOILUTFunction(OFString & value,const unsigned long pos)103 OFCondition FGFrameVOILUT::getVOILUTFunction(OFString& value, const unsigned long pos)
104 {
105     return m_VOILUTFunction.getOFString(value, pos);
106 }
107 
108 // --- set() functionality ---
109 
setWindowCenter(const OFString & value,const OFBool checkValue)110 OFCondition FGFrameVOILUT::setWindowCenter(const OFString& value, const OFBool checkValue)
111 {
112     // no checks at the moment
113     (void)checkValue;
114     return m_WindowCenter.putOFStringArray(value);
115 }
116 
setWindowWidth(const OFString & value,const OFBool checkValue)117 OFCondition FGFrameVOILUT::setWindowWidth(const OFString& value, const OFBool checkValue)
118 {
119     // no checks at the moment
120     (void)checkValue;
121     return m_WindowWidth.putOFStringArray(value);
122 }
123 
setCenterWidthExplanation(const Float64 & windowCenter,const Float64 & windowWidth,const OFString & explanation,const OFBool checkValue)124 OFCondition FGFrameVOILUT::setCenterWidthExplanation(const Float64& windowCenter,
125                                                      const Float64& windowWidth,
126                                                      const OFString& explanation,
127                                                      const OFBool checkValue)
128 {
129     OFCondition result = m_WindowCenter.putFloat64(windowCenter);
130     if (result.good())
131         result = m_WindowWidth.putFloat64(windowWidth);
132     if (result.good() && !explanation.empty())
133     {
134         if (checkValue)
135         {
136             result = (checkValue) ? DcmLongString::checkStringValue(explanation, "1") : EC_Normal;
137         }
138         if (result.good())
139         {
140             result = m_WindowCenterWindowWidthExplanation.putString(explanation.c_str());
141         }
142     }
143     return result;
144 }
145 
setVOILUTFunction(const OFString & value,const OFBool checkValue)146 OFCondition FGFrameVOILUT::setVOILUTFunction(const OFString& value, const OFBool checkValue)
147 {
148     OFCondition result = (checkValue) ? DcmCodeString::checkStringValue(value, "1") : EC_Normal;
149     if (result.good())
150         result = m_VOILUTFunction.putString(value.c_str());
151     return result;
152 }
153 
154 /// Read Frame Content Sequence from given item
read(DcmItem & item)155 OFCondition FGFrameVOILUT::read(DcmItem& item)
156 {
157     clearData();
158 
159     DcmItem* seqItem   = NULL;
160     OFCondition result = getItemFromFGSequence(item, DCM_FrameVOILUTSequence, 0, seqItem);
161     if (result.bad())
162         return result;
163 
164     DcmIODUtil::getAndCheckElementFromDataset(*seqItem, m_WindowCenter, "1-n", "1", "FrameVOILUTMacro");
165     DcmIODUtil::getAndCheckElementFromDataset(*seqItem, m_WindowWidth, "1-n", "1", "FrameVOILUTMacro");
166     DcmIODUtil::getAndCheckElementFromDataset(
167         *seqItem, m_WindowCenterWindowWidthExplanation, "1-n", "3", "FrameVOILUTMacro");
168     DcmIODUtil::getAndCheckElementFromDataset(*seqItem, m_VOILUTFunction, "1", "3", "FrameVOILUTMacro");
169 
170     return EC_Normal;
171 }
172 
173 /// Writes single Frame Content Sequence into given item
write(DcmItem & item)174 OFCondition FGFrameVOILUT::write(DcmItem& item)
175 {
176     DcmItem* seqItem   = NULL;
177     OFCondition result = createNewFGSequence(item, DCM_FrameVOILUTSequence, 0, seqItem);
178     if (result.bad())
179         return result;
180 
181     // --- write frame content macro attributes ---
182     DcmIODUtil::copyElementToDataset(result, *seqItem, m_WindowCenter, "1-n", "1", "FrameVOILUTMacro");
183     DcmIODUtil::copyElementToDataset(result, *seqItem, m_WindowWidth, "1-n", "1", "FrameVOILUTMacro");
184     DcmIODUtil::copyElementToDataset(
185         result, *seqItem, m_WindowCenterWindowWidthExplanation, "1-n", "3", "FrameVOILUTMacro");
186     DcmIODUtil::copyElementToDataset(result, *seqItem, m_VOILUTFunction, "1", "3", "FrameVOILUTMacro");
187     return result;
188 }
189 
compare(const FGBase & rhs) const190 int FGFrameVOILUT::compare(const FGBase& rhs) const
191 {
192     int result = FGBase::compare(rhs);
193     if (result != 0)
194         return result;
195 
196     const FGFrameVOILUT* myRhs = OFstatic_cast(const FGFrameVOILUT*, &rhs);
197     if (!myRhs)
198         return -1;
199 
200     // Compare all elements
201     result = m_WindowCenter.compare(myRhs->m_WindowCenter);
202     if (result == 0)
203         result = m_WindowWidth.compare(myRhs->m_WindowWidth);
204     if (result == 0)
205         result = m_WindowCenterWindowWidthExplanation.compare(myRhs->m_WindowCenterWindowWidthExplanation);
206     if (result == 0)
207         result = m_VOILUTFunction.compare(myRhs->m_VOILUTFunction);
208 
209     return result;
210 }
211