vtk-dicom  0.8.17
vtkDICOMValue.h
1 /*=========================================================================
2 
3  Program: DICOM for VTK
4 
5  Copyright (c) 2012-2024 David Gobbi
6  All rights reserved.
7  See Copyright.txt or http://dgobbi.github.io/bsd3.txt for details.
8 
9  This software is distributed WITHOUT ANY WARRANTY; without even
10  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11  PURPOSE. See the above copyright notice for more information.
12 
13 =========================================================================*/
14 #ifndef vtkDICOMValue_h
15 #define vtkDICOMValue_h
16 
17 #include "vtkSystemIncludes.h"
18 #include "vtkDICOMModule.h" // For export macro
19 #include "vtkDICOMVR.h"
20 #include "vtkDICOMTag.h"
21 #include "vtkDICOMCharacterSet.h"
22 #include "vtkDICOMReferenceCount.h"
23 
24 #include <string>
25 
26 // type constants
27 #define VTK_DICOM_TAG 13
28 #define VTK_DICOM_ITEM 14
29 #define VTK_DICOM_VALUE 15
30 
31 // This adds an overflow byte for the "NumberOfValues" field, so that
32 // "NumberOfValues" can effectively go as high as 2^40-1. This means
33 // that data elements that use delimiters, rather than fixed lengths,
34 // can store up to one terabyte instead of being limited to four gigabytes.
35 #if defined(__x86_64__) || defined(__ia64__) || defined(_M_X64)
36 #define VTK_DICOM_USE_OVERFLOW_BYTE
37 #endif
38 
39 class vtkDICOMItem;
40 class vtkDICOMSequence;
41 
43 
50 class VTKDICOM_EXPORT vtkDICOMValue
51 {
52 private:
54  struct Value
55  {
56  vtkDICOMReferenceCount ReferenceCount;
57  unsigned char Type;
58  unsigned char CharacterSet;
59  unsigned char Overflow;
60  vtkDICOMVR VR;
61  unsigned int VL;
62  unsigned int NumberOfValues;
63 
64  Value() : ReferenceCount(1) {}
65  };
66 
68  template<class T>
69  struct ValueT : Value
70  {
71  T Data[1];
72 
73  ValueT(vtkDICOMVR vr, size_t vn);
74  static bool Compare(const Value *a, const Value *b);
75  static bool CompareEach(const Value *a, const Value *b);
76  };
77 
78 public:
79 
81 
93  vtkDICOMValue(vtkDICOMVR vr, double v);
94  vtkDICOMValue(vtkDICOMVR vr, const std::string& v);
97  vtkDICOMValue(vtkDICOMVR vr, const char *data, size_t count);
98  vtkDICOMValue(vtkDICOMVR vr, const unsigned char *data, size_t count);
99  vtkDICOMValue(vtkDICOMVR vr, const short *data, size_t count);
100  vtkDICOMValue(vtkDICOMVR vr, const unsigned short *data, size_t count);
101  vtkDICOMValue(vtkDICOMVR vr, const int *data, size_t count);
102  vtkDICOMValue(vtkDICOMVR vr, const unsigned int *data, size_t count);
103  vtkDICOMValue(vtkDICOMVR vr, const long long *data, size_t count);
104  vtkDICOMValue(vtkDICOMVR vr, const unsigned long long *data, size_t count);
105  vtkDICOMValue(vtkDICOMVR vr, const float *data, size_t count);
106  vtkDICOMValue(vtkDICOMVR vr, const double *data, size_t count);
107  vtkDICOMValue(vtkDICOMVR vr, const vtkDICOMTag *data, size_t count);
108  vtkDICOMValue(vtkDICOMVR vr, const vtkDICOMItem *data, size_t count);
110 
112 
120  const std::string& v);
122  const char *data, size_t l);
124 
126  explicit vtkDICOMValue(vtkDICOMVR vr);
128 
130  vtkDICOMValue(const vtkDICOMValue &v) : V(v.V) {
131  if (this->V) { ++(this->V->ReferenceCount); } }
132 
135 
138 
142 
144  vtkDICOMValue() : V(nullptr) {}
146 
148  ~vtkDICOMValue() { this->Clear(); }
150 
152 
161  vtkDICOMVR vr, vtkDICOMCharacterSet cs, const std::string& v);
163 
165  void Clear() {
167  if (this->V && --(this->V->ReferenceCount) == 0) {
168  this->FreeValue(this->V); }
169  this->V = nullptr; }
170 
172  bool IsValid() const { return (this->V != nullptr); }
174 
176  vtkDICOMVR GetVR() const { return (this->V ? this->V->VR : vtkDICOMVR()); }
178 
180  unsigned int GetVL() const { return (this->V ? this->V->VL : 0); }
181 
183 
191  return (this->V ? this->V->CharacterSet : 0); }
192 
194 
207  size_t GetNumberOfValues() const {
208  return (this->V ? this->V->NumberOfValues
209 #ifdef VTK_DICOM_USE_OVERFLOW_BYTE
210  + (static_cast<size_t>(this->V->Overflow) << 32)
211 #endif
212  : 0); }
214 
216 
223  void GetValues(std::string *vb, size_t n, size_t i=0) const;
224  void GetValues(unsigned char *vb, size_t n, size_t i=0) const;
225  void GetValues(short *vb, size_t n, size_t i=0) const;
226  void GetValues(unsigned short *vb, size_t n, size_t i=0) const;
227  void GetValues(int *vb, size_t n, size_t i=0) const;
228  void GetValues(unsigned int *vb, size_t n, size_t i=0) const;
229  void GetValues(long long *vb, size_t n, size_t i=0) const;
230  void GetValues(unsigned long long *vb, size_t n, size_t i=0) const;
231  void GetValues(float *vb, size_t n, size_t i=0) const;
232  void GetValues(double *vb, size_t n, size_t i=0) const;
233  void GetValues(vtkDICOMTag *vb, size_t n, size_t i=0) const;
235 
237 
245  std::string GetUTF8String(size_t i) const;
246  std::string GetString(size_t i) const;
247  unsigned char GetUnsignedChar(size_t i) const;
248  short GetShort(size_t i) const;
249  unsigned short GetUnsignedShort(size_t i) const;
250  int GetInt(size_t i) const;
251  unsigned int GetUnsignedInt(size_t i) const;
252  long long GetInt64(size_t i) const;
253  unsigned long long GetUnsignedInt64(size_t i) const;
254  float GetFloat(size_t i) const;
255  double GetDouble(size_t i) const;
256  vtkDICOMTag GetTag(size_t i) const;
257  const vtkDICOMItem& GetItem(size_t i) const;
259 
261 
269  std::string AsUTF8String() const;
270  std::string AsString() const;
271  unsigned char AsUnsignedChar() const;
272  short AsShort() const;
273  unsigned short AsUnsignedShort() const;
274  int AsInt() const;
275  unsigned int AsUnsignedInt() const;
276  long long AsInt64() const;
277  unsigned long long AsUnsignedInt64() const;
278  float AsFloat() const;
279  double AsDouble() const;
280  vtkDICOMTag AsTag() const;
281  const vtkDICOMItem& AsItem() const;
283 
285 
299  const char *GetCharData() const;
300  const unsigned char *GetUnsignedCharData() const;
301  const short *GetShortData() const;
302  const unsigned short *GetUnsignedShortData() const;
303  const int *GetIntData() const;
304  const unsigned int *GetUnsignedIntData() const;
305  const long long *GetInt64Data() const;
306  const unsigned long long *GetUnsignedInt64Data() const;
307  const float *GetFloatData() const;
308  const double *GetDoubleData() const;
309  const vtkDICOMTag *GetTagData() const;
310  const vtkDICOMItem *GetSequenceData() const;
311  const vtkDICOMValue *GetMultiplexData() const;
313 
315 
323  char *AllocateCharData(vtkDICOMVR vr, size_t vn);
324  char *AllocateCharData(
325  vtkDICOMVR vr, vtkDICOMCharacterSet cs, size_t vn);
326  unsigned char *AllocateUnsignedCharData(vtkDICOMVR vr, size_t vn);
327  short *AllocateShortData(vtkDICOMVR vr, size_t vn);
328  unsigned short *AllocateUnsignedShortData(vtkDICOMVR vr, size_t vn);
329  int *AllocateIntData(vtkDICOMVR vr, size_t vn);
330  unsigned int *AllocateUnsignedIntData(vtkDICOMVR vr, size_t vn);
331  long long *AllocateInt64Data(vtkDICOMVR vr, size_t vn);
332  unsigned long long *AllocateUnsignedInt64Data(vtkDICOMVR vr, size_t vn);
333  float *AllocateFloatData(vtkDICOMVR vr, size_t vn);
334  double *AllocateDoubleData(vtkDICOMVR vr, size_t vn);
335  vtkDICOMTag *AllocateTagData(vtkDICOMVR vr, size_t vn);
336  vtkDICOMItem *AllocateSequenceData(vtkDICOMVR vr, size_t vn);
337  vtkDICOMValue *AllocateMultiplexData(vtkDICOMVR vr, size_t vn);
339 
341 
348 
350 
356  unsigned char *ReallocateUnsignedCharData(size_t vn);
358 
360  /*
362  * String values will be converted from their native encoding
363  * to UTF-8.
364  */
365  void AppendValueToUTF8String(std::string &str, size_t i) const;
366 
368  /*
370  * This method will check for control characters or unconvertible
371  * characters in the value, and will replace them with four-byte
372  * codes of the form '\ooo' where 'o' is an octal digit.
373  */
374  void AppendValueToSafeUTF8String(std::string &str, size_t i) const;
375 
377 
383  void AppendValueToString(std::string &str, size_t i) const;
385 
387 
396  bool Matches(const vtkDICOMValue& value) const;
397 
399 
408  bool Matches(const std::string& v) const;
409 
411 
417  bool Matches(double v) const;
419 
421  vtkDICOMValue& operator=(const vtkDICOMValue& o) {
423  if (this->V != o.V) {
424  if (o.V) { ++(o.V->ReferenceCount); }
425  if (this->V) {
426  if (--(this->V->ReferenceCount) == 0) { this->FreeValue(this->V); } }
427  this->V = o.V; }
428  return *this; }
429 
433 
435  bool operator==(const vtkDICOMValue& o) const;
437  bool operator!=(const vtkDICOMValue& o) const { return !(*this == o); }
439 
440 private:
442  template<class T>
443  T *Allocate(vtkDICOMVR vr, size_t vn);
444 
446  static void FreeValue(Value *v);
447 
449  template<class OT>
450  void GetValuesT(OT *v, size_t count, size_t s) const;
451 
453  template<class T>
454  void CreateValue(vtkDICOMVR vr, const T *data, size_t count);
455 
457  template<class T>
458  void AppendInit(vtkDICOMVR vr);
459 
461  template<class T>
462  void AppendValue(const T &item);
463 
465  template<class T>
466  void SetValue(size_t i, const T &item);
467 
469  vtkDICOMValue *GetMultiplex();
470 
472  void Substring(size_t i, const char *&start, const char *&end) const;
473 
475  void CreateValueWithSpecificCharacterSet(
476  vtkDICOMVR vr, vtkDICOMCharacterSet cs, const char *data, size_t l);
477 
479 
486  size_t CreateValueFromUTF8(
487  vtkDICOMVR vr, vtkDICOMCharacterSet cs, const char *data, size_t l);
488 
490  static bool PatternMatches(
491  const char *pattern, const char *pe, const char *val, const char *ve);
492 
494  static bool PatternMatchesMulti(
495  const char *pattern, const char *val, vtkDICOMVR vr);
496 
498 
503  static size_t NormalizeDateTime(
504  const char *input, char output[22], vtkDICOMVR vr);
505 
507 
513  static bool PatternMatchesPersonName(const char *pattern, const char *val);
514 
516 
522  static void NormalizePersonName(
523  const char *input, char output[256], bool isquery=false);
524 
526  Value *V;
527 
529  static const vtkDICOMItem EmptyItem;
530 
531  // friend the sequence class, it requires AppendValue() and SetValue().
532  friend class vtkDICOMSequence;
533 
534  // friend the meta data class, it requires GetMultiplex().
535  friend class vtkDICOMValueFriendMetaData;
536 };
537 
539 // This friendship class allows vtkDICOMMetaData to use exactly one
540 // private method from vtkDICOMValue.
541 class vtkDICOMValueFriendMetaData
542 {
543  static vtkDICOMValue *GetMultiplex(vtkDICOMValue *v) {
544  return v->GetMultiplex(); }
545 
546  friend class vtkDICOMMetaData;
547 };
549 
550 VTKDICOM_EXPORT ostream& operator<<(ostream& os, const vtkDICOMValue& v);
551 
552 #endif /* vtkDICOMValue_h */
553 // VTK-HeaderTest-Exclude: vtkDICOMValue.h
Character sets.
Definition: vtkDICOMCharacterSet.h:55
An item in a DICOM sequence (type SQ).
Definition: vtkDICOMItem.h:34
A container class for DICOM metadata.
Definition: vtkDICOMMetaData.h:44
An object for holding an atomic reference count.
Definition: vtkDICOMReferenceCount.h:27
A sequence of items according to the SQ representation.
Definition: vtkDICOMSequence.h:32
A (group,element) identifier tag for DICOM attributes.
Definition: vtkDICOMTag.h:23
VRs (Value Representations)
Definition: vtkDICOMVR.h:22
A class to store attribute values for DICOM metadata.
Definition: vtkDICOMValue.h:51
bool IsValid() const
Check whether this value is valid, i.e. contains data.
Definition: vtkDICOMValue.h:172
size_t GetNumberOfValues() const
Get the value multiplicity.
Definition: vtkDICOMValue.h:207
vtkDICOMValue(vtkDICOMVR vr, vtkDICOMCharacterSet cs, const std::string &v)
Construct a string value with a specific character set.
std::string GetUTF8String(size_t i) const
Get one scalar, string, tag or item from the value.
vtkDICOMValue(const vtkDICOMSequence &v)
Construct from a sequence.
char * AllocateCharData(vtkDICOMVR vr, size_t vn)
Allocate space within a value object.
static vtkDICOMValue FromUTF8String(vtkDICOMVR vr, vtkDICOMCharacterSet cs, const std::string &v)
Create a value from a UTF8-encoded string.
bool Matches(double v) const
Check if the value is the specified numeric value.
void ComputeNumberOfValuesForCharData()
Compute the number of backslash-separated string values.
vtkDICOMValue(vtkDICOMTag v)
Construct from a tag.
void AppendValueToSafeUTF8String(std::string &str, size_t i) const
Append value "i" to the supplied UTF8 string for safe printing.
const char * GetCharData() const
Get a pointer to the internal data array.
void AppendValueToString(std::string &str, size_t i) const
Append value "i" to the supplied string.
vtkDICOMValue & operator=(const vtkDICOMSequence &o)
Assign a value from a sequence object.
vtkDICOMValue(const vtkDICOMValue &v)
Copy constructor.
Definition: vtkDICOMValue.h:130
vtkDICOMValue(const vtkDICOMItem &v)
Construct from an item.
vtkDICOMCharacterSet GetCharacterSet() const
Get the character set for a text value.
Definition: vtkDICOMValue.h:190
void GetValues(std::string *vb, size_t n, size_t i=0) const
Copy "n" values into vb, starting at value "i".
vtkDICOMValue(vtkDICOMVR vr, double v)
Construct a new value from the data that is provided.
bool Matches(const std::string &v) const
Check if the value is equal to the specified string.
void AppendValueToUTF8String(std::string &str, size_t i) const
Append value "i" to the supplied UTF8 string.
std::string AsUTF8String() const
Get the value as a scalar, string, tag, or item.
unsigned char * ReallocateUnsignedCharData(size_t vn)
Reallocate data of type OB or UN.
unsigned int GetVL() const
Get the VL, the length of the data in bytes (will always be even).
Definition: vtkDICOMValue.h:180
~vtkDICOMValue()
Destructor releases the internal data array.
Definition: vtkDICOMValue.h:148
bool Matches(const vtkDICOMValue &value) const
Check if the value matches the specified find query value.