1 /*
2 *
3 * Copyright (C) 1999-2010, OFFIS e.V.
4 * All rights reserved. See COPYRIGHT file for details.
5 *
6 * This software and supporting documentation were developed by
7 *
8 * OFFIS e.V.
9 * R&D Division Health
10 * Escherweg 2
11 * D-26121 Oldenburg, Germany
12 *
13 *
14 * Module: dcmpstat
15 *
16 * Author: Marco Eichelberg
17 *
18 * Purpose:
19 * classes: DVPSImageBoxContent_PList
20 *
21 */
22
23 #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
24 #include "dcmtk/dcmpstat/dvpspll.h"
25 #include "dcmtk/dcmpstat/dvpspl.h" /* for DVPSImageBoxContent */
26 #include "dcmtk/dcmpstat/dvpshlp.h" /* for class DVPSHelper */
27 #include "dcmtk/dcmpstat/dvpsibl.h" /* for class DVPSImageBoxContent_PList */
28 #include "dcmtk/dcmimgle/diluptab.h" /* for class DiLookupTable */
29 #include "dcmtk/dcmpstat/dvpsdef.h"
30 #include "dcmtk/dcmpstat/dvpsib.h" /* for DVPSImageBoxContent, needed by MSVC5 with STL */
31
32 /* --------------- class DVPSImageBoxContent_PList --------------- */
33
DVPSPresentationLUT_PList()34 DVPSPresentationLUT_PList::DVPSPresentationLUT_PList()
35 : list_()
36 {
37 }
38
DVPSPresentationLUT_PList(const DVPSPresentationLUT_PList & arg)39 DVPSPresentationLUT_PList::DVPSPresentationLUT_PList(const DVPSPresentationLUT_PList &arg)
40 : list_()
41 {
42 OFListConstIterator(DVPSPresentationLUT *) first = arg.list_.begin();
43 OFListConstIterator(DVPSPresentationLUT *) last = arg.list_.end();
44 while (first != last)
45 {
46 list_.push_back((*first)->clone());
47 ++first;
48 }
49 }
50
~DVPSPresentationLUT_PList()51 DVPSPresentationLUT_PList::~DVPSPresentationLUT_PList()
52 {
53 clear();
54 }
55
clear()56 void DVPSPresentationLUT_PList::clear()
57 {
58 OFListIterator(DVPSPresentationLUT *) first = list_.begin();
59 OFListIterator(DVPSPresentationLUT *) last = list_.end();
60 while (first != last)
61 {
62 delete (*first);
63 first = list_.erase(first);
64 }
65 }
66
read(DcmItem & dset)67 OFCondition DVPSPresentationLUT_PList::read(DcmItem &dset)
68 {
69 OFCondition result = EC_Normal;
70 DcmStack stack;
71 DVPSPresentationLUT *newLUT = NULL;
72 DcmSequenceOfItems *dseq=NULL;
73 DcmItem *ditem=NULL;
74
75 if (EC_Normal == dset.search(DCM_RETIRED_PresentationLUTContentSequence, stack, ESM_fromHere, OFFalse))
76 {
77 dseq=(DcmSequenceOfItems *)stack.top();
78 if (dseq)
79 {
80 unsigned long numItems = dseq->card();
81 for (unsigned int i=0; i<numItems; i++)
82 {
83 ditem = dseq->getItem(i);
84 newLUT = new DVPSPresentationLUT();
85 if (newLUT && ditem)
86 {
87 result = newLUT->read(*ditem, OFTrue);
88 list_.push_back(newLUT);
89 } else result = EC_MemoryExhausted;
90 }
91 }
92 }
93
94 return result;
95 }
96
write(DcmItem & dset)97 OFCondition DVPSPresentationLUT_PList::write(DcmItem &dset)
98 {
99 if (size()==0) return EC_Normal; // don't write if sequence is empty
100
101 OFCondition result = EC_Normal;
102 DcmSequenceOfItems *dseq=NULL;
103 DcmItem *ditem=NULL;
104
105 dseq = new DcmSequenceOfItems(DCM_RETIRED_PresentationLUTContentSequence);
106 if (dseq)
107 {
108 OFListIterator(DVPSPresentationLUT *) first = list_.begin();
109 OFListIterator(DVPSPresentationLUT *) last = list_.end();
110 while (first != last)
111 {
112 if (result==EC_Normal)
113 {
114 ditem = new DcmItem();
115 if (ditem)
116 {
117 result = (*first)->write(*ditem, OFTrue);
118 if (result==EC_Normal) dseq->insert(ditem); else delete ditem;
119 } else result = EC_MemoryExhausted;
120 }
121 ++first;
122 }
123 if (result==EC_Normal) dset.insert(dseq, OFTrue /*replaceOld*/); else delete dseq;
124 } else result = EC_MemoryExhausted;
125 return result;
126 }
127
cleanup(const char * filmBox,DVPSImageBoxContent_PList & imageBoxes)128 void DVPSPresentationLUT_PList::cleanup(const char *filmBox, DVPSImageBoxContent_PList& imageBoxes)
129 {
130 OFString aFilmbox;
131 if (filmBox) aFilmbox = filmBox;
132 const char *uid;
133 OFListIterator(DVPSPresentationLUT *) first = list_.begin();
134 OFListIterator(DVPSPresentationLUT *) last = list_.end();
135 while (first != last)
136 {
137 uid = (*first)->getSOPInstanceUID();
138 if (uid && ((aFilmbox == uid)||(imageBoxes.presentationLUTInstanceUIDisUsed(uid)))) ++first;
139 else
140 {
141 delete (*first);
142 first = list_.erase(first);
143 }
144 }
145 return;
146 }
147
findPresentationLUT(const char * instanceUID)148 DVPSPresentationLUT *DVPSPresentationLUT_PList::findPresentationLUT(const char *instanceUID)
149 {
150 if (instanceUID==NULL) return NULL;
151 OFString instance(instanceUID);
152 OFListIterator(DVPSPresentationLUT *) first = list_.begin();
153 OFListIterator(DVPSPresentationLUT *) last = list_.end();
154 const char *c;
155 while (first != last)
156 {
157 c = (*first)->getSOPInstanceUID();
158 if (c && (instance == c)) return (*first);
159 ++first;
160 }
161 return NULL;
162 }
163
addPresentationLUT(DVPSPresentationLUT * newLUT,OFBool inversePLUT)164 const char *DVPSPresentationLUT_PList::addPresentationLUT(DVPSPresentationLUT *newLUT, OFBool inversePLUT)
165 {
166 if (newLUT == NULL) return NULL;
167
168 DiLookupTable *diLUT = NULL;
169 const char *result = NULL;
170
171 // 'INVERSE' LUT shape is undefined for Print and has already
172 // been rendered into the bitmap at this stage.
173 DVPSPresentationLUTType lutType = newLUT->getType();
174 if (lutType == DVPSP_inverse) lutType = DVPSP_identity;
175
176 DVPSPresentationLUT *myLUT = newLUT->clone();
177 if (myLUT)
178 {
179 // make sure that we don't copy an inverse LUT shape
180 if (myLUT->getType() == DVPSP_inverse) myLUT->setType(DVPSP_identity);
181 if (lutType == DVPSP_table)
182 {
183 if (inversePLUT) myLUT->invert();
184 diLUT = myLUT->createDiLookupTable();
185 }
186 } else return NULL;
187
188 // see if myLUT is already somewhere in the list
189 OFListIterator(DVPSPresentationLUT *) first = list_.begin();
190 OFListIterator(DVPSPresentationLUT *) last = list_.end();
191 while (first != last)
192 {
193 if ((*first)->getType() == lutType)
194 {
195 if (lutType == DVPSP_table)
196 {
197 if ((*first)->compareDiLookupTable(diLUT))
198 {
199 result = (*first)->getSOPInstanceUID();
200 break;
201 }
202 } else {
203 result = (*first)->getSOPInstanceUID();
204 break;
205 }
206 }
207 ++first;
208 }
209 delete diLUT;
210
211 if (result)
212 {
213 delete myLUT;
214 return result;
215 }
216
217 // no match, store new LUT
218 char uid[100];
219 dcmGenerateUniqueIdentifier(uid);
220 myLUT->setSOPInstanceUID(uid);
221 list_.push_back(myLUT);
222 result = myLUT->getSOPInstanceUID();
223
224 return result;
225 }
226
227
printSCPDelete(T_DIMSE_Message & rq,T_DIMSE_Message & rsp)228 void DVPSPresentationLUT_PList::printSCPDelete(T_DIMSE_Message& rq, T_DIMSE_Message& rsp)
229 {
230 OFListIterator(DVPSPresentationLUT *) first = list_.begin();
231 OFListIterator(DVPSPresentationLUT *) last = list_.end();
232 OFBool found = OFFalse;
233 OFString theUID(rq.msg.NDeleteRQ.RequestedSOPInstanceUID);
234 while ((first != last) && (!found))
235 {
236 if (theUID == (*first)->getSOPInstanceUID()) found = OFTrue;
237 else ++first;
238 }
239
240 if (found)
241 {
242 delete (*first);
243 list_.erase(first);
244 } else {
245 // presentation LUT does not exist or wrong instance UID
246 DCMPSTAT_WARN("cannot delete presentation LUT with instance UID '" << rq.msg.NDeleteRQ.RequestedSOPInstanceUID << "': object does not exist.");
247 rsp.msg.NDeleteRSP.DimseStatus = STATUS_N_NoSuchObjectInstance;
248 }
249 }
250