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: DVPSGraphicAnnotation_PList
20 *
21 */
22
23 #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
24 #include "dcmtk/dcmpstat/dvpsgal.h"
25 #include "dcmtk/dcmpstat/dvpsga.h" /* for DVPSGraphicAnnotation */
26 #include "dcmtk/ofstd/ofstring.h" /* for OFString */
27 #include "dcmtk/dcmpstat/dvpstx.h" /* for DVPSTextObject */
28 #include "dcmtk/dcmpstat/dvpsgr.h" /* for DVPSGraphicObject */
29 #include "dcmtk/dcmpstat/dvpsri.h" /* for DVPSReferencedImage, needed by MSVC5 with STL */
30
DVPSGraphicAnnotation_PList()31 DVPSGraphicAnnotation_PList::DVPSGraphicAnnotation_PList()
32 : list_()
33 {
34 }
35
DVPSGraphicAnnotation_PList(const DVPSGraphicAnnotation_PList & arg)36 DVPSGraphicAnnotation_PList::DVPSGraphicAnnotation_PList(const DVPSGraphicAnnotation_PList &arg)
37 : list_()
38 {
39 OFListConstIterator(DVPSGraphicAnnotation *) first = arg.list_.begin();
40 OFListConstIterator(DVPSGraphicAnnotation *) last = arg.list_.end();
41 while (first != last)
42 {
43 list_.push_back((*first)->clone());
44 ++first;
45 }
46 }
47
~DVPSGraphicAnnotation_PList()48 DVPSGraphicAnnotation_PList::~DVPSGraphicAnnotation_PList()
49 {
50 clear();
51 }
52
clear()53 void DVPSGraphicAnnotation_PList::clear()
54 {
55 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
56 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
57 while (first != last)
58 {
59 delete (*first);
60 first = list_.erase(first);
61 }
62 }
63
read(DcmItem & dset)64 OFCondition DVPSGraphicAnnotation_PList::read(DcmItem &dset)
65 {
66 OFCondition result = EC_Normal;
67 DcmStack stack;
68 DVPSGraphicAnnotation *newObject = NULL;
69 DcmSequenceOfItems *dseq=NULL;
70 DcmItem *ditem=NULL;
71
72 if (EC_Normal == dset.search(DCM_GraphicAnnotationSequence, 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 newObject = new DVPSGraphicAnnotation();
82 if (newObject && ditem)
83 {
84 result = newObject->read(*ditem);
85 list_.push_back(newObject);
86 } else result = EC_MemoryExhausted;
87 }
88 }
89 }
90
91 return result;
92 }
93
write(DcmItem & dset)94 OFCondition DVPSGraphicAnnotation_PList::write(DcmItem &dset)
95 {
96 if (list_.size()==0) return EC_Normal; // don't write empty Sequence
97
98 OFCondition result = EC_Normal;
99 DcmSequenceOfItems *dseq=NULL;
100 DcmItem *ditem=NULL;
101
102 dseq = new DcmSequenceOfItems(DCM_GraphicAnnotationSequence);
103 if (dseq)
104 {
105 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
106 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
107 while (first != last)
108 {
109 if (result==EC_Normal)
110 {
111 ditem = new DcmItem();
112 if (ditem)
113 {
114 result = (*first)->write(*ditem);
115 if (result==EC_Normal) dseq->insert(ditem); else delete ditem;
116 } else result = EC_MemoryExhausted;
117 }
118 ++first;
119 }
120 if (result==EC_Normal) dset.insert(dseq, OFTrue /*replaceOld*/); else delete dseq;
121 } else result = EC_MemoryExhausted;
122 return result;
123 }
124
125
renameLayer(const char * oldName,const char * newName)126 void DVPSGraphicAnnotation_PList::renameLayer(const char *oldName, const char *newName)
127 {
128 if ((oldName==NULL)||(newName==NULL)) return;
129
130 OFString aString(oldName);
131 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
132 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
133 while (first != last)
134 {
135 if (aString == (*first)->getAnnotationLayer())
136 {
137 (*first)->setAnnotationLayer(newName);
138 }
139 ++first;
140 }
141 return;
142 }
143
removeLayer(const char * name)144 void DVPSGraphicAnnotation_PList::removeLayer(const char *name)
145 {
146 if (name==NULL) return;
147
148 OFString aString(name);
149 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
150 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
151 while (first != last)
152 {
153 if (aString == (*first)->getAnnotationLayer())
154 {
155 delete (*first);
156 first = list_.erase(first);
157 } else ++first;
158 }
159 return;
160 }
161
cleanupLayers()162 void DVPSGraphicAnnotation_PList::cleanupLayers()
163 {
164 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
165 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
166 while (first != last)
167 {
168 if ((*first)->isEmpty())
169 {
170 delete (*first);
171 first = list_.erase(first);
172 } else ++first;
173 }
174 return;
175 }
176
177
usesLayerName(const char * name)178 OFBool DVPSGraphicAnnotation_PList::usesLayerName(const char *name)
179 {
180 if (name==NULL) return OFFalse;
181
182 OFString aString(name);
183 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
184 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
185 while (first != last)
186 {
187 if (aString == (*first)->getAnnotationLayer()) return OFTrue;
188 ++first;
189 }
190 return OFFalse;
191 }
192
193
getNumberOfTextObjects(const char * layer,const char * instanceUID,unsigned long frame)194 size_t DVPSGraphicAnnotation_PList::getNumberOfTextObjects(const char *layer, const char *instanceUID, unsigned long frame)
195 {
196 if (layer==NULL) return 0;
197
198 size_t result = 0;
199 OFString aString(layer);
200 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
201 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
202 while (first != last)
203 {
204 if ((aString == (*first)->getAnnotationLayer()) && ((*first)->isApplicable(instanceUID, frame)))
205 {
206 result += (*first)->getNumberOfTextObjects();
207 }
208 ++first;
209 }
210 return result;
211 }
212
getTextObject(const char * layer,const char * instanceUID,unsigned long frame,size_t idx)213 DVPSTextObject *DVPSGraphicAnnotation_PList::getTextObject(const char *layer, const char *instanceUID, unsigned long frame, size_t idx)
214 {
215 if (layer==NULL) return NULL;
216
217 size_t tmp = 0;
218 OFString aString(layer);
219 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
220 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
221 while (first != last)
222 {
223 if ((aString == (*first)->getAnnotationLayer()) && ((*first)->isApplicable(instanceUID, frame)))
224 {
225 tmp = (*first)->getNumberOfTextObjects();
226 if (idx < tmp) return (*first)->getTextObject(idx); else idx -= tmp;
227 }
228 ++first;
229 }
230 return NULL;
231 }
232
233
addTextObject(const char * layer,const char * sopclassUID,const char * instanceUID,unsigned long frame,DVPSObjectApplicability applicability,DVPSTextObject * text)234 DVPSTextObject *DVPSGraphicAnnotation_PList::addTextObject(
235 const char *layer,
236 const char *sopclassUID,
237 const char *instanceUID,
238 unsigned long frame,
239 DVPSObjectApplicability applicability,
240 DVPSTextObject *text)
241 {
242 if (layer==NULL) return NULL;
243
244 if (text==NULL)
245 {
246 text = new DVPSTextObject();
247 }
248 if (text==NULL) return NULL;
249
250 DVPSGraphicAnnotation *annotation = NULL;
251 OFString aString(layer);
252 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
253 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
254 while (first != last)
255 {
256 if ((aString == (*first)->getAnnotationLayer()) && ((*first)->isApplicable(instanceUID, frame, applicability)))
257 {
258 annotation = *first;
259 first = last;
260 } else ++first;
261 }
262
263 if (annotation==NULL)
264 {
265 annotation = new DVPSGraphicAnnotation();
266 if (annotation)
267 {
268 annotation->setAnnotationLayer(layer);
269 if (applicability != DVPSB_allImages) annotation->addImageReference(sopclassUID, instanceUID, frame, applicability);
270 list_.push_back(annotation);
271 }
272 }
273
274 if (annotation)
275 {
276 annotation->addTextObject(text);
277 return text;
278 }
279
280 delete text;
281 return NULL;
282 }
283
284
removeTextObject(const char * layer,const char * instanceUID,unsigned long frame,size_t idx)285 OFCondition DVPSGraphicAnnotation_PList::removeTextObject(const char *layer, const char *instanceUID, unsigned long frame, size_t idx)
286 {
287 if (layer==NULL) return EC_IllegalCall;
288
289 size_t tmp = 0;
290 OFString aString(layer);
291 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
292 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
293 while (first != last)
294 {
295 if ((aString == (*first)->getAnnotationLayer()) && ((*first)->isApplicable(instanceUID, frame)))
296 {
297 tmp = (*first)->getNumberOfTextObjects();
298 if (idx < tmp)
299 {
300 DVPSTextObject *textObject = (*first)->removeTextObject(idx);
301 if (textObject)
302 {
303 delete textObject;
304 return EC_Normal;
305 } else return EC_IllegalCall;
306 } else idx -= tmp;
307 }
308 ++first;
309 }
310 return EC_IllegalCall;
311 }
312
313
moveTextObject(const char * old_layer,const char * sopclassUID,const char * instanceUID,unsigned long frame,size_t idx,DVPSObjectApplicability applicability,const char * new_layer)314 OFCondition DVPSGraphicAnnotation_PList::moveTextObject(
315 const char *old_layer,
316 const char *sopclassUID,
317 const char *instanceUID,
318 unsigned long frame,
319 size_t idx,
320 DVPSObjectApplicability applicability,
321 const char *new_layer)
322 {
323 if (old_layer==NULL) return EC_IllegalCall;
324 if (new_layer==NULL) return EC_IllegalCall;
325
326 size_t tmp = 0;
327 OFString aString(old_layer);
328 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
329 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
330 while (first != last)
331 {
332 if ((aString == (*first)->getAnnotationLayer()) && ((*first)->isApplicable(instanceUID, frame)))
333 {
334 tmp = (*first)->getNumberOfTextObjects();
335 if (idx < tmp)
336 {
337 DVPSTextObject *textObject = (*first)->removeTextObject(idx);
338 if (textObject)
339 {
340 textObject = addTextObject(new_layer, sopclassUID, instanceUID, frame, applicability, textObject);
341 if (textObject) return EC_Normal; else return EC_MemoryExhausted;
342 } else return EC_IllegalCall;
343 } else idx -= tmp;
344 }
345 ++first;
346 }
347 return EC_IllegalCall;
348 }
349
350
getNumberOfGraphicObjects(const char * layer,const char * instanceUID,unsigned long frame)351 size_t DVPSGraphicAnnotation_PList::getNumberOfGraphicObjects(const char *layer, const char *instanceUID, unsigned long frame)
352 {
353 if (layer==NULL) return 0;
354
355 size_t result = 0;
356 OFString aString(layer);
357 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
358 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
359 while (first != last)
360 {
361 if ((aString == (*first)->getAnnotationLayer()) && ((*first)->isApplicable(instanceUID, frame)))
362 {
363 result += (*first)->getNumberOfGraphicObjects();
364 }
365 ++first;
366 }
367 return result;
368 }
369
getGraphicObject(const char * layer,const char * instanceUID,unsigned long frame,size_t idx)370 DVPSGraphicObject *DVPSGraphicAnnotation_PList::getGraphicObject(const char *layer, const char *instanceUID, unsigned long frame, size_t idx)
371 {
372 if (layer==NULL) return NULL;
373
374 size_t tmp = 0;
375 OFString aString(layer);
376 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
377 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
378 while (first != last)
379 {
380 if ((aString == (*first)->getAnnotationLayer()) && ((*first)->isApplicable(instanceUID, frame)))
381 {
382 tmp = (*first)->getNumberOfGraphicObjects();
383 if (idx < tmp) return (*first)->getGraphicObject(idx); else idx -= tmp;
384 }
385 ++first;
386 }
387 return NULL;
388 }
389
390
addGraphicObject(const char * layer,const char * sopclassUID,const char * instanceUID,unsigned long frame,DVPSObjectApplicability applicability,DVPSGraphicObject * graphic)391 DVPSGraphicObject *DVPSGraphicAnnotation_PList::addGraphicObject(
392 const char *layer,
393 const char *sopclassUID,
394 const char *instanceUID,
395 unsigned long frame,
396 DVPSObjectApplicability applicability,
397 DVPSGraphicObject *graphic)
398 {
399 if (layer==NULL) return NULL;
400
401 if (graphic==NULL) graphic = new DVPSGraphicObject();
402 if (graphic==NULL) return NULL;
403
404 DVPSGraphicAnnotation *annotation = NULL;
405 OFString aString(layer);
406 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
407 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
408 while (first != last)
409 {
410 if ((aString == (*first)->getAnnotationLayer()) && ((*first)->isApplicable(instanceUID, frame, applicability)))
411 {
412 annotation = *first;
413 first = last;
414 } else ++first;
415 }
416
417 if (annotation==NULL)
418 {
419 annotation = new DVPSGraphicAnnotation();
420 if (annotation)
421 {
422 annotation->setAnnotationLayer(layer);
423 if (applicability != DVPSB_allImages) annotation->addImageReference(sopclassUID, instanceUID, frame, applicability);
424 list_.push_back(annotation);
425 }
426 }
427
428 if (annotation)
429 {
430 annotation->addGraphicObject(graphic);
431 return graphic;
432 }
433
434 delete graphic;
435 return NULL;
436 }
437
438
removeGraphicObject(const char * layer,const char * instanceUID,unsigned long frame,size_t idx)439 OFCondition DVPSGraphicAnnotation_PList::removeGraphicObject(const char *layer, const char *instanceUID, unsigned long frame, size_t idx)
440 {
441 if (layer==NULL) return EC_IllegalCall;
442
443 size_t tmp = 0;
444 OFString aString(layer);
445 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
446 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
447 while (first != last)
448 {
449 if ((aString == (*first)->getAnnotationLayer()) && ((*first)->isApplicable(instanceUID, frame)))
450 {
451 tmp = (*first)->getNumberOfGraphicObjects();
452 if (idx < tmp)
453 {
454 DVPSGraphicObject *graphicObject = (*first)->removeGraphicObject(idx);
455 if (graphicObject)
456 {
457 delete graphicObject;
458 return EC_Normal;
459 } else return EC_IllegalCall;
460 } else idx -= tmp;
461 }
462 ++first;
463 }
464 return EC_IllegalCall;
465 }
466
467
moveGraphicObject(const char * old_layer,const char * sopclassUID,const char * instanceUID,unsigned long frame,size_t idx,DVPSObjectApplicability applicability,const char * new_layer)468 OFCondition DVPSGraphicAnnotation_PList::moveGraphicObject(
469 const char *old_layer,
470 const char *sopclassUID,
471 const char *instanceUID,
472 unsigned long frame,
473 size_t idx,
474 DVPSObjectApplicability applicability,
475 const char *new_layer)
476 {
477 if (old_layer==NULL) return EC_IllegalCall;
478 if (new_layer==NULL) return EC_IllegalCall;
479
480 size_t tmp = 0;
481 OFString aString(old_layer);
482 OFListIterator(DVPSGraphicAnnotation *) first = list_.begin();
483 OFListIterator(DVPSGraphicAnnotation *) last = list_.end();
484 while (first != last)
485 {
486 if ((aString == (*first)->getAnnotationLayer()) && ((*first)->isApplicable(instanceUID, frame)))
487 {
488 tmp = (*first)->getNumberOfGraphicObjects();
489 if (idx < tmp)
490 {
491 DVPSGraphicObject *graphicObject = (*first)->removeGraphicObject(idx);
492 if (graphicObject)
493 {
494 graphicObject = addGraphicObject(new_layer, sopclassUID, instanceUID, frame, applicability, graphicObject);
495 if (graphicObject) return EC_Normal; else return EC_MemoryExhausted;
496 } else return EC_IllegalCall;
497 } else idx -= tmp;
498 }
499 ++first;
500 }
501 return EC_IllegalCall;
502 }
503