1 /*
2 *
3 * Copyright (C) 1998-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: DVPSReferencedSeries_PList
20 *
21 */
22
23 #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
24 #include "dcmtk/dcmdata/dcdeftag.h"
25 #include "dcmtk/dcmdata/dcsequen.h"
26 #include "dcmtk/dcmpstat/dvpsrsl.h"
27 #include "dcmtk/dcmpstat/dvpsrs.h" /* for DVPSReferencedSeries */
28 #include "dcmtk/dcmpstat/dvpsri.h" /* for DVPSReferencedImage, needed by MSVC5 with STL */
29 #include "dcmtk/dcmpstat/dvpsdef.h"
30
DVPSReferencedSeries_PList()31 DVPSReferencedSeries_PList::DVPSReferencedSeries_PList()
32 : list_()
33 {
34 }
35
DVPSReferencedSeries_PList(const DVPSReferencedSeries_PList & arg)36 DVPSReferencedSeries_PList::DVPSReferencedSeries_PList(const DVPSReferencedSeries_PList &arg)
37 : list_()
38 {
39 OFListConstIterator(DVPSReferencedSeries *) first = arg.list_.begin();
40 OFListConstIterator(DVPSReferencedSeries *) last = arg.list_.end();
41 while (first != last)
42 {
43 list_.push_back((*first)->clone());
44 ++first;
45 }
46 }
47
~DVPSReferencedSeries_PList()48 DVPSReferencedSeries_PList::~DVPSReferencedSeries_PList()
49 {
50 clear();
51 }
52
clear()53 void DVPSReferencedSeries_PList::clear()
54 {
55 OFListIterator(DVPSReferencedSeries *) first = list_.begin();
56 OFListIterator(DVPSReferencedSeries *) last = list_.end();
57 while (first != last)
58 {
59 delete (*first);
60 first = list_.erase(first);
61 }
62 }
63
read(DcmItem & dset)64 OFCondition DVPSReferencedSeries_PList::read(DcmItem &dset)
65 {
66 OFCondition result = EC_Normal;
67 DcmStack stack;
68 DVPSReferencedSeries *newSeries = NULL;
69 DcmSequenceOfItems *dseq=NULL;
70 DcmItem *ditem=NULL;
71
72 if (EC_Normal == dset.search(DCM_ReferencedSeriesSequence, stack, ESM_fromHere, OFFalse))
73 {
74 dseq=(DcmSequenceOfItems *)stack.top();
75 if (dseq)
76 {
77 unsigned long numItems = dseq->card();
78 for (unsigned int i=0; i<numItems; i++)
79 {
80 ditem = dseq->getItem(i);
81 newSeries = new DVPSReferencedSeries();
82 if (newSeries && ditem)
83 {
84 result = newSeries->read(*ditem);
85 list_.push_back(newSeries);
86 } else result = EC_MemoryExhausted;
87 }
88 }
89 }
90
91 return result;
92 }
93
write(DcmItem & dset)94 OFCondition DVPSReferencedSeries_PList::write(DcmItem &dset)
95 {
96 OFCondition result = EC_Normal;
97 DcmSequenceOfItems *dseq=NULL;
98 DcmItem *ditem=NULL;
99
100 dseq = new DcmSequenceOfItems(DCM_ReferencedSeriesSequence);
101 if (dseq)
102 {
103 OFListIterator(DVPSReferencedSeries *) first = list_.begin();
104 OFListIterator(DVPSReferencedSeries *) last = list_.end();
105 while (first != last)
106 {
107 if (result==EC_Normal)
108 {
109 ditem = new DcmItem();
110 if (ditem)
111 {
112 result = (*first)->write(*ditem);
113 if (result==EC_Normal) dseq->insert(ditem); else delete ditem;
114 } else result = EC_MemoryExhausted;
115 }
116 ++first;
117 }
118 if (result==EC_Normal) dset.insert(dseq, OFTrue /*replaceOld*/); else delete dseq;
119 } else result = EC_MemoryExhausted;
120 return result;
121 }
122
isValid()123 OFBool DVPSReferencedSeries_PList::isValid()
124 {
125 if (list_.size() == 0)
126 {
127 DCMPSTAT_WARN("referenced series SQ is empty in presentation state");
128 return OFFalse;
129 }
130
131 OFBool result = OFTrue;
132 OFString sopclassuid;
133
134 OFListIterator(DVPSReferencedSeries *) first = list_.begin();
135 OFListIterator(DVPSReferencedSeries *) last = list_.end();
136 while ((result == OFTrue) && (first != last))
137 {
138 result = (*first)->isValid(sopclassuid);
139 ++first;
140 }
141 return result;
142 }
143
checkSOPClass(const char * uid)144 OFBool DVPSReferencedSeries_PList::checkSOPClass(const char *uid)
145 {
146
147 OFBool result = OFTrue;
148 OFString sopclassuid(uid);
149 OFListIterator(DVPSReferencedSeries *) first = list_.begin();
150 OFListIterator(DVPSReferencedSeries *) last = list_.end();
151 while ((result == OFTrue) && (first != last))
152 {
153 result = (*first)->isValid(sopclassuid);
154 ++first;
155 }
156 return result;
157 }
158
removeImageReference(const char * seriesUID,const char * instanceUID)159 void DVPSReferencedSeries_PList::removeImageReference(const char *seriesUID, const char *instanceUID)
160 {
161 DVPSReferencedSeries *series = findSeriesReference(seriesUID);
162 if (series) series->removeImageReference(instanceUID);
163 return;
164 }
165
findSeriesReference(const char * seriesUID)166 DVPSReferencedSeries *DVPSReferencedSeries_PList::findSeriesReference(const char *seriesUID)
167 {
168 OFListIterator(DVPSReferencedSeries *) first = list_.begin();
169 OFListIterator(DVPSReferencedSeries *) last = list_.end();
170 while (first != last)
171 {
172 if ((*first)->isSeriesUID(seriesUID)) return *first;
173 ++first;
174 }
175 return NULL;
176 }
177
findImageReference(const char * seriesUID,const char * instanceUID)178 DVPSReferencedImage *DVPSReferencedSeries_PList::findImageReference(const char *seriesUID, const char *instanceUID)
179 {
180 DVPSReferencedSeries *series = findSeriesReference(seriesUID);
181 if (series) return series->findImageReference(instanceUID); else return NULL;
182 }
183
removeSeriesReference(const char * seriesUID)184 void DVPSReferencedSeries_PList::removeSeriesReference(const char *seriesUID)
185 {
186 OFListIterator(DVPSReferencedSeries *) first = list_.begin();
187 OFListIterator(DVPSReferencedSeries *) last = list_.end();
188 while (first != last)
189 {
190 if ((*first)->isSeriesUID(seriesUID))
191 {
192 delete (*first);
193 first = list_.erase(first);
194 } else ++first;
195 }
196 return;
197 }
198
addImageReference(const char * seriesUID,const char * sopclassUID,const char * instanceUID,const char * frames,const char * aetitle,const char * filesetID,const char * filesetUID)199 OFCondition DVPSReferencedSeries_PList::addImageReference(
200 const char *seriesUID,
201 const char *sopclassUID,
202 const char *instanceUID,
203 const char *frames,
204 const char *aetitle,
205 const char *filesetID,
206 const char *filesetUID)
207
208 {
209 if ((seriesUID==NULL) || (sopclassUID==NULL) || (instanceUID==NULL)) return EC_IllegalCall;
210
211 OFCondition result = EC_Normal;
212 if (checkSOPClass(sopclassUID))
213 {
214 DVPSReferencedSeries *series = findSeriesReference(seriesUID);
215 if (series == NULL)
216 {
217 series = new DVPSReferencedSeries();
218 if (series)
219 {
220 series->setSeriesInstanceUID(seriesUID);
221 list_.push_back(series);
222 }
223 }
224 if (series)
225 {
226 result = series->addImageReference(sopclassUID, instanceUID, frames);
227 if (EC_Normal == result) series->setRetrieveLocation(aetitle, filesetID, filesetUID);
228 } else result = EC_MemoryExhausted;
229 } else result = EC_IllegalCall;
230 return result;
231 }
232
233
numberOfImageReferences()234 size_t DVPSReferencedSeries_PList::numberOfImageReferences()
235 {
236 size_t result=0;
237 OFListIterator(DVPSReferencedSeries *) first = list_.begin();
238 OFListIterator(DVPSReferencedSeries *) last = list_.end();
239 while (first != last)
240 {
241 result += (*first)->numberOfImageReferences();
242 ++first;
243 }
244 return result;
245 }
246
getImageReference(size_t idx,OFString & seriesUID,OFString & sopclassUID,OFString & instanceUID,OFString & frames,OFString & aetitle,OFString & filesetID,OFString & filesetUID)247 OFCondition DVPSReferencedSeries_PList::getImageReference(
248 size_t idx,
249 OFString& seriesUID,
250 OFString& sopclassUID,
251 OFString& instanceUID,
252 OFString& frames,
253 OFString& aetitle,
254 OFString& filesetID,
255 OFString& filesetUID)
256 {
257 OFListIterator(DVPSReferencedSeries *) first = list_.begin();
258 OFListIterator(DVPSReferencedSeries *) last = list_.end();
259 OFBool found = OFFalse;
260 size_t i;
261 while ((!found)&&(first != last))
262 {
263 i=(*first)->numberOfImageReferences();
264 if (i > idx) found = OFTrue; else
265 {
266 idx -= i;
267 ++first;
268 }
269 }
270 if (found) return (*first)->getImageReference(idx, seriesUID, sopclassUID, instanceUID, frames, aetitle, filesetID, filesetUID);
271 return EC_IllegalCall;
272 }
273