For proto_tree_add_item(..., proto_xxx, ...)use ENC_NA as the encoding arg.
[obnox/wireshark/wip.git] / epan / dissectors / packet-dcm.c
1 /* packet-dcm.c
2  * Routines for DICOM dissection
3  * Copyright 2003, Rich Coe <Richard.Coe@med.ge.com>
4  * Copyright 2008-2010, David Aggeler <david_aggeler@hispeed.ch>
5  *
6  * DICOM communication protocol
7  * http://medical.nema.org/dicom/2008
8  *   DICOM Part 8: Network Communication Support for Message Exchange
9  *
10  * $Id$
11  *
12  * Wireshark - Network traffic analyzer
13  * By Gerald Combs <gerald@wireshark.org>
14  * Copyright 1998 Gerald Combs
15  *
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version 2
19  * of the License, or (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29  */
30
31
32 /* History:
33  * This dissector was originally coded by Rich Coe and then modified by David Aggeler
34  * **********************************************************************************
35  * ToDo
36  *
37  * - Syntax detection, in case an association request is missing in capture
38  * - Read private tags from configuration and parse in capture
39  * - dissect_dcm_heuristic() to return proper data type
40  *
41  * Jul 11, 2010 - David Aggeler
42  *
43  * - Finally, better reassembly using fragment_add_seq_next().
44  *   The previous mode is still supported.
45  * - Fixed sporadic decoding and export issues. Always decode
46  *   association negotiation, since performance check (tree==NULL)
47  *   is now only in dissect_dcm_pdv_fragmented().
48  * - Added one more PDV length check
49  * - Show Association Headers as individual items
50  * - Code cleanup. i.e. moved a few lookup functions to be closer to the dissection
51  *
52  * May 13, 2010 - David Aggeler (SVN 32815)
53  *
54  * - Fixed HF to separate signed & unsigned values and to have BASE_DEC all signed ones
55  * - Fixed private sequences with undefined length in ILE
56  * - Fixed some spellings in comments
57  *
58  * May 27, 2009 - David Aggeler (SVN 29060)
59  *
60  * - Fixed corrupt files on DICOM Export
61  * - Fixed memory limitation on DICOM Export
62  * - Removed minimum packet length for static port mode
63  * - Simplified checks for heuristic mode
64  * - Removed unused functions
65  *
66  * May 17, 2009 - David Aggeler (SVN 28392)
67  *
68  * - Spelling
69  * - Added expert_add_info() for status responses with warning & error level
70  * - Added command details in info column (optionally)
71  *
72  * Dec 19, 2008 to Mar 29, 2009 - Misc (SVN 27880)
73  *
74  * - Spellings, see SVN
75  *
76  * Oct 26, 2008 - David Aggeler (SVN 26662)
77  *
78  * - Support remaining DICOM/ARCNEMA tags
79  *
80  * Oct 12, 2008 - David Aggeler (SVN 26424)
81  *
82  * - Follow-up checkin 26417
83  *
84  * Oct 3, 2008 - David Aggeler (SVN 26417)
85  *
86  * - DICOM Tags: Support all tags, except for group 1000, 7Fxx
87  *               and tags (0020,3100 to 0020, 31FF).
88  *               Luckily these ones are retired anyhow
89  * - DICOM Tags: Optionally show sequences, items and tags as subtree
90  * - DICOM Tags: Certain items do have a summary of a few contained tags
91  * - DICOM Tags: Support all defined VR representations
92  * - DICOM Tags: For Explicit Syntax, use VR in the capture
93  * - DICOM Tags: Lookup UIDs
94  * - DICOM Tags: Handle split at PDV start and end. RT Structures were affected by this.
95  * - DICOM Tags: Handle split in tag header
96  *
97  * - Added all status messages from PS 3.4 & PS 3.7
98  * - Fixed two more type warnings on solaris, i.e. (gchar *)tvb_get_ephemeral_string
99  * - Replaced all ep_alloc() with ep_alloc0() and se_alloc() with se_alloc0()
100  * - Replaced g_strdup with ep_strdup() or se_strdup()
101  * - Show multiple PDU description in COL_INFO, not just last one. Still not all, but more
102  *   sophisticated logic for this column is probably overkill
103  * - Since DICOM is a 32 bit protocol with all length items specified unsigned
104  *   all offset & position variables are now declared as guint32 for dissect_dcm_pdu and
105  *   its nested functions. dissect_dcm_main() remained by purpose on int,
106  *   since we request data consolidation, requiring a TRUE as return value
107  * - Decode DVTk streams when using defined ports (not in heuristic mode)
108  * - Changed to warning level 4 (for MSVC) and fixed the warnings
109  * - Code cleanup & removed last DISSECTOR_ASSERT()
110  *
111  * Jul 25, 2008 - David Aggeler (SVN 25834)
112  *
113  * - Replaced guchar with gchar, since it caused a lot of warnings on solaris.
114  * - Moved a little more form the include to this one to be consistent
115  *
116  * Jul 17, 2008 - David Aggeler
117  *
118  * - Export objects as part 10 compliant DICOM file. Finally, this major milestone has been reached.
119  * - PDVs are now a child of the PCTX rather than the ASSOC object.
120  * - Fixed PDV continuation for unknown tags (e.g. RT Structure Set)
121  * - Replaced proprietary trim() with g_strstrip()
122  * - Fixed strings that are displayed with /000 (padding of odd length)
123  * - Added expert_add_info() for invalid flags and presentation context IDs
124  *
125  * Jun 17, 2008 - David Aggeler
126  *
127  * - Support multiple PDVs per PDU
128  * - Better summary, in PDV, PDU header and in INFO Column, e.g. show commands like C-STORE
129  * - Fixed Association Reject (was working before my changes)
130  * - Fixed PDV Continuation with very small packets. Reduced minimum packet length
131  *   from 10 to 2 Bytes for PDU Type 4
132  * - Fixed PDV Continuation. Last packet was not found correctly.
133  * - Fixed compilation warning (build 56 on solaris)
134  * - Fixed tree expansion (hf_dcm_xxx)
135  * - Added expert_add_info() for Association Reject
136  * - Added expert_add_info() for Association Abort
137  * - Added expert_add_info() for short PDVs (i.e. last fragment, but PDV is not completed yet)
138  * - Clarified and grouped data structures and its related code (dcmItem, dcmState) to have
139  *   consistent _new() & _get() functions and to be be according to coding conventions
140  * - Added more function declaration to be more consistent
141  * - All dissect_dcm_xx now have (almost) the same parameter order
142  * - Removed DISSECTOR_ASSERT() for packet data errors. Not designed to handle this.
143  * - Handle multiple DICOM Associations in a capture correctly, i.e. if presentation contexts are different.
144  *
145  * May 23, 2008 - David Aggeler
146  *
147  * - Added Class UID lookup, both in the association and in the transfer
148  * - Better hierarchy for items in Association request/response and therefore better overview
149  *   This was a major rework. Abstract Syntax & Transfer Syntax are now children
150  *   of a presentation context and therefore grouped. User Info is now grouped.
151  * - Re-assemble PDVs that span multiple PDUs, i.e fix continuation packets
152  *   This caused significant changes to the data structures
153  * - Added preference with dicom tcp ports, to prevent 'stealing' the conversation
154  *   i.e. don't just rely on heuristic
155  * - Use pinfo->desegment_len instead of tcp_dissect_pdus()
156  * - Returns number of bytes parsed
157  * - For non DICOM packets, do not allocate any memory anymore,
158  * - Added one DISSECTOR_ASSERT() to prevent loop with len==0. More to come
159  * - Heuristic search is optional to save resources for non DICOM users
160  *
161  * - Output naming closer to DICOM Standard
162  * - Variable names closer to Standard
163  * - Protocol in now called DICOM not dcm anymore.
164  * - Fixed type of a few variables to guchar instead of guint8
165  * - Changed some of the length displays to decimal, because the hex value can
166  *   already be seen in the packet and decimal is easier for length calculation
167  *   in respect to TCP
168  *
169  * Apr 28, 2005 - Rich Coe
170  *
171  * - fix memory leak when Assoc packet is processed repeatedly in wireshark
172  * - removed unused partial packet flag
173  * - added better support for DICOM VR
174  *      - sequences
175  *      - report actual VR in packet display, if supplied by xfer syntax
176  *      - show that we are not displaying entire tag string with '[...]',
177  *        some tags can hold up to 2^32-1 chars
178  *
179  * - remove my goofy attempt at trying to get access to the fragmented packets
180  * - process all the data in the Assoc packet even if display is off
181  * - limit display of data in Assoc packet to defined size of the data even
182  *   if reported size is larger
183  * - show the last tag in a packet as [incomplete] if we don't have all the data
184  * - added framework for reporting DICOM async negotiation (not finished)
185  *   (I'm not aware of an implementation which currently supports this)
186  *
187  * Nov 9, 2004 - Rich Coe
188  *
189  * - Fixed the heuristic code -- sometimes a conversation already exists
190  * - Fixed the dissect code to display all the tags in the pdu
191  *
192  * Initial - Rich Coe
193  *
194  * - It currently displays most of the DICOM packets.
195  * - I've used it to debug Query/Retrieve, Storage, and Echo protocols.
196  * - Not all DICOM tags are currently displayed symbolically.
197  *   Unknown tags are displayed as '(unknown)'
198  *   More known tags might be added in the future.
199  *   If the tag data contains a string, it will be displayed.
200  *   Even if the tag contains Explicit VR, it is not currently used to
201  *   symbolically display the data.  Consider this a future enhancement.
202  *
203  */
204
205 #ifdef HAVE_CONFIG_H
206 # include "config.h"
207 #endif
208
209 #include <stdlib.h>
210 #include <string.h>
211 #include <ctype.h>
212
213 #include <glib.h>
214
215 #include <epan/prefs.h>
216 #include <epan/packet.h>
217 #include <epan/emem.h>
218 #include <epan/strutil.h>
219 #include <epan/conversation.h>
220 #include <epan/expert.h>
221 #include <epan/tap.h>
222 #include <epan/reassemble.h>
223
224 #include "packet-tcp.h"
225
226 #include "packet-dcm.h"
227
228 #define DICOM_DEFAULT_RANGE "104"
229
230 /* Many thanks to http://medicalconnections.co.uk/ for the GUID */
231 #define WIRESHARK_IMPLEMENTATION_UID                    "1.2.826.0.1.3680043.8.427.10"
232 #define WIRESHARK_MEDIA_STORAGE_SOP_CLASS_UID           "1.2.826.0.1.3680043.8.427.11.1"
233 #define WIRESHARK_MEDIA_STORAGE_SOP_INSTANCE_UID_PREFIX "1.2.826.0.1.3680043.8.427.11.2"
234 #define WIRESHARK_IMPLEMENTATION_VERSION                "WIRESHARK"
235
236 #define MAX_BUF_LEN 1024                                    /* Used for string allocations */
237
238 static range_t *global_dcm_tcp_range = NULL;
239 static range_t *global_dcm_tcp_range_backup = NULL;         /* needed to deregister */
240
241 static gboolean global_dcm_heuristic = FALSE;
242 static gboolean global_dcm_export_header = TRUE;
243 static guint    global_dcm_export_minsize = 4096;           /* Filter small objects in export */
244
245 static gboolean global_dcm_seq_subtree = TRUE;
246 static gboolean global_dcm_tag_subtree = FALSE;             /* Only useful for debugging */
247 static gboolean global_dcm_cmd_details = TRUE;              /* Show details in header and info column */
248 static gboolean global_dcm_reassemble = TRUE;               /* Merge fragmented PDVs */
249
250 static GHashTable *dcm_tag_table = NULL;
251 static GHashTable *dcm_uid_table = NULL;
252 static GHashTable *dcm_status_table = NULL;
253
254 /* Initialize the protocol and registered fields */
255 static int proto_dcm = -1;
256
257 static int dicom_eo_tap = -1;
258
259 static int hf_dcm_pdu = -1,
260     hf_dcm_pdu_len = -1,
261     hf_dcm_pdu_type = -1,
262     hf_dcm_assoc_version = -1,
263     hf_dcm_assoc_called = -1,
264     hf_dcm_assoc_calling = -1,
265     hf_dcm_assoc_reject_result = -1,
266     hf_dcm_assoc_reject_source = -1,
267     hf_dcm_assoc_reject_reason = -1,
268     hf_dcm_assoc_abort_source = -1,
269     hf_dcm_assoc_abort_reason = -1,
270     hf_dcm_assoc_item_type = -1,
271     hf_dcm_assoc_item_len = -1,
272     hf_dcm_actx = -1,
273     hf_dcm_pctx_id = -1,
274     hf_dcm_pctx_result = -1,
275     hf_dcm_pctx_abss_syntax = -1,
276     hf_dcm_pctx_xfer_syntax = -1,
277     hf_dcm_info_uid = -1,
278     hf_dcm_info_version = -1,
279     hf_dcm_pdu_maxlen = -1,
280     hf_dcm_pdv_len = -1,
281     hf_dcm_pdv_ctx = -1,
282     hf_dcm_pdv_flags = -1,
283     hf_dcm_data_tag = -1,
284     hf_dcm_tag = -1,
285     hf_dcm_tag_vr = -1,
286     hf_dcm_tag_vl = -1,
287     hf_dcm_tag_value_str = -1,
288     hf_dcm_tag_value_16u = -1,
289     hf_dcm_tag_value_16s = -1,
290     hf_dcm_tag_value_32s = -1,
291     hf_dcm_tag_value_32u = -1,
292     hf_dcm_tag_value_byte = -1;
293
294
295 /* Initialize the subtree pointers */
296 static gint
297     ett_dcm = -1,
298     ett_assoc = -1,
299     ett_assoc_header = -1,
300     ett_assoc_actx = -1,
301     ett_assoc_pctx = -1,
302     ett_assoc_pctx_abss = -1,
303     ett_assoc_pctx_xfer = -1,
304     ett_assoc_info = -1,
305     ett_assoc_info_uid = -1,
306     ett_assoc_info_version = -1,
307     ett_dcm_data = -1,
308     ett_dcm_data_pdv = -1,
309     ett_dcm_data_tag = -1,
310     ett_dcm_data_seq = -1,
311     ett_dcm_data_item = -1;
312
313 static dissector_handle_t dcm_handle;
314
315 static const value_string dcm_pdu_ids[] = {
316     { 1, "ASSOC Request" },
317     { 2, "ASSOC Accept" },
318     { 3, "ASSOC Reject" },
319     { 4, "Data" },
320     { 5, "RELEASE Request" },
321     { 6, "RELEASE Response" },
322     { 7, "ABORT" },
323     { 0, NULL }
324 };
325
326 static const value_string dcm_assoc_item_type[] = {
327     { 0x10, "Application Context" },
328     { 0x20, "Presentation Context" },
329     { 0x21, "Presentation Context Reply" },
330     { 0x30, "Abstract Syntax" },
331     { 0x40, "Transfer Syntax" },
332     { 0x50, "User Info" },
333     { 0x51, "Max Length" },
334     { 0x52, "Implementation Class UID" },
335     { 0x55, "Implementation Version" },
336     { 0, NULL }
337 };
338
339 /* ************************************************************************* */
340 /*                  Fragment items                                           */
341 /* ************************************************************************* */
342
343 /* Initialize the subtree pointers */
344 static gint ett_dcm_pdv = -1;
345
346 static gint ett_dcm_pdv_fragment = -1;
347 static gint ett_dcm_pdv_fragments = -1;
348
349 static int hf_dcm_pdv_fragments = -1;
350 static int hf_dcm_pdv_fragment = -1;
351 static int hf_dcm_pdv_fragment_overlap = -1;
352 static int hf_dcm_pdv_fragment_overlap_conflicts = -1;
353 static int hf_dcm_pdv_fragment_multiple_tails = -1;
354 static int hf_dcm_pdv_fragment_too_long_fragment = -1;
355 static int hf_dcm_pdv_fragment_error = -1;
356 static int hf_dcm_pdv_fragment_count = -1;
357 static int hf_dcm_pdv_reassembled_in = -1;
358 static int hf_dcm_pdv_reassembled_length = -1;
359
360 static const fragment_items dcm_pdv_fragment_items = {
361     /* Fragment subtrees */
362     &ett_dcm_pdv_fragment,
363     &ett_dcm_pdv_fragments,
364     /* Fragment fields */
365     &hf_dcm_pdv_fragments,
366     &hf_dcm_pdv_fragment,
367     &hf_dcm_pdv_fragment_overlap,
368     &hf_dcm_pdv_fragment_overlap_conflicts,
369     &hf_dcm_pdv_fragment_multiple_tails,
370     &hf_dcm_pdv_fragment_too_long_fragment,
371     &hf_dcm_pdv_fragment_error,
372     &hf_dcm_pdv_fragment_count,
373     &hf_dcm_pdv_reassembled_in,
374     &hf_dcm_pdv_reassembled_length,
375     /* Tag */
376     "Message fragments"
377 };
378
379 /* Structures to handle fragmented DICOM PDU packets */
380 static GHashTable *dcm_pdv_fragment_table = NULL;
381 static GHashTable *dcm_pdv_reassembled_table = NULL;
382
383 typedef struct dcm_open_tag {
384
385     /* Contains information about an open tag in a PDV, in case it was not complete.
386
387        This implementation differentiates between open headers (grm, elm, vr, vl) and
388        open values. This data structure will handl both cases.
389
390        Open headers are not shown in the packet where the tag starts, but only in the next PDV.
391        Open values are shown in the packet where the tag starts, with <Byte 1-n> as the value
392
393        The same PDV can close an open tag from a previous PDV at the beginning
394        and at the same have time open a new tag at the end. The closing part at the beginning
395        does not have it's own persitent data.
396
397        Do not overwrite the values, once defined, to save some memory.
398
399        Since PDVs are always n*2 bytes, store each of the 2 Bytes in a variable.
400        This way, we don't need to call tvb_get_xxx on a self created buffer
401
402     */
403
404     gboolean    is_header_fragmented;
405     gboolean    is_value_fragmented;
406
407     guint32     len_decoded;    /* Should only by < 16 bytes                */
408
409     guint16     grp;            /* Already decoded group                    */
410     guint16     elm;            /* Already decoded element                  */
411     gchar      *vr;             /* Already decoded VR                       */
412
413     gboolean    is_vl_long;     /* If TRUE, Value Length is 4 Bytes, otherwise 2 */
414     guint16     vl_1;           /* Partially decoded 1st two bytes of length  */
415     guint16     vl_2;           /* Partially decoded 2nd two bytes of length  */
416
417     /* These ones are, where the value was truncated */
418     guint32 len_total;          /* Tag length of 'oversized' tags. Used for display */
419     guint32 len_remaining;      /* Remining tag bytes to 'decoded' as binary data after this PDV */
420
421     gchar  *desc;               /* Last decoded description */
422
423 } dcm_open_tag_t;
424
425 /*
426     Per Data PDV store data needed, to allow decoding of tags longer than a PDV
427 */
428 typedef struct dcm_state_pdv {
429
430     struct dcm_state_pdv *next, *prev;
431
432     guint32  packet_no;         /* Wireshark packet number, where pdv starts */
433     guint32  offset;            /* Offset in packet, where PDV header starts */
434
435     gchar   *desc;              /* PDV description.         se_alloc()  */
436
437     guint8  pctx_id;            /* Reference to used Presentation Context */
438
439     /* Following is drived from the transfer syntax in the parent PCTX, execpt for Command PDVs */
440     guint8  syntax;
441
442     /* Used and filled for Export Object only */
443     gpointer data;              /* Copy of PDV data without any PDU/PDV header */
444     guint32  data_len;          /* Length of this PDV buffer. If >0, memory has been allocated */
445
446     gchar   *sop_class_uid;     /* SOP Class UID.    Set in 1st PDV of a DICOM object. se_alloc() */
447     gchar   *sop_instance_uid;  /* SOP Instance UID. Set in 1st PDV of a DICOM object. se_alloc() */
448     /* End Export use */
449
450     gboolean is_storage;        /* Ture, if the Data PDV is on the context of a storage SOP Class */
451     gboolean is_flagvalid;      /* The following two flags are initalized correctly */
452     gboolean is_command;        /* This PDV is a command rather than a data package */
453     gboolean is_last_fragment;  /* Last Fragment bit was set, i.e. termination of an object
454                                    This flag delimits different dicom object in the same
455                                    association */
456     gboolean is_corrupt;        /* Early termination of long PDVs */
457
458                                 /* The following five attributes are only used from command PDVs */
459
460     gchar   *command;           /* Decoded command as text */
461     gchar   *status;
462     gchar   *comment;           /* Error comment, if any */
463
464     gboolean is_warning;        /* Command response is a cancel, warning, error */
465
466     guint16  message_id;        /* (0000,0110) Message ID */
467     guint16  message_id_resp;   /* (0000,0120) Message ID Being Responded To */
468
469     guint16  no_remaining;      /* (0000,1020) Number of Remaining Sub-operations */
470     guint16  no_completed;      /* (0000,1021) Number of Completed Sub-operations */
471     guint16  no_failed;         /* (0000,1022) Number of Failed Sub-operations  */
472     guint16  no_warning;        /* (0000,1023) Number of Warning Sub-operations */
473
474     dcm_open_tag_t  open_tag;   /* Container to store information about a fragmented tag */
475
476 } dcm_state_pdv_t;
477
478 /*
479     Per Presentation Context in an association store data needed, for subsequent decoding
480 */
481 typedef struct dcm_state_pctx {
482
483     struct dcm_state_pctx *next, *prev;
484
485     guint8 id;                  /* 0x20 Presentation Context ID */
486     gchar *abss_uid;            /* 0x30 Abstract syntax */
487     gchar *abss_desc;           /* 0x30 Abstract syntax decoded*/
488     gchar *xfer_uid;            /* 0x40 Accepted Transfer syntax */
489     gchar *xfer_desc;           /* 0x40 Accepted Transfer syntax decoded*/
490     guint8 syntax;              /* Decoded transfer syntax */
491 #define DCM_ILE  0x01           /* implicit, little endian */
492 #define DCM_EBE  0x02           /* explicit, big endian */
493 #define DCM_ELE  0x03           /* explicit, little endian */
494 #define DCM_UNK  0xf0
495
496     dcm_state_pdv_t     *first_pdv,  *last_pdv;         /* List of PDV objects */
497
498 } dcm_state_pctx_t;
499
500
501 typedef struct dcm_state_assoc {
502
503     struct dcm_state_assoc *next, *prev;
504
505     dcm_state_pctx_t    *first_pctx, *last_pctx;        /* List of Presentation context objects */
506
507     guint32 packet_no;                  /* Wireshark packet number, where association starts */
508
509 #define AEEND 16
510     gchar ae_called[1+AEEND];           /* Called  AE tilte in A-ASSOCIATE RQ */
511     gchar ae_calling[1+AEEND];          /* Calling AE tilte in A-ASSOCIATE RQ */
512     gchar ae_called_resp[1+AEEND];      /* Called  AE tilte in A-ASSOCIATE RP */
513     gchar ae_calling_resp[1+AEEND];     /* Calling AE tilte in A-ASSOCIATE RP */
514
515 } dcm_state_assoc_t;
516
517 typedef struct dcm_state {
518
519     struct dcm_state_assoc *first_assoc, *last_assoc;
520
521     gboolean valid;                     /* this conversation is a DICOM conversation */
522
523 } dcm_state_t;
524
525
526 #define DCM_VR_AE  1  /* Application Entity        */
527 #define DCM_VR_AS  2  /* Age String                */
528 #define DCM_VR_AT  3  /* Attribute Tag             */
529 #define DCM_VR_CS  4  /* Code String               */
530 #define DCM_VR_DA  5  /* Date                      */
531 #define DCM_VR_DS  6  /* Decimal String            */
532 #define DCM_VR_DT  7  /* Date Time                 */
533 #define DCM_VR_FL  8  /* Floating Point Single     */
534 #define DCM_VR_FD  9  /* Floating Point Double     */
535 #define DCM_VR_IS 10  /* Integer String            */
536 #define DCM_VR_LO 11  /* Long String               */
537 #define DCM_VR_LT 12  /* Long Text                 */
538 #define DCM_VR_OB 13  /* Other Byte String         */
539 #define DCM_VR_OF 14  /* Other Float String        */
540 #define DCM_VR_OW 15  /* Other Word String         */
541 #define DCM_VR_PN 16  /* Person Name               */
542 #define DCM_VR_SH 17  /* Short String              */
543 #define DCM_VR_SL 18  /* Signed Long               */
544 #define DCM_VR_SQ 19  /* Sequence of Items         */
545 #define DCM_VR_SS 20  /* Signed Short              */
546 #define DCM_VR_ST 21  /* Short Text                */
547 #define DCM_VR_TM 22  /* Time                      */
548 #define DCM_VR_UI 23  /* Unique Identifier (UID)   */
549 #define DCM_VR_UL 24  /* Unsigned Long             */
550 #define DCM_VR_UN 25  /* Unknown                   */
551 #define DCM_VR_US 26  /* Unsigned Short            */
552 #define DCM_VR_UT 27  /* Unlimited Text            */
553
554 /* Following must be in the same order as the defintions above */
555 static const gchar* dcm_tag_vr_lookup[] = {
556     "  ",
557     "AE","AS","AT","CS","DA","DS","DT","FL",
558     "FD","IS","LO","LT","OB","OF","OW","PN",
559     "SH","SL","SQ","SS","ST","TM","UI","UL",
560     "UN","US","UT"
561 };
562
563 /* ---------------------------------------------------------------------
564  * DICOM Status Value Definitions
565  *
566  * Collected from PS 3.7 & 3.4
567  *
568 */
569
570 typedef struct dcm_status {
571     const guint16 value;
572     const gchar *description;
573 } dcm_status_t;
574
575 static dcm_status_t dcm_status_data[] = {
576
577     /* From PS 3.7 */
578
579     { 0x0000,   "Success"},
580     { 0x0105,   "No such attribute"},
581     { 0x0106,   "Invalid attribute value"},
582     { 0x0107,   "Attribute list error"},
583     { 0x0110,   "Processing failure"},
584     { 0x0111,   "Duplicate SOP instance"},
585     { 0x0112,   "No Such object instance"},
586     { 0x0113,   "No such event type"},
587     { 0x0114,   "No such argument"},
588     { 0x0115,   "Invalid argument value"},
589     { 0x0116,   "Attribute Value Out of Range"},
590     { 0x0117,   "Invalid object instance"},
591     { 0x0118,   "No Such SOP class"},
592     { 0x0119,   "Class-instance conflict"},
593     { 0x0120,   "Missing attribute"},
594     { 0x0121,   "Missing attribute value"},
595     { 0x0122,   "Refused: SOP class not supported"},
596     { 0x0123,   "No such action type"},
597     { 0x0210,   "Duplicate invocation"},
598     { 0x0211,   "Unrecognized operation"},
599     { 0x0212,   "Mistyped argument"},
600     { 0x0213,   "Resource limitation"},
601     { 0xFE00,   "Cancel"},
602
603     /* from PS 3.4 */
604
605     { 0x0001,   "Requested optional Attributes are not supported"},
606     { 0xA501,   "Refused because General Purpose Scheduled Procedure Step Object may no longer be updated"},
607     { 0xA502,   "Refused because the wrong Transaction UID is used"},
608     { 0xA503,   "Refused because the General Purpose Scheduled Procedure Step SOP Instance is already in the 'IN PROGRESS' state"},
609     { 0xA504,   "Refused because the related General Purpose Scheduled Procedure Step SOP Instance is not in the 'IN PROGRESS' state"},
610     { 0xA505,   "Refused because Referenced General Purpose Scheduled Procedure Step Transaction UID does not match the Transaction UID of the N-ACTION request"},
611     { 0xA510,   "Refused because an Initiate Media Creation action has already been received for this SOP Instance"},
612     { 0xA700,   "Refused: Out of Resources"},
613     { 0xA701,   "Refused: Out of Resources - Unable to calculate number of matches"},
614     { 0xA702,   "Refused: Out of Resources - Unable to perform sub-operations"},
615     /*
616     { 0xA7xx,   "Refused: Out of Resources"},
617     */
618     { 0xA801,   "Refused: Move Destination unknown"},
619     /*
620     { 0xA9xx,   "Error: Data Set does not match SOP Class"},
621     */
622     { 0xB000,   "Sub-operations Complete - One or more Failures"},
623     { 0xB006,   "Elements Discarded"},
624     { 0xB007,   "Data Set does not match SOP Class"},
625     { 0xB101,   "Specified Synchronization Frame of Reference UID does not match SCP Synchronization Frame of Reference"},
626     { 0xB102,   "Study Instance UID coercion; Event logged under a different Study Instance UID"},
627     { 0xB104,   "IDs inconsistent in matching a current study; Event logged"},
628     { 0xB605,   "Requested Min Density or Max Density outside of printer's operating range. The printer will use its respective minimum or maximum density value instead"},
629     { 0xC000,   "Error: Cannot understand/Unable to process"},
630     { 0xC100,   "More than one match found"},
631     { 0xC101,   "Procedural Logging not available for specified Study Instance UID"},
632     { 0xC102,   "Event Information does not match Template"},
633     { 0xC103,   "Cannot match event to a current study"},
634     { 0xC104,   "IDs inconsistent in matching a current study; Event not logged"},
635     { 0xC200,   "Unable to support requested template"},
636     { 0xC201,   "Media creation request already completed"},
637     { 0xC202,   "Media creation request already in progress and cannot be interrupted"},
638     { 0xC203,   "Cancellation denied for unspecified reason"},
639     /*
640     { 0xCxxx,   "Error: Cannot understand/Unable to Process"},
641     { 0xFE00,   "Matching/Sub-operations terminated due to Cancel request"},
642     */
643     { 0xFF00,   "Current Match is supplied. Sub-operations are continuing"},
644     { 0xFF01,   "Matches are continuing - Warning that one or more Optional Keys were not supported for existence for this Identifier"}
645
646 };
647
648
649 /* ---------------------------------------------------------------------
650  * DICOM Tag Definitions
651  *
652  * Part 6 lists following different Value Representations (2006-2008)
653  * AE,AS,AT,CS,DA,DS,DT,FD,FL,IS,LO,LT,OB,OB or OW,OF,OW,OW or OB,
654  * PN,SH,SL,SQ,SS,ST,TM,UI,UL,US,US or SS,US or SS or OW,UT
655  *
656  * Some Tags can have different VRs
657  *
658  * Group 1000 is not supported, multiple tags with same description  (retired anyhow)
659  * Group 7Fxx is not supported, multiple tags with same description  (retired anyhow)
660  *
661  * Tags (0020,3100 to 0020, 31FF) not supported, multiple tags with same description  (retired anyhow)
662  *
663  * Repeating groups (50xx & 60xx) are manually added. Declared as 5000 & 6000
664  */
665
666 typedef struct dcm_tag {
667     const guint32 tag;
668     const gchar *description;
669     const gchar *vr;
670     const gchar *vm;
671     const gboolean is_retired;
672     const gboolean add_to_summary;          /* Add to parent's item description */
673 } dcm_tag_t;
674
675 static dcm_tag_t dcm_tag_data[] = {
676
677     /* Command Tags */
678     { 0x00000000, "Command Group Length", "UL", "1", 0, 0},
679     { 0x00000002, "Affected SOP Class UID", "UI", "1", 0, 0},
680     { 0x00000003, "Requested SOP Class UID", "UI", "1", 0, 0},
681     { 0x00000100, "Command Field", "US", "1", 0, 0},
682     { 0x00000110, "Message ID", "US", "1", 0, 0},
683     { 0x00000120, "Message ID Being Responded To", "US", "1", 0, 0},
684     { 0x00000600, "Move Destination", "AE", "1", 0, 0},
685     { 0x00000700, "Priority", "US", "1", 0, 0},
686     { 0x00000800, "Data Set Type", "US", "1", 0, 0},
687     { 0x00000900, "Status", "US", "1", 0, 0},
688     { 0x00000901, "Offending Element", "AT", "1-n", 0, 0},
689     { 0x00000902, "Error Comment", "LO", "1", 0, 0},
690     { 0x00000903, "Error ID", "US", "1", 0, 0},
691     { 0x00001000, "Affected SOP Instance UID", "UI", "1", 0, 0},
692     { 0x00001001, "Requested SOP Instance UID", "UI", "1", 0, 0},
693     { 0x00001002, "Event Type ID", "US", "1", 0, 0},
694     { 0x00001005, "Attribute Identifier List", "AT", "1-n", 0, 0},
695     { 0x00001008, "Action Type ID", "US", "1", 0, 0},
696     { 0x00001020, "Number of Remaining Sub-operations", "US", "1", 0, 0},
697     { 0x00001021, "Number of Completed Sub-operations", "US", "1", 0, 0},
698     { 0x00001022, "Number of Failed Sub-operations", "US", "1", 0, 0},
699     { 0x00001023, "Number of Warning Sub-operations", "US", "1", 0, 0},
700     { 0x00001030, "Move Originator Application Entity Title", "AE", "1", 0, 0},
701     { 0x00001031, "Move Originator Message ID", "US", "1", 0, 0},
702     { 0x00000001, "Length to End", "UL", "1", -1, 0},
703     { 0x00000010, "Recognition Code", "CS", "1", -1, 0},
704     { 0x00000200, "Initiator", "AE", "1", -1, 0},
705     { 0x00000300, "Receiver", "AE", "1", -1, 0},
706     { 0x00000400, "Find Location", "AE", "1", -1, 0},
707     { 0x00000850, "Number of Matches", "US", "1", -1, 0},
708     { 0x00000860, "Response Sequence Number", "US", "1", -1, 0},
709     { 0x00004000, "DIALOG Receiver", "AT", "1", -1, 0},
710     { 0x00004010, "Terminal Type", "AT", "1", -1, 0},
711     { 0x00005010, "Message Set ID", "SH", "1", -1, 0},
712     { 0x00005020, "End Message ID", "SH", "1", -1, 0},
713     { 0x00005110, "Display Format", "AT", "1", -1, 0},
714     { 0x00005120, "Page Position ID", "AT", "1", -1, 0},
715     { 0x00005130, "Text Format ID", "CS", "1", -1, 0},
716     { 0x00005140, "Nor/Rev", "CS", "1", -1, 0},
717     { 0x00005150, "Add Gray Scale", "CS", "1", -1, 0},
718     { 0x00005160, "Borders", "CS", "1", -1, 0},
719     { 0x00005170, "Copies", "IS", "1", -1, 0},
720     { 0x00005180, "Magnification Type", "CS", "1", -1, 0},
721     { 0x00005190, "Erase", "CS", "1", -1, 0},
722     { 0x000051A0, "Print", "CS", "1", -1, 0},
723     { 0x000051B0, "Overlays", "US", "1-n", -1, 0},
724
725
726     /* Data Tags */
727     { 0x00080001, "Length to End", "UL", "1", -1, 0},
728     { 0x00080005, "Specific Character Set", "CS", "1-n", 0, 0},
729     { 0x00080008, "Image Type", "CS", "2-n", 0, 0},
730     { 0x00080010, "Recognition Code", "CS", "1", -1, 0},
731     { 0x00080012, "Instance Creation Date", "DA", "1", 0, 0},
732     { 0x00080013, "Instance Creation Time", "TM", "1", 0, 0},
733     { 0x00080014, "Instance Creator UID", "UI", "1", 0, 0},
734     { 0x00080016, "SOP Class UID", "UI", "1", 0, 0},
735     { 0x00080018, "SOP Instance UID", "UI", "1", 0, 0},
736     { 0x0008001A, "Related General SOP Class UID", "UI", "1-n", 0, 0},
737     { 0x0008001B, "Original Specialized SOP Class UID", "UI", "1", 0, 0},
738     { 0x00080020, "Study Date", "DA", "1", 0, 0},
739     { 0x00080021, "Series Date", "DA", "1", 0, 0},
740     { 0x00080022, "Acquisition Date", "DA", "1", 0, 0},
741     { 0x00080023, "Content Date", "DA", "1", 0, 0},
742     { 0x00080024, "Overlay Date", "DA", "1", -1, 0},
743     { 0x00080025, "Curve Date", "DA", "1", -1, 0},
744     { 0x0008002A, "Acquisition DateTime", "DT", "1", 0, 0},
745     { 0x00080030, "Study Time", "TM", "1", 0, 0},
746     { 0x00080031, "Series Time", "TM", "1", 0, 0},
747     { 0x00080032, "Acquisition Time", "TM", "1", 0, 0},
748     { 0x00080033, "Content Time", "TM", "1", 0, 0},
749     { 0x00080034, "Overlay Time", "TM", "1", -1, 0},
750     { 0x00080035, "Curve Time", "TM", "1", -1, 0},
751     { 0x00080040, "Data Set Type", "US", "1", -1, 0},
752     { 0x00080041, "Data Set Subtype", "LO", "1", -1, 0},
753     { 0x00080042, "Nuclear Medicine Series Type", "CS", "1", -1, 0},
754     { 0x00080050, "Accession Number", "SH", "1", 0, 0},
755     { 0x00080052, "Query/Retrieve Level", "CS", "1", 0, 0},
756     { 0x00080054, "Retrieve AE Title", "AE", "1-n", 0, 0},
757     { 0x00080056, "Instance Availability", "CS", "1", 0, 0},
758     { 0x00080058, "Failed SOP Instance UID List", "UI", "1-n", 0, 0},
759     { 0x00080060, "Modality", "CS", "1", 0, 0},
760     { 0x00080061, "Modalities in Study", "CS", "1-n", 0, 0},
761     { 0x00080062, "SOP Classes in Study", "UI", "1-n", 0, 0},
762     { 0x00080064, "Conversion Type", "CS", "1", 0, 0},
763     { 0x00080068, "Presentation Intent Type", "CS", "1", 0, 0},
764     { 0x00080070, "Manufacturer", "LO", "1", 0, 0},
765     { 0x00080080, "Institution Name", "LO", "1", 0, 0},
766     { 0x00080081, "Institution Address", "ST", "1", 0, 0},
767     { 0x00080082, "Institution Code Sequence", "SQ", "1", 0, 0},
768     { 0x00080090, "Referring Physician's Name", "PN", "1", 0, 0},
769     { 0x00080092, "Referring Physician's Address", "ST", "1", 0, 0},
770     { 0x00080094, "Referring Physician's Telephone Numbers", "SH", "1-n", 0, 0},
771     { 0x00080096, "Referring Physician Identification Sequence", "SQ", "1", 0, 0},
772     { 0x00080100, "Code Value", "SH", "1", 0, 0},
773     { 0x00080102, "Coding Scheme Designator", "SH", "1", 0, 0},
774     { 0x00080103, "Coding Scheme Version", "SH", "1", 0, 0},
775     { 0x00080104, "Code Meaning", "LO", "1", 0, 0},
776     { 0x00080105, "Mapping Resource", "CS", "1", 0, 0},
777     { 0x00080106, "Context Group Version", "DT", "1", 0, 0},
778     { 0x00080107, "Context Group Local Version", "DT", "1", 0, 0},
779     { 0x0008010B, "Context Group Extension Flag", "CS", "1", 0, 0},
780     { 0x0008010C, "Coding Scheme UID", "UI", "1", 0, 0},
781     { 0x0008010D, "Context Group Extension Creator UID", "UI", "1", 0, 0},
782     { 0x0008010F, "Context Identifier", "CS", "1", 0, 0},
783     { 0x00080110, "Coding Scheme Identification Sequence", "SQ", "1", 0, 0},
784     { 0x00080112, "Coding Scheme Registry", "LO", "1", 0, 0},
785     { 0x00080114, "Coding Scheme External ID", "ST", "1", 0, 0},
786     { 0x00080115, "Coding Scheme Name", "ST", "1", 0, 0},
787     { 0x00080116, "Coding Scheme Responsible Organization", "ST", "1", 0, 0},
788     { 0x00080201, "Timezone Offset From UTC", "SH", "1", 0, 0},
789     { 0x00081000, "Network ID", "AE", "1", -1, 0},
790     { 0x00081010, "Station Name", "SH", "1", 0, 0},
791     { 0x00081030, "Study Description", "LO", "1", 0, 0},
792     { 0x00081032, "Procedure Code Sequence", "SQ", "1", 0, 0},
793     { 0x0008103E, "Series Description", "LO", "1", 0, 0},
794     { 0x00081040, "Institutional Department Name", "LO", "1", 0, 0},
795     { 0x00081048, "Physician(s) of Record", "PN", "1-n", 0, 0},
796     { 0x00081049, "Physician(s) of Record Identification Sequence", "SQ", "1", 0, 0},
797     { 0x00081050, "Performing Physician's Name", "PN", "1-n", 0, 0},
798     { 0x00081052, "Performing Physician Identification Sequence", "SQ", "1", 0, 0},
799     { 0x00081060, "Name of Physician(s) Reading Study", "PN", "1-n", 0, 0},
800     { 0x00081062, "Physician(s) Reading Study Identification Sequence", "SQ", "1", 0, 0},
801     { 0x00081070, "Operators' Name", "PN", "1-n", 0, 0},
802     { 0x00081072, "Operator Identification Sequence", "SQ", "1", 0, 0},
803     { 0x00081080, "Admitting Diagnoses Description", "LO", "1-n", 0, 0},
804     { 0x00081084, "Admitting Diagnoses Code Sequence", "SQ", "1", 0, 0},
805     { 0x00081090, "Manufacturer's Model Name", "LO", "1", 0, 0},
806     { 0x00081100, "Referenced Results Sequence", "SQ", "1", -1, 0},
807     { 0x00081110, "Referenced Study Sequence", "SQ", "1", 0, 0},
808     { 0x00081111, "Referenced Performed Procedure Step Sequence", "SQ", "1", 0, 0},
809     { 0x00081115, "Referenced Series Sequence", "SQ", "1", 0, 0},
810     { 0x00081120, "Referenced Patient Sequence", "SQ", "1", 0, 0},
811     { 0x00081125, "Referenced Visit Sequence", "SQ", "1", 0, 0},
812     { 0x00081130, "Referenced Overlay Sequence", "SQ", "1", -1, 0},
813     { 0x0008113A, "Referenced Waveform Sequence", "SQ", "1", 0, 0},
814     { 0x00081140, "Referenced Image Sequence", "SQ", "1", 0, 0},
815     { 0x00081145, "Referenced Curve Sequence", "SQ", "1", -1, 0},
816     { 0x0008114A, "Referenced Instance Sequence", "SQ", "1", 0, 0},
817     { 0x0008114B, "Referenced Real World Value Mapping Instance Sequence", "SQ", "1", 0, 0},
818     { 0x00081150, "Referenced SOP Class UID", "UI", "1", 0, 0},
819     { 0x00081155, "Referenced SOP Instance UID", "UI", "1", 0, 0},
820     { 0x0008115A, "SOP Classes Supported", "UI", "1-n", 0, 0},
821     { 0x00081160, "Referenced Frame Number", "IS", "1-n", 0, 0},
822     { 0x00081195, "Transaction UID", "UI", "1", 0, 0},
823     { 0x00081197, "Failure Reason", "US", "1", 0, 0},
824     { 0x00081198, "Failed SOP Sequence", "SQ", "1", 0, 0},
825     { 0x00081199, "Referenced SOP Sequence", "SQ", "1", 0, 0},
826     { 0x00081200, "Studies Containing Other Referenced Instances Sequence", "SQ", "1", 0, 0},
827     { 0x00081250, "Related Series Sequence", "SQ", "1", 0, 0},
828     { 0x00082110, "Lossy Image Compression (Retired)", "CS", "1", -1, 0},
829     { 0x00082111, "Derivation Description", "ST", "1", 0, 0},
830     { 0x00082112, "Source Image Sequence", "SQ", "1", 0, 0},
831     { 0x00082120, "Stage Name", "SH", "1", 0, 0},
832     { 0x00082122, "Stage Number", "IS", "1", 0, 0},
833     { 0x00082124, "Number of Stages", "IS", "1", 0, 0},
834     { 0x00082127, "View Name", "SH", "1", 0, 0},
835     { 0x00082128, "View Number", "IS", "1", 0, 0},
836     { 0x00082129, "Number of Event Timers", "IS", "1", 0, 0},
837     { 0x0008212A, "Number of Views in Stage", "IS", "1", 0, 0},
838     { 0x00082130, "Event Elapsed Time(s)", "DS", "1-n", 0, 0},
839     { 0x00082132, "Event Timer Name(s)", "LO", "1-n", 0, 0},
840     { 0x00082142, "Start Trim", "IS", "1", 0, 0},
841     { 0x00082143, "Stop Trim", "IS", "1", 0, 0},
842     { 0x00082144, "Recommended Display Frame Rate", "IS", "1", 0, 0},
843     { 0x00082200, "Transducer Position", "CS", "1", -1, 0},
844     { 0x00082204, "Transducer Orientation", "CS", "1", -1, 0},
845     { 0x00082208, "Anatomic Structure", "CS", "1", -1, 0},
846     { 0x00082218, "Anatomic Region Sequence", "SQ", "1", 0, 0},
847     { 0x00082220, "Anatomic Region Modifier Sequence", "SQ", "1", 0, 0},
848     { 0x00082228, "Primary Anatomic Structure Sequence", "SQ", "1", 0, 0},
849     { 0x00082229, "Anatomic Structure, Space or Region Sequence", "SQ", "1", 0, 0},
850     { 0x00082230, "Primary Anatomic Structure Modifier Sequence", "SQ", "1", 0, 0},
851     { 0x00082240, "Transducer Position Sequence", "SQ", "1", -1, 0},
852     { 0x00082242, "Transducer Position Modifier Sequence", "SQ", "1", -1, 0},
853     { 0x00082244, "Transducer Orientation Sequence", "SQ", "1", -1, 0},
854     { 0x00082246, "Transducer Orientation Modifier Sequence", "SQ", "1", -1, 0},
855     { 0x00082251, "Anatomic Structure Space Or Region Code Sequence (Trial)", "SQ", "1", -1, 0},
856     { 0x00082253, "Anatomic Portal Of Entrance Code Sequence (Trial)", "SQ", "1", -1, 0},
857     { 0x00082255, "Anatomic Approach Direction Code Sequence (Trial)", "SQ", "1", -1, 0},
858     { 0x00082256, "Anatomic Perspective Description (Trial)", "ST", "1", -1, 0},
859     { 0x00082257, "Anatomic Perspective Code Sequence (Trial)", "SQ", "1", -1, 0},
860     { 0x00082258, "Anatomic Location Of Examining Instrument Description (Trial)", "ST", "1", -1, 0},
861     { 0x00082259, "Anatomic Location Of Examining Instrument Code Sequence (Trial)", "SQ", "1", -1, 0},
862     { 0x0008225A, "Anatomic Structure Space Or Region Modifier Code Sequence (Trial)", "SQ", "1", -1, 0},
863     { 0x0008225C, "OnAxis Background Anatomic Structure Code Sequence (Trial)", "SQ", "1", -1, 0},
864     { 0x00083001, "Alternate Representation Sequence", "SQ", "1", 0, 0},
865     { 0x00083010, "Irradiation Event UID", "UI", "1", 0, 0},
866     { 0x00084000, "Identifying Comments", "LT", "1", -1, 0},
867     { 0x00089007, "Frame Type", "CS", "4", 0, 0},
868     { 0x00089092, "Referenced Image Evidence Sequence", "SQ", "1", 0, 0},
869     { 0x00089121, "Referenced Raw Data Sequence", "SQ", "1", 0, 0},
870     { 0x00089123, "Creator-Version UID", "UI", "1", 0, 0},
871     { 0x00089124, "Derivation Image Sequence", "SQ", "1", 0, 0},
872     { 0x00089154, "Source Image Evidence Sequence", "SQ", "1", 0, 0},
873     { 0x00089205, "Pixel Presentation", "CS", "1", 0, 0},
874     { 0x00089206, "Volumetric Properties", "CS", "1", 0, 0},
875     { 0x00089207, "Volume Based Calculation Technique", "CS", "1", 0, 0},
876     { 0x00089208, "Complex Image Component", "CS", "1", 0, 0},
877     { 0x00089209, "Acquisition Contrast", "CS", "1", 0, 0},
878     { 0x00089215, "Derivation Code Sequence", "SQ", "1", 0, 0},
879     { 0x00089237, "Referenced Grayscale Presentation State Sequence", "SQ", "1", 0, 0},
880     { 0x00089410, "Referenced Other Plane Sequence", "SQ", "1", 0, 0},
881     { 0x00089458, "Frame Display Sequence", "SQ", "1", 0, 0},
882     { 0x00089459, "Recommended Display Frame Rate in Float", "FL", "1", 0, 0},
883     { 0x00089460, "Skip Frame Range Flag", "CS", "1", 0, 0},
884     { 0x00100010, "Patient's Name", "PN", "1", 0, 0},
885     { 0x00100020, "Patient ID", "LO", "1", 0, 0},
886     { 0x00100021, "Issuer of Patient ID", "LO", "1", 0, 0},
887     { 0x00100022, "Type of Patient ID", "CS", "1", 0, 0},
888     { 0x00100030, "Patient's Birth Date", "DA", "1", 0, 0},
889     { 0x00100032, "Patient's Birth Time", "TM", "1", 0, 0},
890     { 0x00100040, "Patient's Sex", "CS", "1", 0, 0},
891     { 0x00100050, "Patient's Insurance Plan Code Sequence", "SQ", "1", 0, 0},
892     { 0x00100101, "Patient's Primary Language Code Sequence", "SQ", "1", 0, 0},
893     { 0x00100102, "Patient's Primary Language Code Modifier Sequence", "SQ", "1", 0, 0},
894     { 0x00101000, "Other Patient IDs", "LO", "1-n", 0, 0},
895     { 0x00101001, "Other Patient Names", "PN", "1-n", 0, 0},
896     { 0x00101002, "Other Patient IDs Sequence", "SQ", "1", 0, 0},
897     { 0x00101005, "Patient's Birth Name", "PN", "1", 0, 0},
898     { 0x00101010, "Patient's Age", "AS", "1", 0, 0},
899     { 0x00101020, "Patient's Size", "DS", "1", 0, 0},
900     { 0x00101030, "Patient's Weight", "DS", "1", 0, 0},
901     { 0x00101040, "Patient's Address", "LO", "1", 0, 0},
902     { 0x00101050, "Insurance Plan Identification", "LO", "1-n", -1, 0},
903     { 0x00101060, "Patient's Mother's Birth Name", "PN", "1", 0, 0},
904     { 0x00101080, "Military Rank", "LO", "1", 0, 0},
905     { 0x00101081, "Branch of Service", "LO", "1", 0, 0},
906     { 0x00101090, "Medical Record Locator", "LO", "1", 0, 0},
907     { 0x00102000, "Medical Alerts", "LO", "1-n", 0, 0},
908     { 0x00102110, "Allergies", "LO", "1-n", 0, 0},
909     { 0x00102150, "Country of Residence", "LO", "1", 0, 0},
910     { 0x00102152, "Region of Residence", "LO", "1", 0, 0},
911     { 0x00102154, "Patient's Telephone Numbers", "SH", "1-n", 0, 0},
912     { 0x00102160, "Ethnic Group", "SH", "1", 0, 0},
913     { 0x00102180, "Occupation", "SH", "1", 0, 0},
914     { 0x001021A0, "Smoking Status", "CS", "1", 0, 0},
915     { 0x001021B0, "Additional Patient History", "LT", "1", 0, 0},
916     { 0x001021C0, "Pregnancy Status", "US", "1", 0, 0},
917     { 0x001021D0, "Last Menstrual Date", "DA", "1", 0, 0},
918     { 0x001021F0, "Patient's Religious Preference", "LO", "1", 0, 0},
919     { 0x00102201, "Patient Species Description", "LO", "1", 0, 0},
920     { 0x00102202, "Patient Species Code Sequence", "SQ", "1", 0, 0},
921     { 0x00102203, "Patient's Sex Neutered", "CS", "1", 0, 0},
922     { 0x00102292, "Patient Breed Description", "LO", "1", 0, 0},
923     { 0x00102293, "Patient Breed Code Sequence", "SQ", "1", 0, 0},
924     { 0x00102294, "Breed Registration Sequence", "SQ", "1", 0, 0},
925     { 0x00102295, "Breed Registration Number", "LO", "1", 0, 0},
926     { 0x00102296, "Breed Registry Code Sequence", "SQ", "1", 0, 0},
927     { 0x00102297, "Responsible Person", "PN", "1", 0, 0},
928     { 0x00102298, "Responsible Person Role", "CS", "1", 0, 0},
929     { 0x00102299, "Responsible Organization", "LO", "1", 0, 0},
930     { 0x00104000, "Patient Comments", "LT", "1", 0, 0},
931     { 0x00109431, "Examined Body Thickness", "FL", "1", 0, 0},
932     { 0x00120010, "Clinical Trial Sponsor Name", "LO", "1", 0, 0},
933     { 0x00120020, "Clinical Trial Protocol ID", "LO", "1", 0, 0},
934     { 0x00120021, "Clinical Trial Protocol Name", "LO", "1", 0, 0},
935     { 0x00120030, "Clinical Trial Site ID", "LO", "1", 0, 0},
936     { 0x00120031, "Clinical Trial Site Name", "LO", "1", 0, 0},
937     { 0x00120040, "Clinical Trial Subject ID", "LO", "1", 0, 0},
938     { 0x00120042, "Clinical Trial Subject Reading ID", "LO", "1", 0, 0},
939     { 0x00120050, "Clinical Trial Time Point ID", "LO", "1", 0, 0},
940     { 0x00120051, "Clinical Trial Time Point Description", "ST", "1", 0, 0},
941     { 0x00120060, "Clinical Trial Coordinating Center Name", "LO", "1", 0, 0},
942     { 0x00120062, "Patient Identity Removed", "CS", "1", 0, 0},
943     { 0x00120063, "De-identification Method", "LO", "1-n", 0, 0},
944     { 0x00120064, "De-identification Method Code Sequence", "SQ", "1", 0, 0},
945     { 0x00120071, "Clinical Trial Series ID", "LO", "1", 0, 0},
946     { 0x00120072, "Clinical Trial Series Description", "LO", "1", 0, 0},
947     { 0x00180010, "Contrast/Bolus Agent", "LO", "1", 0, 0},
948     { 0x00180012, "Contrast/Bolus Agent Sequence", "SQ", "1", 0, 0},
949     { 0x00180014, "Contrast/Bolus Administration Route Sequence", "SQ", "1", 0, 0},
950     { 0x00180015, "Body Part Examined", "CS", "1", 0, 0},
951     { 0x00180020, "Scanning Sequence", "CS", "1-n", 0, 0},
952     { 0x00180021, "Sequence Variant", "CS", "1-n", 0, 0},
953     { 0x00180022, "Scan Options", "CS", "1-n", 0, 0},
954     { 0x00180023, "MR Acquisition Type", "CS", "1", 0, 0},
955     { 0x00180024, "Sequence Name", "SH", "1", 0, 0},
956     { 0x00180025, "Angio Flag", "CS", "1", 0, 0},
957     { 0x00180026, "Intervention Drug Information Sequence", "SQ", "1", 0, 0},
958     { 0x00180027, "Intervention Drug Stop Time", "TM", "1", 0, 0},
959     { 0x00180028, "Intervention Drug Dose", "DS", "1", 0, 0},
960     { 0x00180029, "Intervention Drug Sequence", "SQ", "1", 0, 0},
961     { 0x0018002A, "Additional Drug Sequence", "SQ", "1", 0, 0},
962     { 0x00180030, "Radionuclide", "LO", "1-n", -1, 0},
963     { 0x00180031, "Radiopharmaceutical", "LO", "1", 0, 0},
964     { 0x00180032, "Energy Window Centerline", "DS", "1", -1, 0},
965     { 0x00180033, "Energy Window Total Width", "DS", "1-n", -1, 0},
966     { 0x00180034, "Intervention Drug Name", "LO", "1", 0, 0},
967     { 0x00180035, "Intervention Drug Start Time", "TM", "1", 0, 0},
968     { 0x00180036, "Intervention Sequence", "SQ", "1", 0, 0},
969     { 0x00180037, "Therapy Type", "CS", "1", -1, 0},
970     { 0x00180038, "Intervention Status", "CS", "1", 0, 0},
971     { 0x00180039, "Therapy Description", "CS", "1", -1, 0},
972     { 0x0018003A, "Intervention Description", "ST", "1", 0, 0},
973     { 0x00180040, "Cine Rate", "IS", "1", 0, 0},
974     { 0x00180050, "Slice Thickness", "DS", "1", 0, 0},
975     { 0x00180060, "KVP", "DS", "1", 0, 0},
976     { 0x00180070, "Counts Accumulated", "IS", "1", 0, 0},
977     { 0x00180071, "Acquisition Termination Condition", "CS", "1", 0, 0},
978     { 0x00180072, "Effective Duration", "DS", "1", 0, 0},
979     { 0x00180073, "Acquisition Start Condition", "CS", "1", 0, 0},
980     { 0x00180074, "Acquisition Start Condition Data", "IS", "1", 0, 0},
981     { 0x00180075, "Acquisition Termination Condition Data", "IS", "1", 0, 0},
982     { 0x00180080, "Repetition Time", "DS", "1", 0, 0},
983     { 0x00180081, "Echo Time", "DS", "1", 0, 0},
984     { 0x00180082, "Inversion Time", "DS", "1", 0, 0},
985     { 0x00180083, "Number of Averages", "DS", "1", 0, 0},
986     { 0x00180084, "Imaging Frequency", "DS", "1", 0, 0},
987     { 0x00180085, "Imaged Nucleus", "SH", "1", 0, 0},
988     { 0x00180086, "Echo Number(s)", "IS", "1-n", 0, 0},
989     { 0x00180087, "Magnetic Field Strength", "DS", "1", 0, 0},
990     { 0x00180088, "Spacing Between Slices", "DS", "1", 0, 0},
991     { 0x00180089, "Number of Phase Encoding Steps", "IS", "1", 0, 0},
992     { 0x00180090, "Data Collection Diameter", "DS", "1", 0, 0},
993     { 0x00180091, "Echo Train Length", "IS", "1", 0, 0},
994     { 0x00180093, "Percent Sampling", "DS", "1", 0, 0},
995     { 0x00180094, "Percent Phase Field of View", "DS", "1", 0, 0},
996     { 0x00180095, "Pixel Bandwidth", "DS", "1", 0, 0},
997     { 0x00181000, "Device Serial Number", "LO", "1", 0, 0},
998     { 0x00181002, "Device UID", "UI", "1", 0, 0},
999     { 0x00181003, "Device ID", "LO", "1", 0, 0},
1000     { 0x00181004, "Plate ID", "LO", "1", 0, 0},
1001     { 0x00181005, "Generator ID", "LO", "1", 0, 0},
1002     { 0x00181006, "Grid ID", "LO", "1", 0, 0},
1003     { 0x00181007, "Cassette ID", "LO", "1", 0, 0},
1004     { 0x00181008, "Gantry ID", "LO", "1", 0, 0},
1005     { 0x00181010, "Secondary Capture Device ID", "LO", "1", 0, 0},
1006     { 0x00181011, "Hardcopy Creation Device ID", "LO", "1", -1, 0},
1007     { 0x00181012, "Date of Secondary Capture", "DA", "1", 0, 0},
1008     { 0x00181014, "Time of Secondary Capture", "TM", "1", 0, 0},
1009     { 0x00181016, "Secondary Capture Device Manufacturers", "LO", "1", 0, 0},
1010     { 0x00181017, "Hardcopy Device Manufacturer", "LO", "1", -1, 0},
1011     { 0x00181018, "Secondary Capture Device Manufacturer's Model Name", "LO", "1", 0, 0},
1012     { 0x00181019, "Secondary Capture Device Software Version(s)", "LO", "1-n", 0, 0},
1013     { 0x0018101A, "Hardcopy Device Software Version", "LO", "1-n", -1, 0},
1014     { 0x0018101B, "Hardcopy Device Manufacturer's Model Name", "LO", "1", -1, 0},
1015     { 0x00181020, "Software Version(s)", "LO", "1-n", 0, 0},
1016     { 0x00181022, "Video Image Format Acquired", "SH", "1", 0, 0},
1017     { 0x00181023, "Digital Image Format Acquired", "LO", "1", 0, 0},
1018     { 0x00181030, "Protocol Name", "LO", "1", 0, 0},
1019     { 0x00181040, "Contrast/Bolus Route", "LO", "1", 0, 0},
1020     { 0x00181041, "Contrast/Bolus Volume", "DS", "1", 0, 0},
1021     { 0x00181042, "Contrast/Bolus Start Time", "TM", "1", 0, 0},
1022     { 0x00181043, "Contrast/Bolus Stop Time", "TM", "1", 0, 0},
1023     { 0x00181044, "Contrast/Bolus Total Dose", "DS", "1", 0, 0},
1024     { 0x00181045, "Syringe Counts", "IS", "1", 0, 0},
1025     { 0x00181046, "Contrast Flow Rate", "DS", "1-n", 0, 0},
1026     { 0x00181047, "Contrast Flow Duration", "DS", "1-n", 0, 0},
1027     { 0x00181048, "Contrast/Bolus Ingredient", "CS", "1", 0, 0},
1028     { 0x00181049, "Contrast/Bolus Ingredient Concentration", "DS", "1", 0, 0},
1029     { 0x00181050, "Spatial Resolution", "DS", "1", 0, 0},
1030     { 0x00181060, "Trigger Time", "DS", "1", 0, 0},
1031     { 0x00181061, "Trigger Source or Type", "LO", "1", 0, 0},
1032     { 0x00181062, "Nominal Interval", "IS", "1", 0, 0},
1033     { 0x00181063, "Frame Time", "DS", "1", 0, 0},
1034     { 0x00181064, "Cardiac Framing Type", "LO", "1", 0, 0},
1035     { 0x00181065, "Frame Time Vector", "DS", "1-n", 0, 0},
1036     { 0x00181066, "Frame Delay", "DS", "1", 0, 0},
1037     { 0x00181067, "Image Trigger Delay", "DS", "1", 0, 0},
1038     { 0x00181068, "Multiplex Group Time Offset", "DS", "1", 0, 0},
1039     { 0x00181069, "Trigger Time Offset", "DS", "1", 0, 0},
1040     { 0x0018106A, "Synchronization Trigger", "CS", "1", 0, 0},
1041     { 0x0018106C, "Synchronization Channel", "US", "2", 0, 0},
1042     { 0x0018106E, "Trigger Sample Position", "UL", "1", 0, 0},
1043     { 0x00181070, "Radiopharmaceutical Route", "LO", "1", 0, 0},
1044     { 0x00181071, "Radiopharmaceutical Volume", "DS", "1", 0, 0},
1045     { 0x00181072, "Radiopharmaceutical Start Time", "TM", "1", 0, 0},
1046     { 0x00181073, "Radiopharmaceutical Stop Time", "TM", "1", 0, 0},
1047     { 0x00181074, "Radionuclide Total Dose", "DS", "1", 0, 0},
1048     { 0x00181075, "Radionuclide Half Life", "DS", "1", 0, 0},
1049     { 0x00181076, "Radionuclide Positron Fraction", "DS", "1", 0, 0},
1050     { 0x00181077, "Radiopharmaceutical Specific Activity", "DS", "1", 0, 0},
1051     { 0x00181078, "Radiopharmaceutical Start DateTime", "DT", "1", 0, 0},
1052     { 0x00181079, "Radiopharmaceutical Stop DateTime", "DT", "1", 0, 0},
1053     { 0x00181080, "Beat Rejection Flag", "CS", "1", 0, 0},
1054     { 0x00181081, "Low R-R Value", "IS", "1", 0, 0},
1055     { 0x00181082, "High R-R Value", "IS", "1", 0, 0},
1056     { 0x00181083, "Intervals Acquired", "IS", "1", 0, 0},
1057     { 0x00181084, "Intervals Rejected", "IS", "1", 0, 0},
1058     { 0x00181085, "PVC Rejection", "LO", "1", 0, 0},
1059     { 0x00181086, "Skip Beats", "IS", "1", 0, 0},
1060     { 0x00181088, "Heart Rate", "IS", "1", 0, 0},
1061     { 0x00181090, "Cardiac Number of Images", "IS", "1", 0, 0},
1062     { 0x00181094, "Trigger Window", "IS", "1", 0, 0},
1063     { 0x00181100, "Reconstruction Diameter", "DS", "1", 0, 0},
1064     { 0x00181110, "Distance Source to Detector", "DS", "1", 0, 0},
1065     { 0x00181111, "Distance Source to Patient", "DS", "1", 0, 0},
1066     { 0x00181114, "Estimated Radiographic Magnification Factor", "DS", "1", 0, 0},
1067     { 0x00181120, "Gantry/Detector Tilt", "DS", "1", 0, 0},
1068     { 0x00181121, "Gantry/Detector Slew", "DS", "1", 0, 0},
1069     { 0x00181130, "Table Height", "DS", "1", 0, 0},
1070     { 0x00181131, "Table Traverse", "DS", "1", 0, 0},
1071     { 0x00181134, "Table Motion", "CS", "1", 0, 0},
1072     { 0x00181135, "Table Vertical Increment", "DS", "1-n", 0, 0},
1073     { 0x00181136, "Table Lateral Increment", "DS", "1-n", 0, 0},
1074     { 0x00181137, "Table Longitudinal Increment", "DS", "1-n", 0, 0},
1075     { 0x00181138, "Table Angle", "DS", "1", 0, 0},
1076     { 0x0018113A, "Table Type", "CS", "1", 0, 0},
1077     { 0x00181140, "Rotation Direction", "CS", "1", 0, 0},
1078     { 0x00181141, "Angular Position", "DS", "1", -1, 0},
1079     { 0x00181142, "Radial Position", "DS", "1-n", 0, 0},
1080     { 0x00181143, "Scan Arc", "DS", "1", 0, 0},
1081     { 0x00181144, "Angular Step", "DS", "1", 0, 0},
1082     { 0x00181145, "Center of Rotation Offset", "DS", "1", 0, 0},
1083     { 0x00181146, "Rotation Offset", "DS", "1-n", -1, 0},
1084     { 0x00181147, "Field of View Shape", "CS", "1", 0, 0},
1085     { 0x00181149, "Field of View Dimension(s)", "IS", "1-2", 0, 0},
1086     { 0x00181150, "Exposure Time", "IS", "1", 0, 0},
1087     { 0x00181151, "X-Ray Tube Current", "IS", "1", 0, 0},
1088     { 0x00181152, "Exposure", "IS", "1", 0, 0},
1089     { 0x00181153, "Exposure in uAs", "IS", "1", 0, 0},
1090     { 0x00181154, "Average Pulse Width", "DS", "1", 0, 0},
1091     { 0x00181155, "Radiation Setting", "CS", "1", 0, 0},
1092     { 0x00181156, "Rectification Type", "CS", "1", 0, 0},
1093     { 0x0018115A, "Radiation Mode", "CS", "1", 0, 0},
1094     { 0x0018115E, "Image and Fluoroscopy Area Dose Product", "DS", "1", 0, 0},
1095     { 0x00181160, "Filter Type", "SH", "1", 0, 0},
1096     { 0x00181161, "Type of Filters", "LO", "1-n", 0, 0},
1097     { 0x00181162, "Intensifier Size", "DS", "1", 0, 0},
1098     { 0x00181164, "Imager Pixel Spacing", "DS", "2", 0, 0},
1099     { 0x00181166, "Grid", "CS", "1-n", 0, 0},
1100     { 0x00181170, "Generator Power", "IS", "1", 0, 0},
1101     { 0x00181180, "Collimator/grid Name", "SH", "1", 0, 0},
1102     { 0x00181181, "Collimator Type", "CS", "1", 0, 0},
1103     { 0x00181182, "Focal Distance", "IS", "1-2", 0, 0},
1104     { 0x00181183, "X Focus Center", "DS", "1-2", 0, 0},
1105     { 0x00181184, "Y Focus Center", "DS", "1-2", 0, 0},
1106     { 0x00181190, "Focal Spot(s)", "DS", "1-n", 0, 0},
1107     { 0x00181191, "Anode Target Material", "CS", "1", 0, 0},
1108     { 0x001811A0, "Body Part Thickness", "DS", "1", 0, 0},
1109     { 0x001811A2, "Compression Force", "DS", "1", 0, 0},
1110     { 0x00181200, "Date of Last Calibration", "DA", "1-n", 0, 0},
1111     { 0x00181201, "Time of Last Calibration", "TM", "1-n", 0, 0},
1112     { 0x00181210, "Convolution Kernel", "SH", "1-n", 0, 0},
1113     { 0x00181240, "Upper/Lower Pixel Values", "IS", "1-n", -1, 0},
1114     { 0x00181242, "Actual Frame Duration", "IS", "1", 0, 0},
1115     { 0x00181243, "Count Rate", "IS", "1", 0, 0},
1116     { 0x00181244, "Preferred Playback Sequencing", "US", "1", 0, 0},
1117     { 0x00181250, "Receive Coil Name", "SH", "1", 0, 0},
1118     { 0x00181251, "Transmit Coil Name", "SH", "1", 0, 0},
1119     { 0x00181260, "Plate Type", "SH", "1", 0, 0},
1120     { 0x00181261, "Phosphor Type", "LO", "1", 0, 0},
1121     { 0x00181300, "Scan Velocity", "DS", "1", 0, 0},
1122     { 0x00181301, "Whole Body Technique", "CS", "1-n", 0, 0},
1123     { 0x00181302, "Scan Length", "IS", "1", 0, 0},
1124     { 0x00181310, "Acquisition Matrix", "US", "4", 0, 0},
1125     { 0x00181312, "In-plane Phase Encoding Direction", "CS", "1", 0, 0},
1126     { 0x00181314, "Flip Angle", "DS", "1", 0, 0},
1127     { 0x00181315, "Variable Flip Angle Flag", "CS", "1", 0, 0},
1128     { 0x00181316, "SAR", "DS", "1", 0, 0},
1129     { 0x00181318, "dB/dt", "DS", "1", 0, 0},
1130     { 0x00181400, "Acquisition Device Processing Description", "LO", "1", 0, 0},
1131     { 0x00181401, "Acquisition Device Processing Code", "LO", "1", 0, 0},
1132     { 0x00181402, "Cassette Orientation", "CS", "1", 0, 0},
1133     { 0x00181403, "Cassette Size", "CS", "1", 0, 0},
1134     { 0x00181404, "Exposures on Plate", "US", "1", 0, 0},
1135     { 0x00181405, "Relative X-Ray Exposure", "IS", "1", 0, 0},
1136     { 0x00181450, "Column Angulation", "DS", "1", 0, 0},
1137     { 0x00181460, "Tomo Layer Height", "DS", "1", 0, 0},
1138     { 0x00181470, "Tomo Angle", "DS", "1", 0, 0},
1139     { 0x00181480, "Tomo Time", "DS", "1", 0, 0},
1140     { 0x00181490, "Tomo Type", "CS", "1", 0, 0},
1141     { 0x00181491, "Tomo Class", "CS", "1", 0, 0},
1142     { 0x00181495, "Number of Tomosynthesis Source Images", "IS", "1", 0, 0},
1143     { 0x00181500, "Positioner Motion", "CS", "1", 0, 0},
1144     { 0x00181508, "Positioner Type", "CS", "1", 0, 0},
1145     { 0x00181510, "Positioner Primary Angle", "DS", "1", 0, 0},
1146     { 0x00181511, "Positioner Secondary Angle", "DS", "1", 0, 0},
1147     { 0x00181520, "Positioner Primary Angle Increment", "DS", "1-n", 0, 0},
1148     { 0x00181521, "Positioner Secondary Angle Increment", "DS", "1-n", 0, 0},
1149     { 0x00181530, "Detector Primary Angle", "DS", "1", 0, 0},
1150     { 0x00181531, "Detector Secondary Angle", "DS", "1", 0, 0},
1151     { 0x00181600, "Shutter Shape", "CS", "1-3", 0, 0},
1152     { 0x00181602, "Shutter Left Vertical Edge", "IS", "1", 0, 0},
1153     { 0x00181604, "Shutter Right Vertical Edge", "IS", "1", 0, 0},
1154     { 0x00181606, "Shutter Upper Horizontal Edge", "IS", "1", 0, 0},
1155     { 0x00181608, "Shutter Lower Horizontal Edge", "IS", "1", 0, 0},
1156     { 0x00181610, "Center of Circular Shutter", "IS", "2", 0, 0},
1157     { 0x00181612, "Radius of Circular Shutter", "IS", "1", 0, 0},
1158     { 0x00181620, "Vertices of the Polygonal Shutter", "IS", "2-2n", 0, 0},
1159     { 0x00181622, "Shutter Presentation Value", "US", "1", 0, 0},
1160     { 0x00181623, "Shutter Overlay Group", "US", "1", 0, 0},
1161     { 0x00181624, "Shutter Presentation Color CIELab Value", "US", "3", 0, 0},
1162     { 0x00181700, "Collimator Shape", "CS", "1-3", 0, 0},
1163     { 0x00181702, "Collimator Left Vertical Edge", "IS", "1", 0, 0},
1164     { 0x00181704, "Collimator Right Vertical Edge", "IS", "1", 0, 0},
1165     { 0x00181706, "Collimator Upper Horizontal Edge", "IS", "1", 0, 0},
1166     { 0x00181708, "Collimator Lower Horizontal Edge", "IS", "1", 0, 0},
1167     { 0x00181710, "Center of Circular Collimator", "IS", "2", 0, 0},
1168     { 0x00181712, "Radius of Circular Collimator", "IS", "1", 0, 0},
1169     { 0x00181720, "Vertices of the Polygonal Collimator", "IS", "2-2n", 0, 0},
1170     { 0x00181800, "Acquisition Time Synchronized", "CS", "1", 0, 0},
1171     { 0x00181801, "Time Source", "SH", "1", 0, 0},
1172     { 0x00181802, "Time Distribution Protocol", "CS", "1", 0, 0},
1173     { 0x00181803, "NTP Source Address", "LO", "1", 0, 0},
1174     { 0x00182001, "Page Number Vector", "IS", "1-n", 0, 0},
1175     { 0x00182002, "Frame Label Vector", "SH", "1-n", 0, 0},
1176     { 0x00182003, "Frame Primary Angle Vector", "DS", "1-n", 0, 0},
1177     { 0x00182004, "Frame Secondary Angle Vector", "DS", "1-n", 0, 0},
1178     { 0x00182005, "Slice Location Vector", "DS", "1-n", 0, 0},
1179     { 0x00182006, "Display Window Label Vector", "SH", "1-n", 0, 0},
1180     { 0x00182010, "Nominal Scanned Pixel Spacing", "DS", "2", 0, 0},
1181     { 0x00182020, "Digitizing Device Transport Direction", "CS", "1", 0, 0},
1182     { 0x00182030, "Rotation of Scanned Film", "DS", "1", 0, 0},
1183     { 0x00183100, "IVUS Acquisition", "CS", "1", 0, 0},
1184     { 0x00183101, "IVUS Pullback Rate", "DS", "1", 0, 0},
1185     { 0x00183102, "IVUS Gated Rate", "DS", "1", 0, 0},
1186     { 0x00183103, "IVUS Pullback Start Frame Number", "IS", "1", 0, 0},
1187     { 0x00183104, "IVUS Pullback Stop Frame Number", "IS", "1", 0, 0},
1188     { 0x00183105, "Lesion Number", "IS", "1-n", 0, 0},
1189     { 0x00184000, "Acquisition Comments", "LT", "1", -1, 0},
1190     { 0x00185000, "Output Power", "SH", "1-n", 0, 0},
1191     { 0x00185010, "Transducer Data", "LO", "3", 0, 0},
1192     { 0x00185012, "Focus Depth", "DS", "1", 0, 0},
1193     { 0x00185020, "Processing Function", "LO", "1", 0, 0},
1194     { 0x00185021, "Postprocessing Function", "LO", "1", -1, 0},
1195     { 0x00185022, "Mechanical Index", "DS", "1", 0, 0},
1196     { 0x00185024, "Bone Thermal Index", "DS", "1", 0, 0},
1197     { 0x00185026, "Cranial Thermal Index", "DS", "1", 0, 0},
1198     { 0x00185027, "Soft Tissue Thermal Index", "DS", "1", 0, 0},
1199     { 0x00185028, "Soft Tissue-focus Thermal Index", "DS", "1", 0, 0},
1200     { 0x00185029, "Soft Tissue-surface Thermal Index", "DS", "1", 0, 0},
1201     { 0x00185030, "Dynamic Range", "DS", "1", -1, 0},
1202     { 0x00185040, "Total Gain", "DS", "1", -1, 0},
1203     { 0x00185050, "Depth of Scan Field", "IS", "1", 0, 0},
1204     { 0x00185100, "Patient Position", "CS", "1", 0, -1},
1205     { 0x00185101, "View Position", "CS", "1", 0, 0},
1206     { 0x00185104, "Projection Eponymous Name Code Sequence", "SQ", "1", 0, 0},
1207     { 0x00185210, "Image Transformation Matrix", "DS", "6", -1, 0},
1208     { 0x00185212, "Image Translation Vector", "DS", "3", -1, 0},
1209     { 0x00186000, "Sensitivity", "DS", "1", 0, 0},
1210     { 0x00186011, "Sequence of Ultrasound Regions", "SQ", "1", 0, 0},
1211     { 0x00186012, "Region Spatial Format", "US", "1", 0, 0},
1212     { 0x00186014, "Region Data Type", "US", "1", 0, 0},
1213     { 0x00186016, "Region Flags", "UL", "1", 0, 0},
1214     { 0x00186018, "Region Location Min X0", "UL", "1", 0, 0},
1215     { 0x0018601A, "Region Location Min Y0", "UL", "1", 0, 0},
1216     { 0x0018601C, "Region Location Max X1", "UL", "1", 0, 0},
1217     { 0x0018601E, "Region Location Max Y1", "UL", "1", 0, 0},
1218     { 0x00186020, "Reference Pixel X0", "SL", "1", 0, 0},
1219     { 0x00186022, "Reference Pixel Y0", "SL", "1", 0, 0},
1220     { 0x00186024, "Physical Units X Direction", "US", "1", 0, 0},
1221     { 0x00186026, "Physical Units Y Direction", "US", "1", 0, 0},
1222     { 0x00186028, "Reference Pixel Physical Value X", "FD", "1", 0, 0},
1223     { 0x0018602A, "Reference Pixel Physical Value Y", "FD", "1", 0, 0},
1224     { 0x0018602C, "Physical Delta X", "FD", "1", 0, 0},
1225     { 0x0018602E, "Physical Delta Y", "FD", "1", 0, 0},
1226     { 0x00186030, "Transducer Frequency", "UL", "1", 0, 0},
1227     { 0x00186031, "Transducer Type", "CS", "1", 0, 0},
1228     { 0x00186032, "Pulse Repetition Frequency", "UL", "1", 0, 0},
1229     { 0x00186034, "Doppler Correction Angle", "FD", "1", 0, 0},
1230     { 0x00186036, "Steering Angle", "FD", "1", 0, 0},
1231     { 0x00186038, "Doppler Sample Volume X Position (Retired)", "UL", "1", -1, 0},
1232     { 0x00186039, "Doppler Sample Volume X Position", "SL", "1", 0, 0},
1233     { 0x0018603A, "Doppler Sample Volume Y Position (Retired)", "UL", "1", -1, 0},
1234     { 0x0018603B, "Doppler Sample Volume Y Position", "SL", "1", 0, 0},
1235     { 0x0018603C, "TM-Line Position X0 (Retired)", "UL", "1", -1, 0},
1236     { 0x0018603D, "TM-Line Position X0", "SL", "1", 0, 0},
1237     { 0x0018603E, "TM-Line Position Y0 (Retired)", "UL", "1", -1, 0},
1238     { 0x0018603F, "TM-Line Position Y0", "SL", "1", 0, 0},
1239     { 0x00186040, "TM-Line Position X1 (Retired)", "UL", "1", -1, 0},
1240     { 0x00186041, "TM-Line Position X1", "SL", "1", 0, 0},
1241     { 0x00186042, "TM-Line Position Y1 (Retired)", "UL", "1", -1, 0},
1242     { 0x00186043, "TM-Line Position Y1", "SL", "1", 0, 0},
1243     { 0x00186044, "Pixel Component Organization", "US", "1", 0, 0},
1244     { 0x00186046, "Pixel Component Mask", "UL", "1", 0, 0},
1245     { 0x00186048, "Pixel Component Range Start", "UL", "1", 0, 0},
1246     { 0x0018604A, "Pixel Component Range Stop", "UL", "1", 0, 0},
1247     { 0x0018604C, "Pixel Component Physical Units", "US", "1", 0, 0},
1248     { 0x0018604E, "Pixel Component Data Type", "US", "1", 0, 0},
1249     { 0x00186050, "Number of Table Break Points", "UL", "1", 0, 0},
1250     { 0x00186052, "Table of X Break Points", "UL", "1-n", 0, 0},
1251     { 0x00186054, "Table of Y Break Points", "FD", "1-n", 0, 0},
1252     { 0x00186056, "Number of Table Entries", "UL", "1", 0, 0},
1253     { 0x00186058, "Table of Pixel Values", "UL", "1-n", 0, 0},
1254     { 0x0018605A, "Table of Parameter Values", "FL", "1-n", 0, 0},
1255     { 0x00186060, "R Wave Time Vector", "FL", "1-n", 0, 0},
1256     { 0x00187000, "Detector Conditions Nominal Flag", "CS", "1", 0, 0},
1257     { 0x00187001, "Detector Temperature", "DS", "1", 0, 0},
1258     { 0x00187004, "Detector Type", "CS", "1", 0, 0},
1259     { 0x00187005, "Detector Configuration", "CS", "1", 0, 0},
1260     { 0x00187006, "Detector Description", "LT", "1", 0, 0},
1261     { 0x00187008, "Detector Mode", "LT", "1", 0, 0},
1262     { 0x0018700A, "Detector ID", "SH", "1", 0, 0},
1263     { 0x0018700C, "Date of Last Detector Calibration", "DA", "1", 0, 0},
1264     { 0x0018700E, "Time of Last Detector Calibration", "TM", "1", 0, 0},
1265     { 0x00187010, "Exposures on Detector Since Last Calibration", "IS", "1", 0, 0},
1266     { 0x00187011, "Exposures on Detector Since Manufactured", "IS", "1", 0, 0},
1267     { 0x00187012, "Detector Time Since Last Exposure", "DS", "1", 0, 0},
1268     { 0x00187014, "Detector Active Time", "DS", "1", 0, 0},
1269     { 0x00187016, "Detector Activation Offset From Exposure", "DS", "1", 0, 0},
1270     { 0x0018701A, "Detector Binning", "DS", "2", 0, 0},
1271     { 0x00187020, "Detector Element Physical Size", "DS", "2", 0, 0},
1272     { 0x00187022, "Detector Element Spacing", "DS", "2", 0, 0},
1273     { 0x00187024, "Detector Active Shape", "CS", "1", 0, 0},
1274     { 0x00187026, "Detector Active Dimension(s)", "DS", "1-2", 0, 0},
1275     { 0x00187028, "Detector Active Origin", "DS", "2", 0, 0},
1276     { 0x0018702A, "Detector Manufacturer Name", "LO", "1", 0, 0},
1277     { 0x0018702B, "Detector Manufacturer's Model Name", "LO", "1", 0, 0},
1278     { 0x00187030, "Field of View Origin", "DS", "2", 0, 0},
1279     { 0x00187032, "Field of View Rotation", "DS", "1", 0, 0},
1280     { 0x00187034, "Field of View Horizontal Flip", "CS", "1", 0, 0},
1281     { 0x00187040, "Grid Absorbing Material", "LT", "1", 0, 0},
1282     { 0x00187041, "Grid Spacing Material", "LT", "1", 0, 0},
1283     { 0x00187042, "Grid Thickness", "DS", "1", 0, 0},
1284     { 0x00187044, "Grid Pitch", "DS", "1", 0, 0},
1285     { 0x00187046, "Grid Aspect Ratio", "IS", "2", 0, 0},
1286     { 0x00187048, "Grid Period", "DS", "1", 0, 0},
1287     { 0x0018704C, "Grid Focal Distance", "DS", "1", 0, 0},
1288     { 0x00187050, "Filter Material", "CS", "1-n", 0, 0},
1289     { 0x00187052, "Filter Thickness Minimum", "DS", "1-n", 0, 0},
1290     { 0x00187054, "Filter Thickness Maximum", "DS", "1-n", 0, 0},
1291     { 0x00187060, "Exposure Control Mode", "CS", "1", 0, 0},
1292     { 0x00187062, "Exposure Control Mode Description", "LT", "1", 0, 0},
1293     { 0x00187064, "Exposure Status", "CS", "1", 0, 0},
1294     { 0x00187065, "Phototimer Setting", "DS", "1", 0, 0},
1295     { 0x00188150, "Exposure Time in uS", "DS", "1", 0, 0},
1296     { 0x00188151, "X-Ray Tube Current in uA", "DS", "1", 0, 0},
1297     { 0x00189004, "Content Qualification", "CS", "1", 0, 0},
1298     { 0x00189005, "Pulse Sequence Name", "SH", "1", 0, 0},
1299     { 0x00189006, "MR Imaging Modifier Sequence", "SQ", "1", 0, 0},
1300     { 0x00189008, "Echo Pulse Sequence", "CS", "1", 0, 0},
1301     { 0x00189009, "Inversion Recovery", "CS", "1", 0, 0},
1302     { 0x00189010, "Flow Compensation", "CS", "1", 0, 0},
1303     { 0x00189011, "Multiple Spin Echo", "CS", "1", 0, 0},
1304     { 0x00189012, "Multi-planar Excitation", "CS", "1", 0, 0},
1305     { 0x00189014, "Phase Contrast", "CS", "1", 0, 0},
1306     { 0x00189015, "Time of Flight Contrast", "CS", "1", 0, 0},
1307     { 0x00189016, "Spoiling", "CS", "1", 0, 0},
1308     { 0x00189017, "Steady State Pulse Sequence", "CS", "1", 0, 0},
1309     { 0x00189018, "Echo Planar Pulse Sequence", "CS", "1", 0, 0},
1310     { 0x00189019, "Tag Angle First Axis", "FD", "1", 0, 0},
1311     { 0x00189020, "Magnetization Transfer", "CS", "1", 0, 0},
1312     { 0x00189021, "T2 Preparation", "CS", "1", 0, 0},
1313     { 0x00189022, "Blood Signal Nulling", "CS", "1", 0, 0},
1314     { 0x00189024, "Saturation Recovery", "CS", "1", 0, 0},
1315     { 0x00189025, "Spectrally Selected Suppression", "CS", "1", 0, 0},
1316     { 0x00189026, "Spectrally Selected Excitation", "CS", "1", 0, 0},
1317     { 0x00189027, "Spatial Pre-saturation", "CS", "1", 0, 0},
1318     { 0x00189028, "Tagging", "CS", "1", 0, 0},
1319     { 0x00189029, "Oversampling Phase", "CS", "1", 0, 0},
1320     { 0x00189030, "Tag Spacing First Dimension", "FD", "1", 0, 0},
1321     { 0x00189032, "Geometry of k-Space Traversal", "CS", "1", 0, 0},
1322     { 0x00189033, "Segmented k-Space Traversal", "CS", "1", 0, 0},
1323     { 0x00189034, "Rectilinear Phase Encode Reordering", "CS", "1", 0, 0},
1324     { 0x00189035, "Tag Thickness", "FD", "1", 0, 0},
1325     { 0x00189036, "Partial Fourier Direction", "CS", "1", 0, 0},
1326     { 0x00189037, "Cardiac Synchronization Technique", "CS", "1", 0, 0},
1327     { 0x00189041, "Receive Coil Manufacturer Name", "LO", "1", 0, 0},
1328     { 0x00189042, "MR Receive Coil Sequence", "SQ", "1", 0, 0},
1329     { 0x00189043, "Receive Coil Type", "CS", "1", 0, 0},
1330     { 0x00189044, "Quadrature Receive Coil", "CS", "1", 0, 0},
1331     { 0x00189045, "Multi-Coil Definition Sequence", "SQ", "1", 0, 0},
1332     { 0x00189046, "Multi-Coil Configuration", "LO", "1", 0, 0},
1333     { 0x00189047, "Multi-Coil Element Name", "SH", "1", 0, 0},
1334     { 0x00189048, "Multi-Coil Element Used", "CS", "1", 0, 0},
1335     { 0x00189049, "MR Transmit Coil Sequence", "SQ", "1", 0, 0},
1336     { 0x00189050, "Transmit Coil Manufacturer Name", "LO", "1", 0, 0},
1337     { 0x00189051, "Transmit Coil Type", "CS", "1", 0, 0},
1338     { 0x00189052, "Spectral Width", "FD", "1-2", 0, 0},
1339     { 0x00189053, "Chemical Shift Reference", "FD", "1-2", 0, 0},
1340     { 0x00189054, "Volume Localization Technique", "CS", "1", 0, 0},
1341     { 0x00189058, "MR Acquisition Frequency Encoding Steps", "US", "1", 0, 0},
1342     { 0x00189059, "De-coupling", "CS", "1", 0, 0},
1343     { 0x00189060, "De-coupled Nucleus", "CS", "1-2", 0, 0},
1344     { 0x00189061, "De-coupling Frequency", "FD", "1-2", 0, 0},
1345     { 0x00189062, "De-coupling Method", "CS", "1", 0, 0},
1346     { 0x00189063, "De-coupling Chemical Shift Reference", "FD", "1-2", 0, 0},
1347     { 0x00189064, "k-space Filtering", "CS", "1", 0, 0},
1348     { 0x00189065, "Time Domain Filtering", "CS", "1-2", 0, 0},
1349     { 0x00189066, "Number of Zero fills", "US", "1-2", 0, 0},
1350     { 0x00189067, "Baseline Correction", "CS", "1", 0, 0},
1351     { 0x00189069, "Parallel Reduction Factor In-plane", "FD", "1", 0, 0},
1352     { 0x00189070, "Cardiac R-R Interval Specified", "FD", "1", 0, 0},
1353     { 0x00189073, "Acquisition Duration", "FD", "1", 0, 0},
1354     { 0x00189074, "Frame Acquisition DateTime", "DT", "1", 0, 0},
1355     { 0x00189075, "Diffusion Directionality", "CS", "1", 0, 0},
1356     { 0x00189076, "Diffusion Gradient Direction Sequence", "SQ", "1", 0, 0},
1357     { 0x00189077, "Parallel Acquisition", "CS", "1", 0, 0},
1358     { 0x00189078, "Parallel Acquisition Technique", "CS", "1", 0, 0},
1359     { 0x00189079, "Inversion Times", "FD", "1-n", 0, 0},
1360     { 0x00189080, "Metabolite Map Description", "ST", "1", 0, 0},
1361     { 0x00189081, "Partial Fourier", "CS", "1", 0, 0},
1362     { 0x00189082, "Effective Echo Time", "FD", "1", 0, 0},
1363     { 0x00189083, "Metabolite Map Code Sequence", "SQ", "1", 0, 0},
1364     { 0x00189084, "Chemical Shift Sequence", "SQ", "1", 0, 0},
1365     { 0x00189085, "Cardiac Signal Source", "CS", "1", 0, 0},
1366     { 0x00189087, "Diffusion b-value", "FD", "1", 0, 0},
1367     { 0x00189089, "Diffusion Gradient Orientation", "FD", "3", 0, 0},
1368     { 0x00189090, "Velocity Encoding Direction", "FD", "3", 0, 0},
1369     { 0x00189091, "Velocity Encoding Minimum Value", "FD", "1", 0, 0},
1370     { 0x00189093, "Number of k-Space Trajectories", "US", "1", 0, 0},
1371     { 0x00189094, "Coverage of k-Space", "CS", "1", 0, 0},
1372     { 0x00189095, "Spectroscopy Acquisition Phase Rows", "UL", "1", 0, 0},
1373     { 0x00189096, "Parallel Reduction Factor In-plane (Retired)", "FD", "1", -1, 0},
1374     { 0x00189098, "Transmitter Frequency", "FD", "1-2", 0, 0},
1375     { 0x00189100, "Resonant Nucleus", "CS", "1-2", 0, 0},
1376     { 0x00189101, "Frequency Correction", "CS", "1", 0, 0},
1377     { 0x00189103, "MR Spectroscopy FOV/Geometry Sequence", "SQ", "1", 0, 0},
1378     { 0x00189104, "Slab Thickness", "FD", "1", 0, 0},
1379     { 0x00189105, "Slab Orientation", "FD", "3", 0, 0},
1380     { 0x00189106, "Mid Slab Position", "FD", "3", 0, 0},
1381     { 0x00189107, "MR Spatial Saturation Sequence", "SQ", "1", 0, 0},
1382     { 0x00189112, "MR Timing and Related Parameters Sequence", "SQ", "1", 0, 0},
1383     { 0x00189114, "MR Echo Sequence", "SQ", "1", 0, 0},
1384     { 0x00189115, "MR Modifier Sequence", "SQ", "1", 0, 0},
1385     { 0x00189117, "MR Diffusion Sequence", "SQ", "1", 0, 0},
1386     { 0x00189118, "Cardiac Synchronization Sequence", "SQ", "1", 0, 0},
1387     { 0x00189119, "MR Averages Sequence", "SQ", "1", 0, 0},
1388     { 0x00189125, "MR FOV/Geometry Sequence", "SQ", "1", 0, 0},
1389     { 0x00189126, "Volume Localization Sequence", "SQ", "1", 0, 0},
1390     { 0x00189127, "Spectroscopy Acquisition Data Columns", "UL", "1", 0, 0},
1391     { 0x00189147, "Diffusion Anisotropy Type", "CS", "1", 0, 0},
1392     { 0x00189151, "Frame Reference DateTime", "DT", "1", 0, 0},
1393     { 0x00189152, "MR Metabolite Map Sequence", "SQ", "1", 0, 0},
1394     { 0x00189155, "Parallel Reduction Factor out-of-plane", "FD", "1", 0, 0},
1395     { 0x00189159, "Spectroscopy Acquisition Out-of-plane Phase Steps", "UL", "1", 0, 0},
1396     { 0x00189166, "Bulk Motion Status", "CS", "1", -1, 0},
1397     { 0x00189168, "Parallel Reduction Factor Second In-plane", "FD", "1", 0, 0},
1398     { 0x00189169, "Cardiac Beat Rejection Technique", "CS", "1", 0, 0},
1399     { 0x00189170, "Respiratory Motion Compensation Technique", "CS", "1", 0, 0},
1400     { 0x00189171, "Respiratory Signal Source", "CS", "1", 0, 0},
1401     { 0x00189172, "Bulk Motion Compensation Technique", "CS", "1", 0, 0},
1402     { 0x00189173, "Bulk Motion Signal Source", "CS", "1", 0, 0},
1403     { 0x00189174, "Applicable Safety Standard Agency", "CS", "1", 0, 0},
1404     { 0x00189175, "Applicable Safety Standard Description", "LO", "1", 0, 0},
1405     { 0x00189176, "Operating Mode Sequence", "SQ", "1", 0, 0},
1406     { 0x00189177, "Operating Mode Type", "CS", "1", 0, 0},
1407     { 0x00189178, "Operating Mode", "CS", "1", 0, 0},
1408     { 0x00189179, "Specific Absorption Rate Definition", "CS", "1", 0, 0},
1409     { 0x00189180, "Gradient Output Type", "CS", "1", 0, 0},
1410     { 0x00189181, "Specific Absorption Rate Value", "FD", "1", 0, 0},
1411     { 0x00189182, "Gradient Output", "FD", "1", 0, 0},
1412     { 0x00189183, "Flow Compensation Direction", "CS", "1", 0, 0},
1413     { 0x00189184, "Tagging Delay", "FD", "1", 0, 0},
1414     { 0x00189185, "Respiratory Motion Compensation Technique Description", "ST", "1", 0, 0},
1415     { 0x00189186, "Respiratory Signal Source ID", "SH", "1", 0, 0},
1416     { 0x00189195, "Chemical Shifts Minimum Integration Limit in Hz", "FD", "1", -1, 0},
1417     { 0x00189196, "Chemical Shifts Maximum Integration Limit in Hz", "FD", "1", -1, 0},
1418     { 0x00189197, "MR Velocity Encoding Sequence", "SQ", "1", 0, 0},
1419     { 0x00189198, "First Order Phase Correction", "CS", "1", 0, 0},
1420     { 0x00189199, "Water Referenced Phase Correction", "CS", "1", 0, 0},
1421     { 0x00189200, "MR Spectroscopy Acquisition Type", "CS", "1", 0, 0},
1422     { 0x00189214, "Respiratory Cycle Position", "CS", "1", 0, 0},
1423     { 0x00189217, "Velocity Encoding Maximum Value", "FD", "1", 0, 0},
1424     { 0x00189218, "Tag Spacing Second Dimension", "FD", "1", 0, 0},
1425     { 0x00189219, "Tag Angle Second Axis", "SS", "1", 0, 0},
1426     { 0x00189220, "Frame Acquisition Duration", "FD", "1", 0, 0},
1427     { 0x00189226, "MR Image Frame Type Sequence", "SQ", "1", 0, 0},
1428     { 0x00189227, "MR Spectroscopy Frame Type Sequence", "SQ", "1", 0, 0},
1429     { 0x00189231, "MR Acquisition Phase Encoding Steps in-plane", "US", "1", 0, 0},
1430     { 0x00189232, "MR Acquisition Phase Encoding Steps out-of-plane", "US", "1", 0, 0},
1431     { 0x00189234, "Spectroscopy Acquisition Phase Columns", "UL", "1", 0, 0},
1432     { 0x00189236, "Cardiac Cycle Position", "CS", "1", 0, 0},
1433     { 0x00189239, "Specific Absorption Rate Sequence", "SQ", "1", 0, 0},
1434     { 0x00189240, "RF Echo Train Length", "US", "1", 0, 0},
1435     { 0x00189241, "Gradient Echo Train Length", "US", "1", 0, 0},
1436     { 0x00189295, "Chemical Shifts Minimum Integration Limit in ppm", "FD", "1", 0, 0},
1437     { 0x00189296, "Chemical Shifts Maximum Integration Limit in ppm", "FD", "1", 0, 0},
1438     { 0x00189301, "CT Acquisition Type Sequence", "SQ", "1", 0, 0},
1439     { 0x00189302, "Acquisition Type", "CS", "1", 0, 0},
1440     { 0x00189303, "Tube Angle", "FD", "1", 0, 0},
1441     { 0x00189304, "CT Acquisition Details Sequence", "SQ", "1", 0, 0},
1442     { 0x00189305, "Revolution Time", "FD", "1", 0, 0},
1443     { 0x00189306, "Single Collimation Width", "FD", "1", 0, 0},
1444     { 0x00189307, "Total Collimation Width", "FD", "1", 0, 0},
1445     { 0x00189308, "CT Table Dynamics Sequence", "SQ", "1", 0, 0},
1446     { 0x00189309, "Table Speed", "FD", "1", 0, 0},
1447     { 0x00189310, "Table Feed per Rotation", "FD", "1", 0, 0},
1448     { 0x00189311, "Spiral Pitch Factor", "FD", "1", 0, 0},
1449     { 0x00189312, "CT Geometry Sequence", "SQ", "1", 0, 0},
1450     { 0x00189313, "Data Collection Center (Patient)", "FD", "3", 0, 0},
1451     { 0x00189314, "CT Reconstruction Sequence", "SQ", "1", 0, 0},
1452     { 0x00189315, "Reconstruction Algorithm", "CS", "1", 0, 0},
1453     { 0x00189316, "Convolution Kernel Group", "CS", "1", 0, 0},
1454     { 0x00189317, "Reconstruction Field of View", "FD", "2", 0, 0},
1455     { 0x00189318, "Reconstruction Target Center (Patient)", "FD", "3", 0, 0},
1456     { 0x00189319, "Reconstruction Angle", "FD", "1", 0, 0},
1457     { 0x00189320, "Image Filter", "SH", "1", 0, 0},
1458     { 0x00189321, "CT Exposure Sequence", "SQ", "1", 0, 0},
1459     { 0x00189322, "Reconstruction Pixel Spacing", "FD", "2", 0, 0},
1460     { 0x00189323, "Exposure Modulation Type", "CS", "1", 0, 0},
1461     { 0x00189324, "Estimated Dose Saving", "FD", "1", 0, 0},
1462     { 0x00189325, "CT X-Ray Details Sequence", "SQ", "1", 0, 0},
1463     { 0x00189326, "CT Position Sequence", "SQ", "1", 0, 0},
1464     { 0x00189327, "Table Position", "FD", "1", 0, 0},
1465     { 0x00189328, "Exposure Time in ms", "FD", "1", 0, 0},
1466     { 0x00189329, "CT Image Frame Type Sequence", "SQ", "1", 0, 0},
1467     { 0x00189330, "X-Ray Tube Current in mA", "FD", "1", 0, 0},
1468     { 0x00189332, "Exposure in mAs", "FD", "1", 0, 0},
1469     { 0x00189333, "Constant Volume Flag", "CS", "1", 0, 0},
1470     { 0x00189334, "Fluoroscopy Flag", "CS", "1", 0, 0},
1471     { 0x00189335, "Distance Source to Data Collection Center", "FD", "1", 0, 0},
1472     { 0x00189337, "Contrast/Bolus Agent Number", "US", "1", 0, 0},
1473     { 0x00189338, "Contrast/Bolus Ingredient Code Sequence", "SQ", "1", 0, 0},
1474     { 0x00189340, "Contrast Administration Profile Sequence", "SQ", "1", 0, 0},
1475     { 0x00189341, "Contrast/Bolus Usage Sequence", "SQ", "1", 0, 0},
1476     { 0x00189342, "Contrast/Bolus Agent Administered", "CS", "1", 0, 0},
1477     { 0x00189343, "Contrast/Bolus Agent Detected", "CS", "1", 0, 0},
1478     { 0x00189344, "Contrast/Bolus Agent Phase", "CS", "1", 0, 0},
1479     { 0x00189345, "CTDIvol", "FD", "1", 0, 0},
1480     { 0x00189346, "CTDI Phantom Type Code Sequence", "SQ", "1", 0, 0},
1481     { 0x00189351, "Calcium Scoring Mass Factor Patient", "FL", "1", 0, 0},
1482     { 0x00189352, "Calcium Scoring Mass Factor Device", "FL", "3", 0, 0},
1483     { 0x00189360, "CT Additional X-Ray Source Sequence", "SQ", "1", 0, 0},
1484     { 0x00189401, "Projection Pixel Calibration Sequence", "SQ", "1", 0, 0},
1485     { 0x00189402, "Distance Source to Isocenter", "FL", "1", 0, 0},
1486     { 0x00189403, "Distance Object to Table Top", "FL", "1", 0, 0},
1487     { 0x00189404, "Object Pixel Spacing in Center of Beam", "FL", "2", 0, 0},
1488     { 0x00189405, "Positioner Position Sequence", "SQ", "1", 0, 0},
1489     { 0x00189406, "Table Position Sequence", "SQ", "1", 0, 0},
1490     { 0x00189407, "Collimator Shape Sequence", "SQ", "1", 0, 0},
1491     { 0x00189412, "XA/XRF Frame Characteristics Sequence", "SQ", "1", 0, 0},
1492     { 0x00189417, "Frame Acquisition Sequence", "SQ", "1", 0, 0},
1493     { 0x00189420, "X-Ray Receptor Type", "CS", "1", 0, 0},
1494     { 0x00189423, "Acquisition Protocol Name", "LO", "1", 0, 0},
1495     { 0x00189424, "Acquisition Protocol Description", "LT", "1", 0, 0},
1496     { 0x00189425, "Contrast/Bolus Ingredient Opaque", "CS", "1", 0, 0},
1497     { 0x00189426, "Distance Receptor Plane to Detector Housing", "FL", "1", 0, 0},
1498     { 0x00189427, "Intensifier Active Shape", "CS", "1", 0, 0},
1499     { 0x00189428, "Intensifier Active Dimension(s)", "FL", "1-2", 0, 0},
1500     { 0x00189429, "Physical Detector Size", "FL", "2", 0, 0},
1501     { 0x00189430, "Position of Isocenter Projection", "US", "2", 0, 0},
1502     { 0x00189432, "Field of View Sequence", "SQ", "1", 0, 0},
1503     { 0x00189433, "Field of View Description", "LO", "1", 0, 0},
1504     { 0x00189434, "Exposure Control Sensing Regions Sequence", "SQ", "1", 0, 0},
1505     { 0x00189435, "Exposure Control Sensing Region Shape", "CS", "1", 0, 0},
1506     { 0x00189436, "Exposure Control Sensing Region Left Vertical Edge", "SS", "1", 0, 0},
1507     { 0x00189437, "Exposure Control Sensing Region Right Vertical Edge", "SS", "1", 0, 0},
1508     { 0x00189438, "Exposure Control Sensing Region Upper Horizontal Edge", "SS", "1", 0, 0},
1509     { 0x00189439, "Exposure Control Sensing Region Lower Horizontal Edge", "SS", "1", 0, 0},
1510     { 0x00189440, "Center of Circular Exposure Control Sensing Region", "SS", "2", 0, 0},
1511     { 0x00189441, "Radius of Circular Exposure Control Sensing Region", "US", "1", 0, 0},
1512     { 0x00189442, "Vertices of the Polygonal Exposure Control Sensing Region", "SS", "2-n", 0, 0},
1513     { 0x00189445, "", "", "", -1, 0},
1514     { 0x00189447, "Column Angulation (Patient)", "FL", "1", 0, 0},
1515     { 0x00189449, "Beam Angle", "FL", "1", 0, 0},
1516     { 0x00189451, "Frame Detector Parameters Sequence", "SQ", "1", 0, 0},
1517     { 0x00189452, "Calculated Anatomy Thickness", "FL", "1", 0, 0},
1518     { 0x00189455, "Calibration Sequence", "SQ", "1", 0, 0},
1519     { 0x00189456, "Object Thickness Sequence", "SQ", "1", 0, 0},
1520     { 0x00189457, "Plane Identification", "CS", "1", 0, 0},
1521     { 0x00189461, "Field of View Dimension(s) in Float", "FL", "1-2", 0, 0},
1522     { 0x00189462, "Isocenter Reference System Sequence", "SQ", "1", 0, 0},
1523     { 0x00189463, "Positioner Isocenter Primary Angle", "FL", "1", 0, 0},
1524     { 0x00189464, "Positioner Isocenter Secondary Angle", "FL", "1", 0, 0},
1525     { 0x00189465, "Positioner Isocenter Detector Rotation Angle", "FL", "1", 0, 0},
1526     { 0x00189466, "Table X Position to Isocenter", "FL", "1", 0, 0},
1527     { 0x00189467, "Table Y Position to Isocenter", "FL", "1", 0, 0},
1528     { 0x00189468, "Table Z Position to Isocenter", "FL", "1", 0, 0},
1529     { 0x00189469, "Table Horizontal Rotation Angle", "FL", "1", 0, 0},
1530     { 0x00189470, "Table Head Tilt Angle", "FL", "1", 0, 0},
1531     { 0x00189471, "Table Cradle Tilt Angle", "FL", "1", 0, 0},
1532     { 0x00189472, "Frame Display Shutter Sequence", "SQ", "1", 0, 0},
1533     { 0x00189473, "Acquired Image Area Dose Product", "FL", "1", 0, 0},
1534     { 0x00189474, "C-arm Positioner Tabletop Relationship", "CS", "1", 0, 0},
1535     { 0x00189476, "X-Ray Geometry Sequence", "SQ", "1", 0, 0},
1536     { 0x00189477, "Irradiation Event Identification Sequence", "SQ", "1", 0, 0},
1537     { 0x00189504, "X-Ray 3D Frame Type Sequence", "SQ", "1", 0, 0},
1538     { 0x00189506, "Contributing Sources Sequence", "SQ", "1", 0, 0},
1539     { 0x00189507, "X-Ray 3D Acquisition Sequence", "SQ", "1", 0, 0},
1540     { 0x00189508, "Primary Positioner Scan Arc", "FL", "1", 0, 0},
1541     { 0x00189509, "Secondary Positioner Scan Arc", "FL", "1", 0, 0},
1542     { 0x00189510, "Primary Positioner Scan Start Angle", "FL", "1", 0, 0},
1543     { 0x00189511, "Secondary Positioner Scan Start Angle", "FL", "1", 0, 0},
1544     { 0x00189514, "Primary Positioner Increment", "FL", "1", 0, 0},
1545     { 0x00189515, "Secondary Positioner Increment", "FL", "1", 0, 0},
1546     { 0x00189516, "Start Acquisition DateTime", "DT", "1", 0, 0},
1547     { 0x00189517, "End Acquisition DateTime", "DT", "1", 0, 0},
1548     { 0x00189524, "Application Name", "LO", "1", 0, 0},
1549     { 0x00189525, "Application Version", "LO", "1", 0, 0},
1550     { 0x00189526, "Application Manufacturer", "LO", "1", 0, 0},
1551     { 0x00189527, "Algorithm Type", "CS", "1", 0, 0},
1552     { 0x00189528, "Algorithm Description", "LO", "1", 0, 0},
1553     { 0x00189530, "X-Ray 3D Reconstruction Sequence", "SQ", "1", 0, 0},
1554     { 0x00189531, "Reconstruction Description", "LO", "1", 0, 0},
1555     { 0x00189538, "Per Projection Acquisition Sequence", "SQ", "1", 0, 0},
1556     { 0x00189601, "Diffusion b-matrix Sequence", "SQ", "1", 0, 0},
1557     { 0x00189602, "Diffusion b-value XX", "FD", "1", 0, 0},
1558     { 0x00189603, "Diffusion b-value XY", "FD", "1", 0, 0},
1559     { 0x00189604, "Diffusion b-value XZ", "FD", "1", 0, 0},
1560     { 0x00189605, "Diffusion b-value YY", "FD", "1", 0, 0},
1561     { 0x00189606, "Diffusion b-value YZ", "FD", "1", 0, 0},
1562     { 0x00189607, "Diffusion b-value ZZ", "FD", "1", 0, 0},
1563     { 0x0018A001, "Contributing Equipment Sequence", "SQ", "1", 0, 0},
1564     { 0x0018A002, "Contribution Date Time", "DT", "1", 0, 0},
1565     { 0x0018A003, "Contribution Description", "ST", "1", 0, 0},
1566     { 0x0020000D, "Study Instance UID", "UI", "1", 0, 0},
1567     { 0x0020000E, "Series Instance UID", "UI", "1", 0, 0},
1568     { 0x00200010, "Study ID", "SH", "1", 0, 0},
1569     { 0x00200011, "Series Number", "IS", "1", 0, 0},
1570     { 0x00200012, "Acquisition Number", "IS", "1", 0, 0},
1571     { 0x00200013, "Instance Number", "IS", "1", 0, 0},
1572     { 0x00200014, "Isotope Number", "IS", "1", -1, 0},
1573     { 0x00200015, "Phase Number", "IS", "1", -1, 0},
1574     { 0x00200016, "Interval Number", "IS", "1", -1, 0},
1575     { 0x00200017, "Time Slot Number", "IS", "1", -1, 0},
1576     { 0x00200018, "Angle Number", "IS", "1", -1, 0},
1577     { 0x00200019, "Item Number", "IS", "1", 0, 0},
1578     { 0x00200020, "Patient Orientation", "CS", "2", 0, 0},
1579     { 0x00200022, "Overlay Number", "IS", "1", -1, 0},
1580     { 0x00200024, "Curve Number", "IS", "1", -1, 0},
1581     { 0x00200026, "Lookup Table Number", "IS", "1", -1, 0},
1582     { 0x00200030, "Image Position", "DS", "3", -1, 0},
1583     { 0x00200032, "Image Position (Patient)", "DS", "3", 0, 0},
1584     { 0x00200035, "Image Orientation", "DS", "6", -1, 0},
1585     { 0x00200037, "Image Orientation (Patient)", "DS", "6", 0, 0},
1586     { 0x00200050, "Location", "DS", "1", -1, 0},
1587     { 0x00200052, "Frame of Reference UID", "UI", "1", 0, 0},
1588     { 0x00200060, "Laterality", "CS", "1", 0, 0},
1589     { 0x00200062, "Image Laterality", "CS", "1", 0, 0},
1590     { 0x00200070, "Image Geometry Type", "LO", "1", -1, 0},
1591     { 0x00200080, "Masking Image", "CS", "1-n", -1, 0},
1592     { 0x00200100, "Temporal Position Identifier", "IS", "1", 0, 0},
1593     { 0x00200105, "Number of Temporal Positions", "IS", "1", 0, 0},
1594     { 0x00200110, "Temporal Resolution", "DS", "1", 0, 0},
1595     { 0x00200200, "Synchronization Frame of Reference UID", "UI", "1", 0, 0},
1596     { 0x00201000, "Series in Study", "IS", "1", -1, 0},
1597     { 0x00201001, "Acquisitions in Series", "IS", "1", -1, 0},
1598     { 0x00201002, "Images in Acquisition", "IS", "1", 0, 0},
1599     { 0x00201003, "Images in Series", "IS", "1", -1, 0},
1600     { 0x00201004, "Acquisitions in Study", "IS", "1", -1, 0},
1601     { 0x00201005, "Images in Study", "IS", "1", -1, 0},
1602     { 0x00201020, "Reference", "CS", "1-n", -1, 0},
1603     { 0x00201040, "Position Reference Indicator", "LO", "1", 0, 0},
1604     { 0x00201041, "Slice Location", "DS", "1", 0, 0},
1605     { 0x00201070, "Other Study Numbers", "IS", "1-n", -1, 0},
1606     { 0x00201200, "Number of Patient Related Studies", "IS", "1", 0, 0},
1607     { 0x00201202, "Number of Patient Related Series", "IS", "1", 0, 0},
1608     { 0x00201204, "Number of Patient Related Instances", "IS", "1", 0, 0},
1609     { 0x00201206, "Number of Study Related Series", "IS", "1", 0, 0},
1610     { 0x00201208, "Number of Study Related Instances", "IS", "1", 0, 0},
1611     { 0x00201209, "Number of Series Related Instances", "IS", "1", 0, 0},
1612     { 0x00203100, "Source Image IDs", "CS", "1-n", -1, 0},
1613     { 0x00203401, "Modifying Device ID", "CS", "1", -1, 0},
1614     { 0x00203402, "Modified Image ID", "CS", "1", -1, 0},
1615     { 0x00203403, "Modified Image Date", "DA", "1", -1, 0},
1616     { 0x00203404, "Modifying Device Manufacturer", "LO", "1", -1, 0},
1617     { 0x00203405, "Modified Image Time", "TM", "1", -1, 0},
1618     { 0x00203406, "Modified Image Description", "LO", "1", -1, 0},
1619     { 0x00204000, "Image Comments", "LT", "1", 0, 0},
1620     { 0x00205000, "Original Image Identification", "AT", "1-n", -1, 0},
1621     { 0x00205002, "Original Image Identification Nomenclature", "CS", "1-n", -1, 0},
1622     { 0x00209056, "Stack ID", "SH", "1", 0, 0},
1623     { 0x00209057, "In-Stack Position Number", "UL", "1", 0, 0},
1624     { 0x00209071, "Frame Anatomy Sequence", "SQ", "1", 0, 0},
1625     { 0x00209072, "Frame Laterality", "CS", "1", 0, 0},
1626     { 0x00209111, "Frame Content Sequence", "SQ", "1", 0, 0},
1627     { 0x00209113, "Plane Position Sequence", "SQ", "1", 0, 0},
1628     { 0x00209116, "Plane Orientation Sequence", "SQ", "1", 0, 0},
1629     { 0x00209128, "Temporal Position Index", "UL", "1", 0, 0},
1630     { 0x00209153, "Nominal Cardiac Trigger Delay Time", "FD", "1", 0, 0},
1631     { 0x00209156, "Frame Acquisition Number", "US", "1", 0, 0},
1632     { 0x00209157, "Dimension Index Values", "UL", "1-n", 0, 0},
1633     { 0x00209158, "Frame Comments", "LT", "1", 0, 0},
1634     { 0x00209161, "Concatenation UID", "UI", "1", 0, 0},
1635     { 0x00209162, "In-concatenation Number", "US", "1", 0, 0},
1636     { 0x00209163, "In-concatenation Total Number", "US", "1", 0, 0},
1637     { 0x00209164, "Dimension Organization UID", "UI", "1", 0, 0},
1638     { 0x00209165, "Dimension Index Pointer", "AT", "1", 0, 0},
1639     { 0x00209167, "Functional Group Pointer", "AT", "1", 0, 0},
1640     { 0x00209213, "Dimension Index Private Creator", "LO", "1", 0, 0},
1641     { 0x00209221, "Dimension Organization Sequence", "SQ", "1", 0, 0},
1642     { 0x00209222, "Dimension Index Sequence", "SQ", "1", 0, 0},
1643     { 0x00209228, "Concatenation Frame Offset Number", "UL", "1", 0, 0},
1644     { 0x00209238, "Functional Group Private Creator", "LO", "1", 0, 0},
1645     { 0x00209241, "Nominal Percentage of Cardiac Phase", "FL", "1", 0, 0},
1646     { 0x00209245, "Nominal Percentage of Respiratory Phase", "FL", "1", 0, 0},
1647     { 0x00209246, "Starting Respiratory Amplitude", "FL", "1", 0, 0},
1648     { 0x00209247, "Starting Respiratory Phase", "CS", "1", 0, 0},
1649     { 0x00209248, "Ending Respiratory Amplitude", "FL", "1", 0, 0},
1650     { 0x00209249, "Ending Respiratory Phase", "CS", "1", 0, 0},
1651     { 0x00209250, "Respiratory Trigger Type", "CS", "1", 0, 0},
1652     { 0x00209251, "R - R Interval Time Nominal", "FD", "1", 0, 0},
1653     { 0x00209252, "Actual Cardiac Trigger Delay Time", "FD", "1", 0, 0},
1654     { 0x00209253, "Respiratory Synchronization Sequence", "SQ", "1", 0, 0},
1655     { 0x00209254, "Respiratory Interval Time", "FD", "1", 0, 0},
1656     { 0x00209255, "Nominal Respiratory Trigger Delay Time", "FD", "1", 0, 0},
1657     { 0x00209256, "Respiratory Trigger Delay Threshold", "FD", "1", 0, 0},
1658     { 0x00209257, "Actual Respiratory Trigger Delay Time", "FD", "1", 0, 0},
1659     { 0x00209421, "Dimension Description Label", "LO", "1", 0, 0},
1660     { 0x00209450, "Patient Orientation in Frame Sequence", "SQ", "1", 0, 0},
1661     { 0x00209453, "Frame Label", "LO", "1", 0, 0},
1662     { 0x00209518, "Acquisition Index", "US", "1-n", 0, 0},
1663     { 0x00209529, "Contributing SOP Instances Reference Sequence", "SQ", "1", 0, 0},
1664     { 0x00209536, "Reconstruction Index", "US", "1", 0, 0},
1665     { 0x00220001, "Light Path Filter Pass-Through Wavelength", "US", "1", 0, 0},
1666     { 0x00220002, "Light Path Filter Pass Band", "US", "2", 0, 0},
1667     { 0x00220003, "Image Path Filter Pass-Through Wavelength", "US", "1", 0, 0},
1668     { 0x00220004, "Image Path Filter Pass Band", "US", "2", 0, 0},
1669     { 0x00220005, "Patient Eye Movement Commanded", "CS", "1", 0, 0},
1670     { 0x00220006, "Patient Eye Movement Command Code Sequence", "SQ", "1", 0, 0},
1671     { 0x00220007, "Spherical Lens Power", "FL", "1", 0, 0},
1672     { 0x00220008, "Cylinder Lens Power", "FL", "1", 0, 0},
1673     { 0x00220009, "Cylinder Axis", "FL", "1", 0, 0},
1674     { 0x0022000A, "Emmetropic Magnification", "FL", "1", 0, 0},
1675     { 0x0022000B, "Intra Ocular Pressure", "FL", "1", 0, 0},
1676     { 0x0022000C, "Horizontal Field of View", "FL", "1", 0, 0},
1677     { 0x0022000D, "Pupil Dilated", "CS", "1", 0, 0},
1678     { 0x0022000E, "Degree of Dilation", "FL", "1", 0, 0},
1679     { 0x00220010, "Stereo Baseline Angle", "FL", "1", 0, 0},
1680     { 0x00220011, "Stereo Baseline Displacement", "FL", "1", 0, 0},
1681     { 0x00220012, "Stereo Horizontal Pixel Offset", "FL", "1", 0, 0},
1682     { 0x00220013, "Stereo Vertical Pixel Offset", "FL", "1", 0, 0},
1683     { 0x00220014, "Stereo Rotation", "FL", "1", 0, 0},
1684     { 0x00220015, "Acquisition Device Type Code Sequence", "SQ", "1", 0, 0},
1685     { 0x00220016, "Illumination Type Code Sequence", "SQ", "1", 0, 0},
1686     { 0x00220017, "Light Path Filter Type Stack Code Sequence", "SQ", "1", 0, 0},
1687     { 0x00220018, "Image Path Filter Type Stack Code Sequence", "SQ", "1", 0, 0},
1688     { 0x00220019, "Lenses Code Sequence", "SQ", "1", 0, 0},
1689     { 0x0022001A, "Channel Description Code Sequence", "SQ", "1", 0, 0},
1690     { 0x0022001B, "Refractive State Sequence", "SQ", "1", 0, 0},
1691     { 0x0022001C, "Mydriatic Agent Code Sequence", "SQ", "1", 0, 0},
1692     { 0x0022001D, "Relative Image Position Code Sequence", "SQ", "1", 0, 0},
1693     { 0x00220020, "Stereo Pairs Sequence", "SQ", "1", 0, 0},
1694     { 0x00220021, "Left Image Sequence", "SQ", "1", 0, 0},
1695     { 0x00220022, "Right Image Sequence", "SQ", "1", 0, 0},
1696     { 0x00220030, "Axial Length of the Eye", "FL", "1", 0, 0},
1697     { 0x00220031, "Ophthalmic Frame Location Sequence", "SQ", "1", 0, 0},
1698     { 0x00220032, "Reference Coordinates", "FL", "2-2n", 0, 0},
1699     { 0x00220035, "Depth Spatial Resolution", "FL", "1", 0, 0},
1700     { 0x00220036, "Maximum Depth Distortion", "FL", "1", 0, 0},
1701     { 0x00220037, "Along-scan Spatial Resolution", "FL", "1", 0, 0},
1702     { 0x00220038, "Maximum Along-scan Distortion", "FL", "1", 0, 0},
1703     { 0x00220039, "Ophthalmic Image Orientation", "CS", "1", 0, 0},
1704     { 0x00220041, "Depth of Transverse Image", "FL", "1", 0, 0},
1705     { 0x00220042, "Mydriatic Agent Concentration Units Sequence", "SQ", "1", 0, 0},
1706     { 0x00220048, "Across-scan Spatial Resolution", "FL", "1", 0, 0},
1707     { 0x00220049, "Maximum Across-scan Distortion", "FL", "1", 0, 0},
1708     { 0x0022004E, "Mydriatic Agent Concentration", "DS", "1", 0, 0},
1709     { 0x00220055, "Illumination Wave Length", "FL", "1", 0, 0},
1710     { 0x00220056, "Illumination Power", "FL", "1", 0, 0},
1711     { 0x00220057, "Illumination Bandwidth", "FL", "1", 0, 0},
1712     { 0x00220058, "Mydriatic Agent Sequence", "SQ", "1", 0, 0},
1713     { 0x00280002, "Samples per Pixel", "US", "1", 0, 0},
1714     { 0x00280003, "Samples per Pixel Used", "US", "1", 0, 0},
1715     { 0x00280004, "Photometric Interpretation", "CS", "1", 0, 0},
1716     { 0x00280005, "Image Dimensions", "US", "1", -1, 0},
1717     { 0x00280006, "Planar Configuration", "US", "1", 0, 0},
1718     { 0x00280008, "Number of Frames", "IS", "1", 0, 0},
1719     { 0x00280009, "Frame Increment Pointer", "AT", "1-n", 0, 0},
1720     { 0x0028000A, "Frame Dimension Pointer", "AT", "1-n", 0, 0},
1721     { 0x00280010, "Rows", "US", "1", 0, 0},
1722     { 0x00280011, "Columns", "US", "1", 0, 0},
1723     { 0x00280012, "Planes", "US", "1", -1, 0},
1724     { 0x00280014, "Ultrasound Color Data Present", "US", "1", 0, 0},
1725     { 0x00280020, "", "", "", -1, 0},
1726     { 0x00280030, "Pixel Spacing", "DS", "2", 0, 0},
1727     { 0x00280031, "Zoom Factor", "DS", "2", 0, 0},
1728     { 0x00280032, "Zoom Center", "DS", "2", 0, 0},
1729     { 0x00280034, "Pixel Aspect Ratio", "IS", "2", 0, 0},
1730     { 0x00280040, "Image Format", "CS", "1", -1, 0},
1731     { 0x00280050, "Manipulated Image", "LO", "1-n", -1, 0},
1732     { 0x00280051, "Corrected Image", "CS", "1-n", 0, 0},
1733     { 0x0028005F, "Compression Recognition Code", "LO", "1", -1, 0},
1734     { 0x00280060, "Compression Code", "CS", "1", -1, 0},
1735     { 0x00280061, "Compression Originator", "SH", "1", -1, 0},
1736     { 0x00280062, "Compression Label", "LO", "1", -1, 0},
1737     { 0x00280063, "Compression Description", "SH", "1", -1, 0},
1738     { 0x00280065, "Compression Sequence", "CS", "1-n", -1, 0},
1739     { 0x00280066, "Compression Step Pointers", "AT", "1-n", -1, 0},
1740     { 0x00280068, "Repeat Interval", "US", "1", -1, 0},
1741     { 0x00280069, "Bits Grouped", "US", "1", -1, 0},
1742     { 0x00280070, "Perimeter Table", "US", "1-n", -1, 0},
1743     { 0x00280071, "Perimeter Value", "US or SS", "1", -1, 0},
1744     { 0x00280080, "Predictor Rows", "US", "1", -1, 0},
1745     { 0x00280081, "Predictor Columns", "US", "1", -1, 0},
1746     { 0x00280082, "Predictor Constants", "US", "1-n", -1, 0},
1747     { 0x00280090, "Blocked Pixels", "CS", "1", -1, 0},
1748     { 0x00280091, "Block Rows", "US", "1", -1, 0},
1749     { 0x00280092, "Block Columns", "US", "1", -1, 0},
1750     { 0x00280093, "Row Overlap", "US", "1", -1, 0},
1751     { 0x00280094, "Column Overlap", "US", "1", -1, 0},
1752     { 0x00280100, "Bits Allocated", "US", "1", 0, 0},
1753     { 0x00280101, "Bits Stored", "US", "1", 0, 0},
1754     { 0x00280102, "High Bit", "US", "1", 0, 0},
1755     { 0x00280103, "Pixel Representation", "US", "1", 0, 0},
1756     { 0x00280104, "Smallest Valid Pixel Value", "US or SS", "1", -1, 0},
1757     { 0x00280105, "Largest Valid Pixel Value", "US or SS", "1", -1, 0},
1758     { 0x00280106, "Smallest Image Pixel Value", "US or SS", "1", 0, 0},
1759     { 0x00280107, "Largest Image Pixel Value", "US or SS", "1", 0, 0},
1760     { 0x00280108, "Smallest Pixel Value in Series", "US or SS", "1", 0, 0},
1761     { 0x00280109, "Largest Pixel Value in Series", "US or SS", "1", 0, 0},
1762     { 0x00280110, "Smallest Image Pixel Value in Plane", "US or SS", "1", -1, 0},
1763     { 0x00280111, "Largest Image Pixel Value in Plane", "US or SS", "1", -1, 0},
1764     { 0x00280120, "Pixel Padding Value", "US or SS", "1", 0, 0},
1765     { 0x00280121, "Pixel Padding Range Limit", "US or SS", "1", 0, 0},
1766     { 0x00280200, "Image Location", "US", "1", -1, 0},
1767     { 0x00280300, "Quality Control Image", "CS", "1", 0, 0},
1768     { 0x00280301, "Burned In Annotation", "CS", "1", 0, 0},
1769     { 0x00280400, "Transform Label", "LO", "1", -1, 0},
1770     { 0x00280401, "Transform Version Number", "LO", "1", -1, 0},
1771     { 0x00280402, "Number of Transform Steps", "US", "1", -1, 0},
1772     { 0x00280403, "Sequence of Compressed Data", "LO", "1-n", -1, 0},
1773     { 0x00280404, "Details of Coefficients", "AT", "1-n", -1, 0},
1774     { 0x00280410, "Rows For Nth Order Coefficients", "US", "1", -1, 0},
1775     { 0x00280411, "Columns For Nth Order Coefficients", "US", "1", -1, 0},
1776     { 0x00280412, "Coefficient Coding", "LO", "1-n", -1, 0},
1777     { 0x00280413, "Coefficient Coding Pointers", "AT", "1-n", -1, 0},
1778     { 0x00280700, "DCT Label", "LO", "1", -1, 0},
1779     { 0x00280701, "Data Block Description", "CS", "1-n", -1, 0},
1780     { 0x00280702, "Data Block", "AT", "1-n", -1, 0},
1781     { 0x00280710, "Normalization Factor Format", "US", "1", -1, 0},
1782     { 0x00280720, "Zonal Map Number Format", "US", "1", -1, 0},
1783     { 0x00280721, "Zonal Map Location", "AT", "1-n", -1, 0},
1784     { 0x00280722, "Zonal Map Format", "US", "1", -1, 0},
1785     { 0x00280730, "Adaptive Map Format", "US", "1", -1, 0},
1786     { 0x00280740, "Code Number Format", "US", "1", -1, 0},
1787     { 0x00280800, "Code Label", "CS", "1-n", -1, 0},
1788     { 0x00280802, "Number of Table", "US", "1", -1, 0},
1789     { 0x00280803, "Code Table Location", "AT", "1-n", -1, 0},
1790     { 0x00280804, "Bits For Code Word", "US", "1", -1, 0},
1791     { 0x00280808, "Image Data Location", "AT", "1-n", -1, 0},
1792     { 0x00280A02, "Pixel Spacing Calibration Type", "CS", "1", 0, 0},
1793     { 0x00280A04, "Pixel Spacing Calibration Description", "LO", "1", 0, 0},
1794     { 0x00281040, "Pixel Intensity Relationship", "CS", "1", 0, 0},
1795     { 0x00281041, "Pixel Intensity Relationship Sign", "SS", "1", 0, 0},
1796     { 0x00281050, "Window Center", "DS", "1-n", 0, 0},
1797     { 0x00281051, "Window Width", "DS", "1-n", 0, 0},
1798     { 0x00281052, "Rescale Intercept", "DS", "1", 0, 0},
1799     { 0x00281053, "Rescale Slope", "DS", "1", 0, 0},
1800     { 0x00281054, "Rescale Type", "LO", "1", 0, 0},
1801     { 0x00281055, "Window Center & Width Explanation", "LO", "1-n", 0, 0},
1802     { 0x00281056, "VOI LUT Function", "CS", "1", 0, 0},
1803     { 0x00281080, "Gray Scale", "CS", "1", -1, 0},
1804     { 0x00281090, "Recommended Viewing Mode", "CS", "1", 0, 0},
1805     { 0x00281100, "Gray Lookup Table Descriptor", "US or SS", "3", -1, 0},
1806     { 0x00281101, "Red Palette Color Lookup Table Descriptor", "US or SS", "3", 0, 0},
1807     { 0x00281102, "Green Palette Color Lookup Table Descriptor", "US or SS", "3", 0, 0},
1808     { 0x00281103, "Blue Palette Color Lookup Table Descriptor", "US or SS", "3", 0, 0},
1809     { 0x00281111, "Large Red Palette Color Lookup Table Descriptor", "US or SS", "4", -1, 0},
1810     { 0x00281112, "Large Green Palette Color Lookup Table Descriptor", "US or SS", "4", -1, 0},
1811     { 0x00281113, "Large Blue Palette Color Lookup Table Descriptor", "US or SS", "4", -1, 0},
1812     { 0x00281199, "Palette Color Lookup Table UID", "UI", "1", 0, 0},
1813     { 0x00281200, "Gray Lookup Table Data", "US or SS or OW", "1-n 1", -1, 0},
1814     { 0x00281201, "Red Palette Color Lookup Table Data", "OW", "1", 0, 0},
1815     { 0x00281202, "Green Palette Color Lookup Table Data", "OW", "1", 0, 0},
1816     { 0x00281203, "Blue Palette Color Lookup Table Data", "OW", "1", 0, 0},
1817     { 0x00281211, "Large Red Palette Color Lookup Table Data", "OW", "1", -1, 0},
1818     { 0x00281212, "Large Green Palette Color Lookup Table Data", "OW", "1", -1, 0},
1819     { 0x00281213, "Large Blue Palette Color Lookup Table Data", "OW", "1", -1, 0},
1820     { 0x00281214, "Large Palette Color Lookup Table UID", "UI", "1", -1, 0},
1821     { 0x00281221, "Segmented Red Palette Color Lookup Table Data", "OW", "1", 0, 0},
1822     { 0x00281222, "Segmented Green Palette Color Lookup Table Data", "OW", "1", 0, 0},
1823     { 0x00281223, "Segmented Blue Palette Color Lookup Table Data", "OW", "1", 0, 0},
1824     { 0x00281300, "Implant Present", "CS", "1", 0, 0},
1825     { 0x00281350, "Partial View", "CS", "1", 0, 0},
1826     { 0x00281351, "Partial View Description", "ST", "1", 0, 0},
1827     { 0x00281352, "Partial View Code Sequence", "SQ", "1", 0, 0},
1828     { 0x0028135A, "Spatial Locations Preserved", "CS", "1", 0, 0},
1829     { 0x00282000, "ICC Profile", "OB", "1", 0, 0},
1830     { 0x00282110, "Lossy Image Compression", "CS", "1", 0, 0},
1831     { 0x00282112, "Lossy Image Compression Ratio", "DS", "1-n", 0, 0},
1832     { 0x00282114, "Lossy Image Compression Method", "CS", "1-n", 0, 0},
1833     { 0x00283000, "Modality LUT Sequence", "SQ", "1", 0, 0},
1834     { 0x00283002, "LUT Descriptor", "US or SS", "3", 0, 0},
1835     { 0x00283003, "LUT Explanation", "LO", "1", 0, 0},
1836     { 0x00283004, "Modality LUT Type", "LO", "1", 0, 0},
1837     { 0x00283006, "LUT Data", "US or SS or OW", "1-n 1", 0, 0},
1838     { 0x00283010, "VOI LUT Sequence", "SQ", "1", 0, 0},
1839     { 0x00283110, "Softcopy VOI LUT Sequence", "SQ", "1", 0, 0},
1840     { 0x00284000, "Image Presentation Comments", "LT", "1", -1, 0},
1841     { 0x00285000, "Bi-Plane Acquisition Sequence", "SQ", "1", -1, 0},
1842     { 0x00286010, "Representative Frame Number", "US", "1", 0, 0},
1843     { 0x00286020, "Frame Numbers of Interest (FOI)", "US", "1-n", 0, 0},
1844     { 0x00286022, "Frame(s) of Interest Description", "LO", "1-n", 0, 0},
1845     { 0x00286023, "Frame of Interest Type", "CS", "1-n", 0, 0},
1846     { 0x00286030, "Mask Pointer(s)", "US", "1-n", -1, 0},
1847     { 0x00286040, "R Wave Pointer", "US", "1-n", 0, 0},
1848     { 0x00286100, "Mask Subtraction Sequence", "SQ", "1", 0, 0},
1849     { 0x00286101, "Mask Operation", "CS", "1", 0, 0},
1850     { 0x00286102, "Applicable Frame Range", "US", "2-2n", 0, 0},
1851     { 0x00286110, "Mask Frame Numbers", "US", "1-n", 0, 0},
1852     { 0x00286112, "Contrast Frame Averaging", "US", "1", 0, 0},
1853     { 0x00286114, "Mask Sub-pixel Shift", "FL", "2", 0, 0},
1854     { 0x00286120, "TID Offset", "SS", "1", 0, 0},
1855     { 0x00286190, "Mask Operation Explanation", "ST", "1", 0, 0},
1856     { 0x00287FE0, "Pixel Data Provider URL", "UT", "1", 0, 0},
1857     { 0x00289001, "Data Point Rows", "UL", "1", 0, 0},
1858     { 0x00289002, "Data Point Columns", "UL", "1", 0, 0},
1859     { 0x00289003, "Signal Domain Columns", "CS", "1", 0, 0},
1860     { 0x00289099, "Largest Monochrome Pixel Value", "US", "1", -1, 0},
1861     { 0x00289108, "Data Representation", "CS", "1", 0, 0},
1862     { 0x00289110, "Pixel Measures Sequence", "SQ", "1", 0, 0},
1863     { 0x00289132, "Frame VOI LUT Sequence", "SQ", "1", 0, 0},
1864     { 0x00289145, "Pixel Value Transformation Sequence", "SQ", "1", 0, 0},
1865     { 0x00289235, "Signal Domain Rows", "CS", "1", 0, 0},
1866     { 0x00289411, "Display Filter Percentage", "FL", "1", 0, 0},
1867     { 0x00289415, "Frame Pixel Shift Sequence", "SQ", "1", 0, 0},
1868     { 0x00289416, "Subtraction Item ID", "US", "1", 0, 0},
1869     { 0x00289422, "Pixel Intensity Relationship LUT Sequence", "SQ", "1", 0, 0},
1870     { 0x00289443, "Frame Pixel Data Properties Sequence", "SQ", "1", 0, 0},
1871     { 0x00289444, "Geometrical Properties", "CS", "1", 0, 0},
1872     { 0x00289445, "Geometric Maximum Distortion", "FL", "1", 0, 0},
1873     { 0x00289446, "Image Processing Applied", "CS", "1-n", 0, 0},
1874     { 0x00289454, "Mask Selection Mode", "CS", "1", 0, 0},
1875     { 0x00289474, "LUT Function", "CS", "1", 0, 0},
1876     { 0x00289520, "Image to Equipment Mapping Matrix", "DS", "16", 0, 0},
1877     { 0x00289537, "Equipment Coordinate System Identification", "CS", "1", 0, 0},
1878     { 0x0032000A, "Study Status ID", "CS", "1", -1, 0},
1879     { 0x0032000C, "Study Priority ID", "CS", "1", -1, 0},
1880     { 0x00320012, "Study ID Issuer", "LO", "1", -1, 0},
1881     { 0x00320032, "Study Verified Date", "DA", "1", -1, 0},
1882     { 0x00320033, "Study Verified Time", "TM", "1", -1, 0},
1883     { 0x00320034, "Study Read Date", "DA", "1", -1, 0},
1884     { 0x00320035, "Study Read Time", "TM", "1", -1, 0},
1885     { 0x00321000, "Scheduled Study Start Date", "DA", "1", -1, 0},
1886     { 0x00321001, "Scheduled Study Start Time", "TM", "1", -1, 0},
1887     { 0x00321010, "Scheduled Study Stop Date", "DA", "1", -1, 0},
1888     { 0x00321011, "Scheduled Study Stop Time", "TM", "1", -1, 0},
1889     { 0x00321020, "Scheduled Study Location", "LO", "1", -1, 0},
1890     { 0x00321021, "Scheduled Study Location AE Title", "AE", "1-n", -1, 0},
1891     { 0x00321030, "Reason for Study", "LO", "1", -1, 0},
1892     { 0x00321031, "Requesting Physician Identification Sequence", "SQ", "1", 0, 0},
1893     { 0x00321032, "Requesting Physician", "PN", "1", 0, 0},
1894     { 0x00321033, "Requesting Service", "LO", "1", 0, 0},
1895     { 0x00321040, "Study Arrival Date", "DA", "1", -1, 0},
1896     { 0x00321041, "Study Arrival Time", "TM", "1", -1, 0},
1897     { 0x00321050, "Study Completion Date", "DA", "1", -1, 0},
1898     { 0x00321051, "Study Completion Time", "TM", "1", -1, 0},
1899     { 0x00321055, "Study Component Status ID", "CS", "1", -1, 0},
1900     { 0x00321060, "Requested Procedure Description", "LO", "1", 0, 0},
1901     { 0x00321064, "Requested Procedure Code Sequence", "SQ", "1", 0, 0},
1902     { 0x00321070, "Requested Contrast Agent", "LO", "1", 0, 0},
1903     { 0x00324000, "Study Comments", "LT", "1", -1, 0},
1904     { 0x00380004, "Referenced Patient Alias Sequence", "SQ", "1", 0, 0},
1905     { 0x00380008, "Visit Status ID", "CS", "1", 0, 0},
1906     { 0x00380010, "Admission ID", "LO", "1", 0, 0},
1907     { 0x00380011, "Issuer of Admission ID", "LO", "1", 0, 0},
1908     { 0x00380016, "Route of Admissions", "LO", "1", 0, 0},
1909     { 0x0038001A, "Scheduled Admission Date", "DA", "1", -1, 0},
1910     { 0x0038001B, "Scheduled Admission Time", "TM", "1", -1, 0},
1911     { 0x0038001C, "Scheduled Discharge Date", "DA", "1", -1, 0},
1912     { 0x0038001D, "Scheduled Discharge Time", "TM", "1", -1, 0},
1913     { 0x0038001E, "Scheduled Patient Institution Residence", "LO", "1", -1, 0},
1914     { 0x00380020, "Admitting Date", "DA", "1", 0, 0},
1915     { 0x00380021, "Admitting Time", "TM", "1", 0, 0},
1916     { 0x00380030, "Discharge Date", "DA", "1", -1, 0},
1917     { 0x00380032, "Discharge Time", "TM", "1", -1, 0},
1918     { 0x00380040, "Discharge Diagnosis Description", "LO", "1", -1, 0},
1919     { 0x00380044, "Discharge Diagnosis Code Sequence", "SQ", "1", -1, 0},
1920     { 0x00380050, "Special Needs", "LO", "1", 0, 0},
1921     { 0x00380060, "Service Episode ID", "LO", "1", 0, 0},
1922     { 0x00380061, "Issuer of Service Episode ID", "LO", "1", 0, 0},
1923     { 0x00380062, "Service Episode Description", "LO", "1", 0, 0},
1924     { 0x00380100, "Pertinent Documents Sequence", "SQ", "1", 0, 0},
1925     { 0x00380300, "Current Patient Location", "LO", "1", 0, 0},
1926     { 0x00380400, "Patient's Institution Residence", "LO", "1", 0, 0},
1927     { 0x00380500, "Patient State", "LO", "1", 0, 0},
1928     { 0x00380502, "Patient Clinical Trial Participation Sequence", "SQ", "1", 0, 0},
1929     { 0x00384000, "Visit Comments", "LT", "1", 0, 0},
1930     { 0x003A0004, "Waveform Originality", "CS", "1", 0, 0},
1931     { 0x003A0005, "Number of Waveform Channels", "US", "1", 0, 0},
1932     { 0x003A0010, "Number of Waveform Samples", "UL", "1", 0, 0},
1933     { 0x003A001A, "Sampling Frequency", "DS", "1", 0, 0},
1934     { 0x003A0020, "Multiplex Group Label", "SH", "1", 0, 0},
1935     { 0x003A0200, "Channel Definition Sequence", "SQ", "1", 0, 0},
1936     { 0x003A0202, "Waveform Channel Number", "IS", "1", 0, 0},
1937     { 0x003A0203, "Channel Label", "SH", "1", 0, 0},
1938     { 0x003A0205, "Channel Status", "CS", "1-n", 0, 0},
1939     { 0x003A0208, "Channel Source Sequence", "SQ", "1", 0, 0},
1940     { 0x003A0209, "Channel Source Modifiers Sequence", "SQ", "1", 0, 0},
1941     { 0x003A020A, "Source Waveform Sequence", "SQ", "1", 0, 0},
1942     { 0x003A020C, "Channel Derivation Description", "LO", "1", 0, 0},
1943     { 0x003A0210, "Channel Sensitivity", "DS", "1", 0, 0},
1944     { 0x003A0211, "Channel Sensitivity Units Sequence", "SQ", "1", 0, 0},
1945     { 0x003A0212, "Channel Sensitivity Correction Factor", "DS", "1", 0, 0},
1946     { 0x003A0213, "Channel Baseline", "DS", "1", 0, 0},
1947     { 0x003A0214, "Channel Time Skew", "DS", "1", 0, 0},
1948     { 0x003A0215, "Channel Sample Skew", "DS", "1", 0, 0},
1949     { 0x003A0218, "Channel Offset", "DS", "1", 0, 0},
1950     { 0x003A021A, "Waveform Bits Stored", "US", "1", 0, 0},
1951     { 0x003A0220, "Filter Low Frequency", "DS", "1", 0, 0},
1952     { 0x003A0221, "Filter High Frequency", "DS", "1", 0, 0},
1953     { 0x003A0222, "Notch Filter Frequency", "DS", "1", 0, 0},
1954     { 0x003A0223, "Notch Filter Bandwidth", "DS", "1", 0, 0},
1955     { 0x003A0230, "Waveform Data Display Scale", "FL", "1", 0, 0},
1956     { 0x003A0231, "Waveform Display Background CIELab Value", "US", "3", 0, 0},
1957     { 0x003A0240, "Waveform Presentation Group Sequence", "SQ", "1", 0, 0},
1958     { 0x003A0241, "Presentation Group Number", "US", "1", 0, 0},
1959     { 0x003A0242, "Channel Display Sequence", "SQ", "1", 0, 0},
1960     { 0x003A0244, "Channel Recommended Display CIELab Value", "US", "3", 0, 0},
1961     { 0x003A0245, "Channel Position", "FL", "1", 0, 0},
1962     { 0x003A0246, "Display Shading Flag", "CS", "1", 0, 0},
1963     { 0x003A0247, "Fractional Channel Display Scale", "FL", "1", 0, 0},
1964     { 0x003A0248, "Absolute Channel Display Scale", "FL", "1", 0, 0},
1965     { 0x003A0300, "Multiplexed Audio Channels Description Code Sequence", "SQ", "1", 0, 0},
1966     { 0x003A0301, "Channel Identification Code", "IS", "1", 0, 0},
1967     { 0x003A0302, "Channel Mode", "CS", "1", 0, 0},
1968     { 0x00400001, "Scheduled Station AE Title", "AE", "1-n", 0, 0},
1969     { 0x00400002, "Scheduled Procedure Step Start Date", "DA", "1", 0, 0},
1970     { 0x00400003, "Scheduled Procedure Step Start Time", "TM", "1", 0, 0},
1971     { 0x00400004, "Scheduled Procedure Step End Date", "DA", "1", 0, 0},
1972     { 0x00400005, "Scheduled Procedure Step End Time", "TM", "1", 0, 0},
1973     { 0x00400006, "Scheduled Performing Physician's Name", "PN", "1", 0, 0},
1974     { 0x00400007, "Scheduled Procedure Step Description", "LO", "1", 0, 0},
1975     { 0x00400008, "Scheduled Protocol Code Sequence", "SQ", "1", 0, 0},
1976     { 0x00400009, "Scheduled Procedure Step ID", "SH", "1", 0, 0},
1977     { 0x0040000A, "Stage Code Sequence", "SQ", "1", 0, 0},
1978     { 0x0040000B, "Scheduled Performing Physician Identification Sequence", "SQ", "1", 0, 0},
1979     { 0x00400010, "Scheduled Station Name", "SH", "1-n", 0, 0},
1980     { 0x00400011, "Scheduled Procedure Step Location", "SH", "1", 0, 0},
1981     { 0x00400012, "Pre-Medication", "LO", "1", 0, 0},
1982     { 0x00400020, "Scheduled Procedure Step Status", "CS", "1", 0, 0},
1983     { 0x00400100, "Scheduled Procedure Step Sequence", "SQ", "1", 0, 0},
1984     { 0x00400220, "Referenced Non-Image Composite SOP Instance Sequence", "SQ", "1", 0, 0},
1985     { 0x00400241, "Performed Station AE Title", "AE", "1", 0, 0},
1986     { 0x00400242, "Performed Station Name", "SH", "1", 0, 0},
1987     { 0x00400243, "Performed Location", "SH", "1", 0, 0},
1988     { 0x00400244, "Performed Procedure Step Start Date", "DA", "1", 0, 0},
1989     { 0x00400245, "Performed Procedure Step Start Time", "TM", "1", 0, 0},
1990     { 0x00400250, "Performed Procedure Step End Date", "DA", "1", 0, 0},
1991     { 0x00400251, "Performed Procedure Step End Time", "TM", "1", 0, 0},
1992     { 0x00400252, "Performed Procedure Step Status", "CS", "1", 0, 0},
1993     { 0x00400253, "Performed Procedure Step ID", "SH", "1", 0, 0},
1994     { 0x00400254, "Performed Procedure Step Description", "LO", "1", 0, 0},
1995     { 0x00400255, "Performed Procedure Type Description", "LO", "1", 0, 0},
1996     { 0x00400260, "Performed Protocol Code Sequence", "SQ", "1", 0, 0},
1997     { 0x00400270, "Scheduled Step Attributes Sequence", "SQ", "1", 0, 0},
1998     { 0x00400275, "Request Attributes Sequence", "SQ", "1", 0, 0},
1999     { 0x00400280, "Comments on the Performed Procedure Step", "ST", "1", 0, 0},
2000     { 0x00400281, "Performed Procedure Step Discontinuation Reason Code Sequence", "SQ", "1", 0, 0},
2001     { 0x00400293, "Quantity Sequence", "SQ", "1", 0, 0},
2002     { 0x00400294, "Quantity", "DS", "1", 0, 0},
2003     { 0x00400295, "Measuring Units Sequence", "SQ", "1", 0, 0},
2004     { 0x00400296, "Billing Item Sequence", "SQ", "1", 0, 0},
2005     { 0x00400300, "Total Time of Fluoroscopy", "US", "1", 0, 0},
2006     { 0x00400301, "Total Number of Exposures", "US", "1", 0, 0},
2007     { 0x00400302, "Entrance Dose", "US", "1", 0, 0},
2008     { 0x00400303, "Exposed Area", "US", "1-2", 0, 0},
2009     { 0x00400306, "Distance Source to Entrance", "DS", "1", 0, 0},
2010     { 0x00400307, "Distance Source to Support", "DS", "1", -1, 0},
2011     { 0x0040030E, "Exposure Dose Sequence", "SQ", "1", 0, 0},
2012     { 0x00400310, "Comments on Radiation Dose", "ST", "1", 0, 0},
2013     { 0x00400312, "X-Ray Output", "DS", "1", 0, 0},
2014     { 0x00400314, "Half Value Layer", "DS", "1", 0, 0},
2015     { 0x00400316, "Organ Dose", "DS", "1", 0, 0},
2016     { 0x00400318, "Organ Exposed", "CS", "1", 0, 0},
2017     { 0x00400320, "Billing Procedure Step Sequence", "SQ", "1", 0, 0},
2018     { 0x00400321, "Film Consumption Sequence", "SQ", "1", 0, 0},
2019     { 0x00400324, "Billing Supplies and Devices Sequence", "SQ", "1", 0, 0},
2020     { 0x00400330, "Referenced Procedure Step Sequence", "SQ", "1", -1, 0},
2021     { 0x00400340, "Performed Series Sequence", "SQ", "1", 0, 0},
2022     { 0x00400400, "Comments on the Scheduled Procedure Step", "LT", "1", 0, 0},
2023     { 0x00400440, "Protocol Context Sequence", "SQ", "1", 0, 0},
2024     { 0x00400441, "Content Item Modifier Sequence", "SQ", "1", 0, 0},
2025     { 0x0040050A, "Specimen Accession Number", "LO", "1", 0, 0},
2026     { 0x00400550, "Specimen Sequence", "SQ", "1", 0, 0},
2027     { 0x00400551, "Specimen Identifier", "LO", "1", 0, 0},
2028     { 0x00400552, "Specimen Description Sequence - Trial", "SQ", "1", -1, 0},
2029     { 0x00400553, "Specimen Description - Trial", "ST", "1", -1, 0},
2030     { 0x00400555, "Acquisition Context Sequence", "SQ", "1", 0, 0},
2031     { 0x00400556, "Acquisition Context Description", "ST", "1", 0, 0},
2032     { 0x0040059A, "Specimen Type Code Sequence", "SQ", "1", 0, 0},
2033     { 0x004006FA, "Slide Identifier", "LO", "1", 0, 0},
2034     { 0x0040071A, "Image Center Point Coordinates Sequence", "SQ", "1", 0, 0},
2035     { 0x0040072A, "X offset in Slide Coordinate System", "DS", "1", 0, 0},
2036     { 0x0040073A, "Y offset in Slide Coordinate System", "DS", "1", 0, 0},
2037     { 0x0040074A, "Z offset in Slide Coordinate System", "DS", "1", 0, 0},
2038     { 0x004008D8, "Pixel Spacing Sequence", "SQ", "1", 0, 0},
2039     { 0x004008DA, "Coordinate System Axis Code Sequence", "SQ", "1", 0, 0},
2040     { 0x004008EA, "Measurement Units Code Sequence", "SQ", "1", 0, 0},
2041     { 0x004009F8, "Vital Stain Code Sequence - Trial", "SQ", "1", -1, 0},
2042     { 0x00401001, "Requested Procedure ID", "SH", "1", 0, 0},
2043     { 0x00401002, "Reason for the Requested Procedure", "LO", "1", 0, 0},
2044     { 0x00401003, "Requested Procedure Priority", "SH", "1", 0, 0},
2045     { 0x00401004, "Patient Transport Arrangements", "LO", "1", 0, 0},
2046     { 0x00401005, "Requested Procedure Location", "LO", "1", 0, 0},
2047     { 0x00401006, "Placer Order Number / Procedure", "SH", "1", -1, 0},
2048     { 0x00401007, "Filler Order Number / Procedure", "SH", "1", -1, 0},
2049     { 0x00401008, "Confidentiality Code", "LO", "1", 0, 0},
2050     { 0x00401009, "Reporting Priority", "SH", "1", 0, 0},
2051     { 0x0040100A, "Reason for Requested Procedure Code Sequence", "SQ", "1", 0, 0},
2052     { 0x00401010, "Names of Intended Recipients of Results", "PN", "1-n", 0, 0},
2053     { 0x00401011, "Intended Recipients of Results Identification Sequence", "SQ", "1", 0, 0},
2054     { 0x00401101, "Person Identification Code Sequence", "SQ", "1", 0, 0},
2055     { 0x00401102, "Person's Address", "ST", "1", 0, 0},
2056     { 0x00401103, "Person's Telephone Numbers", "LO", "1-n", 0, 0},
2057     { 0x00401400, "Requested Procedure Comments", "LT", "1", 0, 0},
2058     { 0x00402001, "Reason for the Imaging Service Request", "LO", "1", -1, 0},
2059     { 0x00402004, "Issue Date of Imaging Service Request", "DA", "1", 0, 0},
2060     { 0x00402005, "Issue Time of Imaging Service Request", "TM", "1", 0, 0},
2061     { 0x00402006, "Placer Order Number / Imaging Service Request (Retired)", "SH", "1", -1, 0},
2062     { 0x00402007, "Filler Order Number / Imaging Service Request (Retired)", "SH", "1", -1, 0},
2063     { 0x00402008, "Order Entered By", "PN", "1", 0, 0},
2064     { 0x00402009, "Order Enterer's Location", "SH", "1", 0, 0},
2065     { 0x00402010, "Order Callback Phone Number", "SH", "1", 0, 0},
2066     { 0x00402016, "Placer Order Number / Imaging Service Request", "LO", "1", 0, 0},
2067     { 0x00402017, "Filler Order Number / Imaging Service Request", "LO", "1", 0, 0},
2068     { 0x00402400, "Imaging Service Request Comments", "LT", "1", 0, 0},
2069     { 0x00403001, "Confidentiality Constraint on Patient Data Description", "LO", "1", 0, 0},
2070     { 0x00404001, "General Purpose Scheduled Procedure Step Status", "CS", "1", 0, 0},
2071     { 0x00404002, "General Purpose Performed Procedure Step Status", "CS", "1", 0, 0},
2072     { 0x00404003, "General Purpose Scheduled Procedure Step Priority", "CS", "1", 0, 0},
2073     { 0x00404004, "Scheduled Processing Applications Code Sequence", "SQ", "1", 0, 0},
2074     { 0x00404005, "Scheduled Procedure Step Start Date and Time", "DT", "1", 0, 0},
2075     { 0x00404006, "Multiple Copies Flag", "CS", "1", 0, 0},
2076     { 0x00404007, "Performed Processing Applications Code Sequence", "SQ", "1", 0, 0},
2077     { 0x00404009, "Human Performer Code Sequence", "SQ", "1", 0, 0},
2078     { 0x00404010, "Scheduled Procedure Step Modification Date and Time", "DT", "1", 0, 0},
2079     { 0x00404011, "Expected Completion Date and Time", "DT", "1", 0, 0},
2080     { 0x00404015, "Resulting General Purpose Performed Procedure Steps Sequence", "SQ", "1", 0, 0},
2081     { 0x00404016, "Referenced General Purpose Scheduled Procedure Step Sequence", "SQ", "1", 0, 0},
2082     { 0x00404018, "Scheduled Workitem Code Sequence", "SQ", "1", 0, 0},
2083     { 0x00404019, "Performed Workitem Code Sequence", "SQ", "1", 0, 0},
2084     { 0x00404020, "Input Availability Flag", "CS", "1", 0, 0},
2085     { 0x00404021, "Input Information Sequence", "SQ", "1", 0, 0},
2086     { 0x00404022, "Relevant Information Sequence", "SQ", "1", 0, 0},
2087     { 0x00404023, "Referenced General Purpose Scheduled Procedure Step Transaction UID", "UI", "1", 0, 0},
2088     { 0x00404025, "Scheduled Station Name Code Sequence", "SQ", "1", 0, 0},
2089     { 0x00404026, "Scheduled Station Class Code Sequence", "SQ", "1", 0, 0},
2090     { 0x00404027, "Scheduled Station Geographic Location Code Sequence", "SQ", "1", 0, 0},
2091     { 0x00404028, "Performed Station Name Code Sequence", "SQ", "1", 0, 0},
2092     { 0x00404029, "Performed Station Class Code Sequence", "SQ", "1", 0, 0},
2093     { 0x00404030, "Performed Station Geographic Location Code Sequence", "SQ", "1", 0, 0},
2094     { 0x00404031, "Requested Subsequent Workitem Code Sequence", "SQ", "1", 0, 0},
2095     { 0x00404032, "Non-DICOM Output Code Sequence", "SQ", "1", 0, 0},
2096     { 0x00404033, "Output Information Sequence", "SQ", "1", 0, 0},
2097     { 0x00404034, "Scheduled Human Performers Sequence", "SQ", "1", 0, 0},
2098     { 0x00404035, "Actual Human Performers Sequence", "SQ", "1", 0, 0},
2099     { 0x00404036, "Human Performer's Organization", "LO", "1", 0, 0},
2100     { 0x00404037, "Human Performer's Name", "PN", "1", 0, 0},
2101     { 0x00408302, "Entrance Dose in mGy", "DS", "1", 0, 0},
2102     { 0x00409094, "Referenced Image Real World Value Mapping Sequence", "SQ", "1", 0, 0},
2103     { 0x00409096, "Real World Value Mapping Sequence", "SQ", "1", 0, 0},
2104     { 0x00409098, "Pixel Value Mapping Code Sequence", "SQ", "1", 0, 0},
2105     { 0x00409210, "LUT Label", "SH", "1", 0, 0},
2106     { 0x00409211, "Real World Value Last Value Mapped", "US or SS", "1", 0, 0},
2107     { 0x00409212, "Real World Value LUT Data", "FD", "1-n", 0, 0},
2108     { 0x00409216, "Real World Value First Value Mapped", "US or SS", "1", 0, 0},
2109     { 0x00409224, "Real World Value Intercept", "FD", "1", 0, 0},
2110     { 0x00409225, "Real World Value Slope", "FD", "1", 0, 0},
2111     { 0x0040A010, "Relationship Type", "CS", "1", 0, 0},
2112     { 0x0040A027, "Verifying Organization", "LO", "1", 0, 0},
2113     { 0x0040A030, "Verification Date Time", "DT", "1", 0, 0},
2114     { 0x0040A032, "Observation Date Time", "DT", "1", 0, 0},
2115     { 0x0040A040, "Value Type", "CS", "1", 0, 0},
2116     { 0x0040A043, "Concept Name Code Sequence", "SQ", "1", 0, 0},
2117     { 0x0040A050, "Continuity Of Content", "CS", "1", 0, 0},
2118     { 0x0040A073, "Verifying Observer Sequence", "SQ", "1", 0, 0},
2119     { 0x0040A075, "Verifying Observer Name", "PN", "1", 0, 0},
2120     { 0x0040A078, "Author Observer Sequence", "SQ", "1", 0, 0},
2121     { 0x0040A07A, "Participant Sequence", "SQ", "1", 0, 0},
2122     { 0x0040A07C, "Custodial Organization Sequence", "SQ", "1", 0, 0},
2123     { 0x0040A080, "Participation Type", "CS", "1", 0, 0},
2124     { 0x0040A082, "Participation DateTime", "DT", "1", 0, 0},
2125     { 0x0040A084, "Observer Type", "CS", "1", 0, 0},
2126     { 0x0040A088, "Verifying Observer Identification Code Sequence", "SQ", "1", 0, 0},
2127     { 0x0040A090, "Equivalent CDA Document Sequence", "SQ", "1", -1, 0},
2128     { 0x0040A0B0, "Referenced Waveform Channels", "US", "2-2n", 0, 0},
2129     { 0x0040A120, "DateTime", "DT", "1", 0, 0},
2130     { 0x0040A121, "Date", "DA", "1", 0, 0},
2131     { 0x0040A122, "Time", "TM", "1", 0, 0},
2132     { 0x0040A123, "Person Name", "PN", "1", 0, 0},
2133     { 0x0040A124, "UID", "UI", "1", 0, 0},
2134     { 0x0040A130, "Temporal Range Type", "CS", "1", 0, 0},
2135     { 0x0040A132, "Referenced Sample Positions", "UL", "1-n", 0, 0},
2136     { 0x0040A136, "Referenced Frame Numbers", "US", "1-n", 0, 0},
2137     { 0x0040A138, "Referenced Time Offsets", "DS", "1-n", 0, 0},
2138     { 0x0040A13A, "Referenced DateTime", "DT", "1-n", 0, 0},
2139     { 0x0040A160, "Text Value", "UT", "1", 0, 0},
2140     { 0x0040A168, "Concept Code Sequence", "SQ", "1", 0, 0},
2141     { 0x0040A170, "Purpose of Reference Code Sequence", "SQ", "1", 0, 0},
2142     { 0x0040A180, "Annotation Group Number", "US", "1", 0, 0},
2143     { 0x0040A195, "Modifier Code Sequence", "SQ", "1", 0, 0},
2144     { 0x0040A300, "Measured Value Sequence", "SQ", "1", 0, 0},
2145     { 0x0040A301, "Numeric Value Qualifier Code Sequence", "SQ", "1", 0, 0},
2146     { 0x0040A30A, "Numeric Value", "DS", "1-n", 0, 0},
2147     { 0x0040A353, "Address - Trial", "ST", "1", -1, 0},
2148     { 0x0040A354, "Telephone Number - Trial", "LO", "1", -1, 0},
2149     { 0x0040A360, "Predecessor Documents Sequence", "SQ", "1", 0, 0},
2150     { 0x0040A370, "Referenced Request Sequence", "SQ", "1", 0, 0},
2151     { 0x0040A372, "Performed Procedure Code Sequence", "SQ", "1", 0, 0},
2152     { 0x0040A375, "Current Requested Procedure Evidence Sequence", "SQ", "1", 0, 0},
2153     { 0x0040A385, "Pertinent Other Evidence Sequence", "SQ", "1", 0, 0},
2154     { 0x0040A390, "HL7 Structured Document Reference Sequence", "SQ", "1", 0, 0},
2155     { 0x0040A491, "Completion Flag", "CS", "1", 0, 0},
2156     { 0x0040A492, "Completion Flag Description", "LO", "1", 0, 0},
2157     { 0x0040A493, "Verification Flag", "CS", "1", 0, 0},
2158     { 0x0040A494, "Archive Requested", "CS", "1", 0, 0},
2159     { 0x0040A504, "Content Template Sequence", "SQ", "1", 0, 0},
2160     { 0x0040A525, "Identical Documents Sequence", "SQ", "1", 0, 0},
2161     { 0x0040A730, "Content Sequence", "SQ", "1", 0, 0},
2162     { 0x0040B020, "Annotation Sequence", "SQ", "1", 0, 0},
2163     { 0x0040DB00, "Template Identifier", "CS", "1", 0, 0},
2164     { 0x0040DB06, "Template Version", "DT", "1", -1, 0},
2165     { 0x0040DB07, "Template Local Version", "DT", "1", -1, 0},
2166     { 0x0040DB0B, "Template Extension Flag", "CS", "1", -1, 0},
2167     { 0x0040DB0C, "Template Extension Organization UID", "UI", "1", -1, 0},
2168     { 0x0040DB0D, "Template Extension Creator UID", "UI", "1", -1, 0},
2169     { 0x0040DB73, "Referenced Content Item Identifier", "UL", "1-n", 0, 0},
2170     { 0x0040E001, "HL7 Instance Identifier", "ST", "1", 0, 0},
2171     { 0x0040E004, "HL7 Document Effective Time", "DT", "1", 0, 0},
2172     { 0x0040E006, "HL7 Document Type Code Sequence", "SQ", "1", 0, 0},
2173     { 0x0040E010, "Retrieve URI", "UT", "1", 0, 0},
2174     { 0x00420010, "Document Title", "ST", "1", 0, 0},
2175     { 0x00420011, "Encapsulated Document", "OB", "1", 0, 0},
2176     { 0x00420012, "MIME Type of Encapsulated Document", "LO", "1", 0, 0},
2177     { 0x00420013, "Source Instance Sequence", "SQ", "1", 0, 0},
2178     { 0x00420014, "List of MIME Types", "LO", "1-n", 0, 0},
2179     { 0x00440001, "Product Package Identifier", "ST", "1", 0, 0},
2180     { 0x00440002, "Substance Administration Approval", "CS", "1", 0, 0},
2181     { 0x00440003, "Approval Status Further Description", "LT", "1", 0, 0},
2182     { 0x00440004, "Approval Status DateTime", "DT", "1", 0, 0},
2183     { 0x00440007, "Product Type Code Sequence", "SQ", "1", 0, 0},
2184     { 0x00440008, "Product Name", "LO", "1-n", 0, 0},
2185     { 0x00440009, "Product Description", "LT", "1", 0, 0},
2186     { 0x0044000A, "Product Lot Identifier", "LO", "1", 0, 0},
2187     { 0x0044000B, "Product Expiration DateTime", "DT", "1", 0, 0},
2188     { 0x00440010, "Substance Administration DateTime", "DT", "1", 0, 0},
2189     { 0x00440011, "Substance Administration Notes", "LO", "1", 0, 0},
2190     { 0x00440012, "Substance Administration Device ID", "LO", "1", 0, 0},
2191     { 0x00440013, "Product Parameter Sequence", "SQ", "1", 0, 0},
2192     { 0x00440019, "Substance Administration Parameter Sequence", "SQ", "1", 0, 0},
2193     { 0x00500004, "Calibration Image", "CS", "1", 0, 0},
2194     { 0x00500010, "Device Sequence", "SQ", "1", 0, 0},
2195     { 0x00500014, "Device Length", "DS", "1", 0, 0},
2196     { 0x00500016, "Device Diameter", "DS", "1", 0, 0},
2197     { 0x00500017, "Device Diameter Units", "CS", "1", 0, 0},
2198     { 0x00500018, "Device Volume", "DS", "1", 0, 0},
2199     { 0x00500019, "Intermarker Distance", "DS", "1", 0, 0},
2200     { 0x00500020, "Device Description", "LO", "1", 0, 0},
2201     { 0x00540010, "Energy Window Vector", "US", "1-n", 0, 0},
2202     { 0x00540011, "Number of Energy Windows", "US", "1", 0, 0},
2203     { 0x00540012, "Energy Window Information Sequence", "SQ", "1", 0, 0},
2204     { 0x00540013, "Energy Window Range Sequence", "SQ", "1", 0, 0},
2205     { 0x00540014, "Energy Window Lower Limit", "DS", "1", 0, 0},
2206     { 0x00540015, "Energy Window Upper Limit", "DS", "1", 0, 0},
2207     { 0x00540016, "Radiopharmaceutical Information Sequence", "SQ", "1", 0, 0},
2208     { 0x00540017, "Residual Syringe Counts", "IS", "1", 0, 0},
2209     { 0x00540018, "Energy Window Name", "SH", "1", 0, 0},
2210     { 0x00540020, "Detector Vector", "US", "1-n", 0, 0},
2211     { 0x00540021, "Number of Detectors", "US", "1", 0, 0},
2212     { 0x00540022, "Detector Information Sequence", "SQ", "1", 0, 0},
2213     { 0x00540030, "Phase Vector", "US", "1-n", 0, 0},
2214     { 0x00540031, "Number of Phases", "US", "1", 0, 0},
2215     { 0x00540032, "Phase Information Sequence", "SQ", "1", 0, 0},
2216     { 0x00540033, "Number of Frames in Phase", "US", "1", 0, 0},
2217     { 0x00540036, "Phase Delay", "IS", "1", 0, 0},
2218     { 0x00540038, "Pause Between Frames", "IS", "1", 0, 0},
2219     { 0x00540039, "Phase Description", "CS", "1", 0, 0},
2220     { 0x00540050, "Rotation Vector", "US", "1-n", 0, 0},
2221     { 0x00540051, "Number of Rotations", "US", "1", 0, 0},
2222     { 0x00540052, "Rotation Information Sequence", "SQ", "1", 0, 0},
2223     { 0x00540053, "Number of Frames in Rotation", "US", "1", 0, 0},
2224     { 0x00540060, "R-R Interval Vector", "US", "1-n", 0, 0},
2225     { 0x00540061, "Number of R-R Intervals", "US", "1", 0, 0},
2226     { 0x00540062, "Gated Information Sequence", "SQ", "1", 0, 0},
2227     { 0x00540063, "Data Information Sequence", "SQ", "1", 0, 0},
2228     { 0x00540070, "Time Slot Vector", "US", "1-n", 0, 0},
2229     { 0x00540071, "Number of Time Slots", "US", "1", 0, 0},
2230     { 0x00540072, "Time Slot Information Sequence", "SQ", "1", 0, 0},
2231     { 0x00540073, "Time Slot Time", "DS", "1", 0, 0},
2232     { 0x00540080, "Slice Vector", "US", "1-n", 0, 0},
2233     { 0x00540081, "Number of Slices", "US", "1", 0, 0},
2234     { 0x00540090, "Angular View Vector", "US", "1-n", 0, 0},
2235     { 0x00540100, "Time Slice Vector", "US", "1-n", 0, 0},
2236     { 0x00540101, "Number of Time Slices", "US", "1", 0, 0},
2237     { 0x00540200, "Start Angle", "DS", "1", 0, 0},
2238     { 0x00540202, "Type of Detector Motion", "CS", "1", 0, 0},
2239     { 0x00540210, "Trigger Vector", "IS", "1-n", 0, 0},
2240     { 0x00540211, "Number of Triggers in Phase", "US", "1", 0, 0},
2241     { 0x00540220, "View Code Sequence", "SQ", "1", 0, 0},
2242     { 0x00540222, "View Modifier Code Sequence", "SQ", "1", 0, 0},
2243     { 0x00540300, "Radionuclide Code Sequence", "SQ", "1", 0, 0},
2244     { 0x00540302, "Administration Route Code Sequence", "SQ", "1", 0, 0},
2245     { 0x00540304, "Radiopharmaceutical Code Sequence", "SQ", "1", 0, 0},
2246     { 0x00540306, "Calibration Data Sequence", "SQ", "1", 0, 0},
2247     { 0x00540308, "Energy Window Number", "US", "1", 0, 0},
2248     { 0x00540400, "Image ID", "SH", "1", 0, 0},
2249     { 0x00540410, "Patient Orientation Code Sequence", "SQ", "1", 0, 0},
2250     { 0x00540412, "Patient Orientation Modifier Code Sequence", "SQ", "1", 0, 0},
2251     { 0x00540414, "Patient Gantry Relationship Code Sequence", "SQ", "1", 0, 0},
2252     { 0x00540500, "Slice Progression Direction", "CS", "1", 0, 0},
2253     { 0x00541000, "Series Type", "CS", "2", 0, 0},
2254     { 0x00541001, "Units", "CS", "1", 0, 0},
2255     { 0x00541002, "Counts Source", "CS", "1", 0, 0},
2256     { 0x00541004, "Reprojection Method", "CS", "1", 0, 0},
2257     { 0x00541100, "Randoms Correction Method", "CS", "1", 0, 0},
2258     { 0x00541101, "Attenuation Correction Method", "LO", "1", 0, 0},
2259     { 0x00541102, "Decay Correction", "CS", "1", 0, 0},
2260     { 0x00541103, "Reconstruction Method", "LO", "1", 0, 0},
2261     { 0x00541104, "Detector Lines of Response Used", "LO", "1", 0, 0},
2262     { 0x00541105, "Scatter Correction Method", "LO", "1", 0, 0},
2263     { 0x00541200, "Axial Acceptance", "DS", "1", 0, 0},
2264     { 0x00541201, "Axial Mash", "IS", "2", 0, 0},
2265     { 0x00541202, "Transverse Mash", "IS", "1", 0, 0},
2266     { 0x00541203, "Detector Element Size", "DS", "2", 0, 0},
2267     { 0x00541210, "Coincidence Window Width", "DS", "1", 0, 0},
2268     { 0x00541220, "Secondary Counts Type", "CS", "1-n", 0, 0},
2269     { 0x00541300, "Frame Reference Time", "DS", "1", 0, 0},
2270     { 0x00541310, "Primary (Prompts) Counts Accumulated", "IS", "1", 0, 0},
2271     { 0x00541311, "Secondary Counts Accumulated", "IS", "1-n", 0, 0},
2272     { 0x00541320, "Slice Sensitivity Factor", "DS", "1", 0, 0},
2273     { 0x00541321, "Decay Factor", "DS", "1", 0, 0},
2274     { 0x00541322, "Dose Calibration Factor", "DS", "1", 0, 0},
2275     { 0x00541323, "Scatter Fraction Factor", "DS", "1", 0, 0},
2276     { 0x00541324, "Dead Time Factor", "DS", "1", 0, 0},
2277     { 0x00541330, "Image Index", "US", "1", 0, 0},
2278     { 0x00541400, "Counts Included", "CS", "1-n", -1, 0},
2279     { 0x00541401, "Dead Time Correction Flag", "CS", "1", -1, 0},
2280     { 0x00603000, "Histogram Sequence", "SQ", "1", 0, 0},
2281     { 0x00603002, "Histogram Number of Bins", "US", "1", 0, 0},
2282     { 0x00603004, "Histogram First Bin Value", "US or SS", "1", 0, 0},
2283     { 0x00603006, "Histogram Last Bin Value", "US or SS", "1", 0, 0},
2284     { 0x00603008, "Histogram Bin Width", "US", "1", 0, 0},
2285     { 0x00603010, "Histogram Explanation", "LO", "1", 0, 0},
2286     { 0x00603020, "Histogram Data", "UL", "1-n", 0, 0},
2287     { 0x00620001, "Segmentation Type", "CS", "1", 0, 0},
2288     { 0x00620002, "Segment Sequence", "SQ", "1", 0, 0},
2289     { 0x00620003, "Segmented Property Category Code Sequence", "SQ", "1", 0, 0},
2290     { 0x00620004, "Segment Number", "US", "1", 0, 0},
2291     { 0x00620005, "Segment Label", "LO", "1", 0, 0},
2292     { 0x00620006, "Segment Description", "ST", "1", 0, 0},
2293     { 0x00620008, "Segment Algorithm Type", "CS", "1", 0, 0},
2294     { 0x00620009, "Segment Algorithm Name", "LO", "1", 0, 0},
2295     { 0x0062000A, "Segment Identification Sequence", "SQ", "1", 0, 0},
2296     { 0x0062000B, "Referenced Segment Number", "US", "1-n", 0, 0},
2297     { 0x0062000C, "Recommended Display Grayscale Value", "US", "1", 0, 0},
2298     { 0x0062000D, "Recommended Display CIELab Value", "US", "3", 0, 0},
2299     { 0x0062000E, "Maximum Fractional Value", "US", "1", 0, 0},
2300     { 0x0062000F, "Segmented Property Type Code Sequence", "SQ", "1", 0, 0},
2301     { 0x00620010, "Segmentation Fractional Type", "CS", "1", 0, 0},
2302     { 0x00640002, "Deformable Registration Sequence", "SQ", "1", 0, 0},
2303     { 0x00640003, "Source Frame of Reference UID", "UI", "1", 0, 0},
2304     { 0x00640005, "Deformable Registration Grid Sequence", "SQ", "1", 0, 0},
2305     { 0x00640007, "Grid Dimensions", "UL", "3", 0, 0},
2306     { 0x00640008, "Grid Resolution", "FD", "3", 0, 0},
2307     { 0x00640009, "Vector Grid Data", "OF", "1", 0, 0},
2308     { 0x0064000F, "Pre Deformation Matrix Registration Sequence", "SQ", "1", 0, 0},
2309     { 0x00640010, "Post Deformation Matrix Registration Sequence", "SQ", "1", 0, 0},
2310     { 0x00700001, "Graphic Annotation Sequence", "SQ", "1", 0, 0},
2311     { 0x00700002, "Graphic Layer", "CS", "1", 0, 0},
2312     { 0x00700003, "Bounding Box Annotation Units", "CS", "1", 0, 0},
2313     { 0x00700004, "Anchor Point Annotation Units", "CS", "1", 0, 0},
2314     { 0x00700005, "Graphic Annotation Units", "CS", "1", 0, 0},
2315     { 0x00700006, "Unformatted Text Value", "ST", "1", 0, 0},
2316     { 0x00700008, "Text Object Sequence", "SQ", "1", 0, 0},
2317     { 0x00700009, "Graphic Object Sequence", "SQ", "1", 0, 0},
2318     { 0x00700010, "Bounding Box Top Left Hand Corner", "FL", "2", 0, 0},
2319     { 0x00700011, "Bounding Box Bottom Right Hand Corner", "FL", "2", 0, 0},
2320     { 0x00700012, "Bounding Box Text Horizontal Justification", "CS", "1", 0, 0},
2321     { 0x00700014, "Anchor Point", "FL", "2", 0, 0},
2322     { 0x00700015, "Anchor Point Visibility", "CS", "1", 0, 0},
2323     { 0x00700020, "Graphic Dimensions", "US", "1", 0, 0},
2324     { 0x00700021, "Number of Graphic Points", "US", "1", 0, 0},
2325     { 0x00700022, "Graphic Data", "FL", "2-n", 0, 0},
2326     { 0x00700023, "Graphic Type", "CS", "1", 0, 0},
2327     { 0x00700024, "Graphic Filled", "CS", "1", 0, 0},
2328     { 0x00700040, "Image Rotation (Retired)", "IS", "1", -1, 0},
2329     { 0x00700041, "Image Horizontal Flip", "CS", "1", 0, 0},
2330     { 0x00700042, "Image Rotation", "US", "1", 0, 0},
2331     { 0x00700050, "Displayed Area Top Left Hand Corner (Trial)", "US", "2", -1, 0},
2332     { 0x00700051, "Displayed Area Bottom Right Hand Corner (Trial)", "US", "2", -1, 0},
2333     { 0x00700052, "Displayed Area Top Left Hand Corner", "SL", "2", 0, 0},
2334     { 0x00700053, "Displayed Area Bottom Right Hand Corner", "SL", "2", 0, 0},
2335     { 0x0070005A, "Displayed Area Selection Sequence", "SQ", "1", 0, 0},
2336     { 0x00700060, "Graphic Layer Sequence", "SQ", "1", 0, 0},
2337     { 0x00700062, "Graphic Layer Order", "IS", "1", 0, 0},
2338     { 0x00700066, "Graphic Layer Recommended Display Grayscale Value", "US", "1", 0, 0},
2339     { 0x00700067, "Graphic Layer Recommended Display RGB Value", "US", "3", -1, 0},
2340     { 0x00700068, "Graphic Layer Description", "LO", "1", 0, 0},
2341     { 0x00700080, "Content Label", "CS", "1", 0, 0},
2342     { 0x00700081, "Content Description", "LO", "1", 0, 0},
2343     { 0x00700082, "Presentation Creation Date", "DA", "1", 0, 0},
2344     { 0x00700083, "Presentation Creation Time", "TM", "1", 0, 0},
2345     { 0x00700084, "Content Creator's Name", "PN", "1", 0, 0},
2346     { 0x00700086, "Content Creator's Identification Code Sequence", "SQ", "1", 0, 0},
2347     { 0x00700100, "Presentation Size Mode", "CS", "1", 0, 0},
2348     { 0x00700101, "Presentation Pixel Spacing", "DS", "2", 0, 0},
2349     { 0x00700102, "Presentation Pixel Aspect Ratio", "IS", "2", 0, 0},
2350     { 0x00700103, "Presentation Pixel Magnification Ratio", "FL", "1", 0, 0},
2351     { 0x00700306, "Shape Type", "CS", "1", 0, 0},
2352     { 0x00700308, "Registration Sequence", "SQ", "1", 0, 0},
2353     { 0x00700309, "Matrix Registration Sequence", "SQ", "1", 0, 0},
2354     { 0x0070030A, "Matrix Sequence", "SQ", "1", 0, 0},
2355     { 0x0070030C, "Frame of Reference Transformation Matrix Type", "CS", "1", 0, 0},
2356     { 0x0070030D, "Registration Type Code Sequence", "SQ", "1", 0, 0},
2357     { 0x0070030F, "Fiducial Description", "ST", "1", 0, 0},
2358     { 0x00700310, "Fiducial Identifier", "SH", "1", 0, 0},
2359     { 0x00700311, "Fiducial Identifier Code Sequence", "SQ", "1", 0, 0},
2360     { 0x00700312, "Contour Uncertainty Radius", "FD", "1", 0, 0},
2361     { 0x00700314, "Used Fiducials Sequence", "SQ", "1", 0, 0},
2362     { 0x00700318, "Graphic Coordinates Data Sequence", "SQ", "1", 0, 0},
2363     { 0x0070031A, "Fiducial UID", "UI", "1", 0, 0},
2364     { 0x0070031C, "Fiducial Set Sequence", "SQ", "1", 0, 0},
2365     { 0x0070031E, "Fiducial Sequence", "SQ", "1", 0, 0},
2366     { 0x00700401, "Graphic Layer Recommended Display CIELab Value", "US", "3", 0, 0},
2367     { 0x00700402, "Blending Sequence", "SQ", "1", 0, 0},
2368     { 0x00700403, "Relative Opacity", "FL", "1", 0, 0},
2369     { 0x00700404, "Referenced Spatial Registration Sequence", "SQ", "1", 0, 0},
2370     { 0x00700405, "Blending Position", "CS", "1", 0, 0},
2371     { 0x00720002, "Hanging Protocol Name", "SH", "1", 0, 0},
2372     { 0x00720004, "Hanging Protocol Description", "LO", "1", 0, 0},
2373     { 0x00720006, "Hanging Protocol Level", "CS", "1", 0, 0},
2374     { 0x00720008, "Hanging Protocol Creator", "LO", "1", 0, 0},
2375     { 0x0072000A, "Hanging Protocol Creation DateTime", "DT", "1", 0, 0},
2376     { 0x0072000C, "Hanging Protocol Definition Sequence", "SQ", "1", 0, 0},
2377     { 0x0072000E, "Hanging Protocol User Identification Code Sequence", "SQ", "1", 0, 0},
2378     { 0x00720010, "Hanging Protocol User Group Name", "LO", "1", 0, 0},
2379     { 0x00720012, "Source Hanging Protocol Sequence", "SQ", "1", 0, 0},
2380     { 0x00720014, "Number of Priors Referenced", "US", "1", 0, 0},
2381     { 0x00720020, "Image Sets Sequence", "SQ", "1", 0, 0},
2382     { 0x00720022, "Image Set Selector Sequence", "SQ", "1", 0, 0},
2383     { 0x00720024, "Image Set Selector Usage Flag", "CS", "1", 0, 0},
2384     { 0x00720026, "Selector Attribute", "AT", "1", 0, 0},
2385     { 0x00720028, "Selector Value Number", "US", "1", 0, 0},
2386     { 0x00720030, "Time Based Image Sets Sequence", "SQ", "1", 0, 0},
2387     { 0x00720032, "Image Set Number", "US", "1", 0, 0},
2388     { 0x00720034, "Image Set Selector Category", "CS", "1", 0, 0},
2389     { 0x00720038, "Relative Time", "US", "2", 0, 0},
2390     { 0x0072003A, "Relative Time Units", "CS", "1", 0, 0},
2391     { 0x0072003C, "Abstract Prior Value", "SS", "2", 0, 0},
2392     { 0x0072003E, "Abstract Prior Code Sequence", "SQ", "1", 0, 0},
2393     { 0x00720040, "Image Set Label", "LO", "1", 0, 0},
2394     { 0x00720050, "Selector Attribute VR", "CS", "1", 0, 0},
2395     { 0x00720052, "Selector Sequence Pointer", "AT", "1", 0, 0},
2396     { 0x00720054, "Selector Sequence Pointer Private Creator", "LO", "1", 0, 0},
2397     { 0x00720056, "Selector Attribute Private Creator", "LO", "1", 0, 0},
2398     { 0x00720060, "Selector AT Value", "AT", "1-n", 0, 0},
2399     { 0x00720062, "Selector CS Value", "CS", "1-n", 0, 0},
2400     { 0x00720064, "Selector IS Value", "IS", "1-n", 0, 0},
2401     { 0x00720066, "Selector LO Value", "LO", "1-n", 0, 0},
2402     { 0x00720068, "Selector LT Value", "LT", "1", 0, 0},
2403     { 0x0072006A, "Selector PN Value", "PN", "1-n", 0, 0},
2404     { 0x0072006C, "Selector SH Value", "SH", "1-n", 0, 0},
2405     { 0x0072006E, "Selector ST Value", "ST", "1", 0, 0},
2406     { 0x00720070, "Selector UT Value", "UT", "1", 0, 0},
2407     { 0x00720072, "Selector DS Value", "DS", "1-n", 0, 0},
2408     { 0x00720074, "Selector FD Value", "FD", "1-n", 0, 0},
2409     { 0x00720076, "Selector FL Value", "FL", "1-n", 0, 0},
2410     { 0x00720078, "Selector UL Value", "UL", "1-n", 0, 0},
2411     { 0x0072007A, "Selector US Value", "US", "1-n", 0, 0},
2412     { 0x0072007C, "Selector SL Value", "SL", "1-n", 0, 0},
2413     { 0x0072007E, "Selector SS Value", "SS", "1-n", 0, 0},
2414     { 0x00720080, "Selector Code Sequence Value", "SQ", "1", 0, 0},
2415     { 0x00720100, "Number of Screens", "US", "1", 0, 0},
2416     { 0x00720102, "Nominal Screen Definition Sequence", "SQ", "1", 0, 0},
2417     { 0x00720104, "Number of Vertical Pixels", "US", "1", 0, 0},
2418     { 0x00720106, "Number of Horizontal Pixels", "US", "1", 0, 0},
2419     { 0x00720108, "Display Environment Spatial Position", "FD", "4", 0, 0},
2420     { 0x0072010A, "Screen Minimum Grayscale Bit Depth", "US", "1", 0, 0},
2421     { 0x0072010C, "Screen Minimum Color Bit Depth", "US", "1", 0, 0},
2422     { 0x0072010E, "Application Maximum Repaint Time", "US", "1", 0, 0},
2423     { 0x00720200, "Display Sets Sequence", "SQ", "1", 0, 0},
2424     { 0x00720202, "Display Set Number", "US", "1", 0, 0},
2425     { 0x00720203, "Display Set Label", "LO", "1", 0, 0},
2426     { 0x00720204, "Display Set Presentation Group", "US", "1", 0, 0},
2427     { 0x00720206, "Display Set Presentation Group Description", "LO", "1", 0, 0},
2428     { 0x00720208, "Partial Data Display Handling", "CS", "1", 0, 0},
2429     { 0x00720210, "Synchronized Scrolling Sequence", "SQ", "1", 0, 0},
2430     { 0x00720212, "Display Set Scrolling Group", "US", "2-n", 0, 0},
2431     { 0x00720214, "Navigation Indicator Sequence", "SQ", "1", 0, 0},
2432     { 0x00720216, "Navigation Display Set", "US", "1", 0, 0},
2433     { 0x00720218, "Reference Display Sets", "US", "1-n", 0, 0},
2434     { 0x00720300, "Image Boxes Sequence", "SQ", "1", 0, 0},
2435     { 0x00720302, "Image Box Number", "US", "1", 0, 0},
2436     { 0x00720304, "Image Box Layout Type", "CS", "1", 0, 0},
2437     { 0x00720306, "Image Box Tile Horizontal Dimension", "US", "1", 0, 0},
2438     { 0x00720308, "Image Box Tile Vertical Dimension", "US", "1", 0, 0},
2439     { 0x00720310, "Image Box Scroll Direction", "CS", "1", 0, 0},
2440     { 0x00720312, "Image Box Small Scroll Type", "CS", "1", 0, 0},
2441     { 0x00720314, "Image Box Small Scroll Amount", "US", "1", 0, 0},
2442     { 0x00720316, "Image Box Large Scroll Type", "CS", "1", 0, 0},
2443     { 0x00720318, "Image Box Large Scroll Amount", "US", "1", 0, 0},
2444     { 0x00720320, "Image Box Overlap Priority", "US", "1", 0, 0},
2445     { 0x00720330, "Cine Relative to Real-Time", "FD", "1", 0, 0},
2446     { 0x00720400, "Filter Operations Sequence", "SQ", "1", 0, 0},
2447     { 0x00720402, "Filter-by Category", "CS", "1", 0, 0},
2448     { 0x00720404, "Filter-by Attribute Presence", "CS", "1", 0, 0},
2449     { 0x00720406, "Filter-by Operator", "CS", "1", 0, 0},
2450     { 0x00720500, "Blending Operation Type", "CS", "1", 0, 0},
2451     { 0x00720510, "Reformatting Operation Type", "CS", "1", 0, 0},
2452     { 0x00720512, "Reformatting Thickness", "FD", "1", 0, 0},
2453     { 0x00720514, "Reformatting Interval", "FD", "1", 0, 0},
2454     { 0x00720516, "Reformatting Operation Initial View Direction", "CS", "1", 0, 0},
2455     { 0x00720520, "3D Rendering Type", "CS", "1-n", 0, 0},
2456     { 0x00720600, "Sorting Operations Sequence", "SQ", "1", 0, 0},
2457     { 0x00720602, "Sort-by Category", "CS", "1", 0, 0},
2458     { 0x00720604, "Sorting Direction", "CS", "1", 0, 0},
2459     { 0x00720700, "Display Set Patient Orientation", "CS", "2", 0, 0},
2460     { 0x00720702, "VOI Type", "CS", "1", 0, 0},
2461     { 0x00720704, "Pseudo-color Type", "CS", "1", 0, 0},
2462     { 0x00720706, "Show Grayscale Inverted", "CS", "1", 0, 0},
2463     { 0x00720710, "Show Image True Size Flag", "CS", "1", 0, 0},
2464     { 0x00720712, "Show Graphic Annotation Flag", "CS", "1", 0, 0},
2465     { 0x00720714, "Show Patient Demographics Flag", "CS", "1", 0, 0},
2466     { 0x00720716, "Show Acquisition Techniques Flag", "CS", "1", 0, 0},
2467     { 0x00720717, "Display Set Horizontal Justification", "CS", "1", 0, 0},
2468     { 0x00720718, "Display Set Vertical Justification", "CS", "1", 0, 0},
2469     { 0x00741000, "Unified Procedure Step State", "CS", "1", 0, 0},
2470     { 0x00741002, "UPS Progress Information Sequence", "SQ", "1", 0, 0},
2471     { 0x00741004, "Unified Procedure Step Progress", "DS", "1", 0, 0},
2472     { 0x00741006, "Unified Procedure Step Progress Description", "ST", "1", 0, 0},
2473     { 0x00741008, "Unified Procedure Step Communications URI Sequence", "SQ", "1", 0, 0},
2474     { 0x0074100a, "Contact URI", "ST", "1", 0, 0},
2475     { 0x0074100c, "Contact Display Name", "LO", "1", 0, 0},
2476     { 0x0074100e, "Unified Procedure Step Discontinuation Reason Code Sequence", "SQ", "1", 0, 0},
2477     { 0x00741020, "Beam Task Sequence", "SQ", "1", 0, 0},
2478     { 0x00741022, "Beam Task Type", "CS", "1", 0, 0},
2479     { 0x00741024, "Beam Order Index", "IS", "1", 0, 0},
2480     { 0x00741030, "Delivery Verification Image Sequence", "SQ", "1", 0, 0},
2481     { 0x00741032, "Verification Image Timing", "CS", "1", 0, 0},
2482     { 0x00741034, "Double Exposure Flag", "CS", "1", 0, 0},
2483     { 0x00741036, "Double Exposure Ordering", "CS", "1", 0, 0},
2484     { 0x00741038, "Double Exposure Meterset", "DS", "1", 0, 0},
2485     { 0x0074103A, "Double Exposure Field Delta", "DS", "4", 0, 0},
2486     { 0x00741040, "Related Reference RT Image Sequence", "SQ", "1", 0, 0},
2487     { 0x00741042, "General Machine Verification Sequence", "SQ", "1", 0, 0},
2488     { 0x00741044, "Conventional Machine Verification Sequence", "SQ", "1", 0, 0},
2489     { 0x00741046, "Ion Machine Verification Sequence", "SQ", "1", 0, 0},
2490     { 0x00741048, "Failed Attributes Sequence", "SQ", "1-n", 0, 0},
2491     { 0x0074104A, "Overridden Attributes Sequence", "SQ", "1-n", 0, 0},
2492     { 0x0074104C, "Conventional Control Point Verification Sequence", "SQ", "1", 0, 0},
2493     { 0x0074104E, "Ion Control Point Verification Sequence", "SQ", "1", 0, 0},
2494     { 0x00741050, "Attribute Occurrence Sequence", "SQ", "1-n", 0, 0},
2495     { 0x00741052, "Attribute Occurrence Pointer", "AT", "1", 0, 0},
2496     { 0x00741054, "Attribute Item Selector", "UL", "1", 0, 0},
2497     { 0x00741056, "Attribute Occurrence Private Creator", "LO", "1", 0, 0},
2498     { 0x00741200, "Scheduled Procedure Step Priority", "CS", "1", 0, 0},
2499     { 0x00741202, "Worklist Label", "LO", "1", 0, 0},
2500     { 0x00741204, "Procedure Step Label", "LO", "1", 0, 0},
2501     { 0x00741210, "Scheduled Processing Parameters Sequence", "SQ", "1", 0, 0},
2502     { 0x00741212, "Performed Processing Parameters Sequence", "SQ", "1", 0, 0},
2503     { 0x00741216, "UPS Performed Procedure Sequence", "SQ", "1", 0, 0},
2504     { 0x00741220, "Related Procedure Step Sequence", "SQ", "1", 0, 0},
2505     { 0x00741222, "Procedure Step Relationship Type", "LO", "1", 0, 0},
2506     { 0x00741230, "Deletion Lock", "LO", "1", 0, 0},
2507     { 0x00741234, "Receiving AE", "AE", "1", 0, 0},
2508     { 0x00741236, "Requesting AE", "AE", "1", 0, 0},
2509     { 0x00741238, "Reason for Cancellation", "LT", "1", 0, 0},
2510     { 0x00741242, "SCP Status", "CS", "1", 0, 0},
2511     { 0x00741244, "Subscription List Status", "CS", "1", 0, 0},
2512     { 0x00741246, "UPS List Status", "CS", "1", 0, 0},
2513     { 0x00880130, "Storage Media File-set ID", "SH", "1", 0, 0},
2514     { 0x00880140, "Storage Media File-set UID", "UI", "1", 0, 0},
2515     { 0x00880200, "Icon Image Sequence", "SQ", "1", 0, 0},
2516     { 0x00880904, "Topic Title", "LO", "1", -1, 0},
2517     { 0x00880906, "Topic Subject", "ST", "1", -1, 0},
2518     { 0x00880910, "Topic Author", "LO", "1", -1, 0},
2519     { 0x00880912, "Topic Keywords", "LO", "1-32", -1, 0},
2520     { 0x01000410, "SOP Instance Status", "CS", "1", 0, 0},
2521     { 0x01000420, "SOP Authorization Date and Time", "DT", "1", 0, 0},
2522     { 0x01000424, "SOP Authorization Comment", "LT", "1", 0, 0},
2523     { 0x01000426, "Authorization Equipment Certification Number", "LO", "1", 0, 0},
2524     { 0x04000005, "MAC ID Number", "US", "1", 0, 0},
2525     { 0x04000010, "MAC Calculation Transfer Syntax UID", "UI", "1", 0, 0},
2526     { 0x04000015, "MAC Algorithm", "CS", "1", 0, 0},
2527     { 0x04000020, "Data Elements Signed", "AT", "1-n", 0, 0},
2528     { 0x04000100, "Digital Signature UID", "UI", "1", 0, 0},
2529     { 0x04000105, "Digital Signature DateTime", "DT", "1", 0, 0},
2530     { 0x04000110, "Certificate Type", "CS", "1", 0, 0},
2531     { 0x04000115, "Certificate of Signer", "OB", "1", 0, 0},
2532     { 0x04000120, "Signature", "OB", "1", 0, 0},
2533     { 0x04000305, "Certified Timestamp Type", "CS", "1", 0, 0},
2534     { 0x04000310, "Certified Timestamp", "OB", "1", 0, 0},
2535     { 0x04000401, "Digital Signature Purpose Code Sequence", "SQ", "1", 0, 0},
2536     { 0x04000402, "Referenced Digital Signature Sequence", "SQ", "1", 0, 0},
2537     { 0x04000403, "Referenced SOP Instance MAC Sequence", "SQ", "1", 0, 0},
2538     { 0x04000404, "MAC", "OB", "1", 0, 0},
2539     { 0x04000500, "Encrypted Attributes Sequence", "SQ", "1", 0, 0},
2540     { 0x04000510, "Encrypted Content Transfer Syntax UID", "UI", "1", 0, 0},
2541     { 0x04000520, "Encrypted Content", "OB", "1", 0, 0},
2542     { 0x04000550, "Modified Attributes Sequence", "SQ", "1", 0, 0},
2543     { 0x04000561, "Original Attributes Sequence", "SQ", "1", 0, 0},
2544     { 0x04000562, "Attribute Modification DateTime", "DT", "1", 0, 0},
2545     { 0x04000563, "Modifying System", "LO", "1", 0, 0},
2546     { 0x04000564, "Source of Previous Values", "LO", "1", 0, 0},
2547     { 0x04000565, "Reason for the Attribute Modification", "CS", "1", 0, 0},
2548     { 0x10000000, "Escape Triplet", "US", "3", -1, 0},
2549     { 0x10000001, "Run Length Triplet", "US", "3", -1, 0},
2550     { 0x10000002, "Huffman Table Size", "US", "1", -1, 0},
2551     { 0x10000003, "Huffman Table Triplet", "US", "3", -1, 0},
2552     { 0x10000004, "Shift Table Size", "US", "1", -1, 0},
2553     { 0x10000005, "Shift Table Triplet", "US", "3", -1, 0},
2554     { 0x10100000, "Zonal Map", "US", "1-n", -1, 0},
2555     { 0x20000010, "Number of Copies", "IS", "1", 0, 0},
2556     { 0x2000001E, "Printer Configuration Sequence", "SQ", "1", 0, 0},
2557     { 0x20000020, "Print Priority", "CS", "1", 0, 0},
2558     { 0x20000030, "Medium Type", "CS", "1", 0, 0},
2559     { 0x20000040, "Film Destination", "CS", "1", 0, 0},
2560     { 0x20000050, "Film Session Label", "LO", "1", 0, 0},
2561     { 0x20000060, "Memory Allocation", "IS", "1", 0, 0},
2562     { 0x20000061, "Maximum Memory Allocation", "IS", "1", 0, 0},
2563     { 0x20000062, "Color Image Printing Flag", "CS", "1", -1, 0},
2564     { 0x20000063, "Collation Flag", "CS", "1", -1, 0},
2565     { 0x20000065, "Annotation Flag", "CS", "1", -1, 0},
2566     { 0x20000067, "Image Overlay Flag", "CS", "1", -1, 0},
2567     { 0x20000069, "Presentation LUT Flag", "CS", "1", -1, 0},
2568     { 0x2000006A, "Image Box Presentation LUT Flag", "CS", "1", -1, 0},
2569     { 0x200000A0, "Memory Bit Depth", "US", "1", 0, 0},
2570     { 0x200000A1, "Printing Bit Depth", "US", "1", 0, 0},
2571     { 0x200000A2, "Media Installed Sequence", "SQ", "1", 0, 0},
2572     { 0x200000A4, "Other Media Available Sequence", "SQ", "1", 0, 0},
2573     { 0x200000A8, "Supported Image Display Formats Sequence", "SQ", "1", 0, 0},
2574     { 0x20000500, "Referenced Film Box Sequence", "SQ", "1", 0, 0},
2575     { 0x20000510, "Referenced Stored Print Sequence", "SQ", "1", -1, 0},
2576     { 0x20100010, "Image Display Format", "ST", "1", 0, 0},
2577     { 0x20100030, "Annotation Display Format ID", "CS", "1", 0, 0},
2578     { 0x20100040, "Film Orientation", "CS", "1", 0, 0},
2579     { 0x20100050, "Film Size ID", "CS", "1", 0, 0},
2580     { 0x20100052, "Printer Resolution ID", "CS", "1", 0, 0},
2581     { 0x20100054, "Default Printer Resolution ID", "CS", "1", 0, 0},
2582     { 0x20100060, "Magnification Type", "CS", "1", 0, 0},
2583     { 0x20100080, "Smoothing Type", "CS", "1", 0, 0},
2584     { 0x201000A6, "Default Magnification Type", "CS", "1", 0, 0},
2585     { 0x201000A7, "Other Magnification Types Available", "CS", "1-n", 0, 0},
2586     { 0x201000A8, "Default Smoothing Type", "CS", "1", 0, 0},
2587     { 0x201000A9, "Other Smoothing Types Available", "CS", "1-n", 0, 0},
2588     { 0x20100100, "Border Density", "CS", "1", 0, 0},
2589     { 0x20100110, "Empty Image Density", "CS", "1", 0, 0},
2590     { 0x20100120, "Min Density", "US", "1", 0, 0},
2591     { 0x20100130, "Max Density", "US", "1", 0, 0},
2592     { 0x20100140, "Trim", "CS", "1", 0, 0},
2593     { 0x20100150, "Configuration Information", "ST", "1", 0, 0},
2594     { 0x20100152, "Configuration Information Description", "LT", "1", 0, 0},
2595     { 0x20100154, "Maximum Collated Films", "IS", "1", 0, 0},
2596     { 0x2010015E, "Illumination", "US", "1", 0, 0},
2597     { 0x20100160, "Reflected Ambient Light", "US", "1", 0, 0},
2598     { 0x20100376, "Printer Pixel Spacing", "DS", "2", 0, 0},
2599     { 0x20100500, "Referenced Film Session Sequence", "SQ", "1", 0, 0},
2600     { 0x20100510, "Referenced Image Box Sequence", "SQ", "1", 0, 0},
2601     { 0x20100520, "Referenced Basic Annotation Box Sequence", "SQ", "1", 0, 0},
2602     { 0x20200010, "Image Box Position", "US", "1", 0, 0},
2603     { 0x20200020, "Polarity", "CS", "1", 0, 0},
2604     { 0x20200030, "Requested Image Size", "DS", "1", 0, 0},
2605     { 0x20200040, "Requested Decimate/Crop Behavior", "CS", "1", 0, 0},
2606     { 0x20200050, "Requested Resolution ID", "CS", "1", 0, 0},
2607     { 0x202000A0, "Requested Image Size Flag", "CS", "1", 0, 0},
2608     { 0x202000A2, "Decimate/Crop Result", "CS", "1", 0, 0},
2609     { 0x20200110, "Basic Grayscale Image Sequence", "SQ", "1", 0, 0},
2610     { 0x20200111, "Basic Color Image Sequence", "SQ", "1", 0, 0},
2611     { 0x20200130, "Referenced Image Overlay Box Sequence", "SQ", "1", -1, 0},
2612     { 0x20200140, "Referenced VOI LUT Box Sequence", "SQ", "1", -1, 0},
2613     { 0x20300010, "Annotation Position", "US", "1", 0, 0},
2614     { 0x20300020, "Text String", "LO", "1", 0, 0},
2615     { 0x20400010, "Referenced Overlay Plane Sequence", "SQ", "1", -1, 0},
2616     { 0x20400011, "Referenced Overlay Plane Groups", "US", "1-99", -1, 0},
2617     { 0x20400020, "Overlay Pixel Data Sequence", "SQ", "1", -1, 0},
2618     { 0x20400060, "Overlay Magnification Type", "CS", "1", -1, 0},
2619     { 0x20400070, "Overlay Smoothing Type", "CS", "1", -1, 0},
2620     { 0x20400072, "Overlay or Image Magnification", "CS", "1", -1, 0},
2621     { 0x20400074, "Magnify to Number of Columns", "US", "1", -1, 0},
2622     { 0x20400080, "Overlay Foreground Density", "CS", "1", -1, 0},
2623     { 0x20400082, "Overlay Background Density", "CS", "1", -1, 0},
2624     { 0x20400090, "Overlay Mode", "CS", "1", -1, 0},
2625     { 0x20400100, "Threshold Density", "CS", "1", -1, 0},
2626     { 0x20400500, "Referenced Image Box Sequence (Retired)", "SQ", "1", -1, 0},
2627     { 0x20500010, "Presentation LUT Sequence", "SQ", "1", 0, 0},
2628     { 0x20500020, "Presentation LUT Shape", "CS", "1", 0, 0},
2629     { 0x20500500, "Referenced Presentation LUT Sequence", "SQ", "1", 0, 0},
2630     { 0x21000010, "Print Job ID", "SH", "1", -1, 0},
2631     { 0x21000020, "Execution Status", "CS", "1", 0, 0},
2632     { 0x21000030, "Execution Status Info", "CS", "1", 0, 0},
2633     { 0x21000040, "Creation Date", "DA", "1", 0, 0},
2634     { 0x21000050, "Creation Time", "TM", "1", 0, 0},
2635     { 0x21000070, "Originator", "AE", "1", 0, 0},
2636     { 0x21000140, "Destination AE", "AE", "1", -1, 0},
2637     { 0x21000160, "Owner ID", "SH", "1", 0, 0},
2638     { 0x21000170, "Number of Films", "IS", "1", 0, 0},
2639     { 0x21000500, "Referenced Print Job Sequence (Pull Stored Print)", "SQ", "1", -1, 0},
2640     { 0x21100010, "Printer Status", "CS", "1", 0, 0},
2641     { 0x21100020, "Printer Status Info", "CS", "1", 0, 0},
2642     { 0x21100030, "Printer Name", "LO", "1", 0, 0},
2643     { 0x21100099, "Print Queue ID", "SH", "1", -1, 0},
2644     { 0x21200010, "Queue Status", "CS", "1", -1, 0},
2645     { 0x21200050, "Print Job Description Sequence", "SQ", "1", -1, 0},
2646     { 0x21200070, "Referenced Print Job Sequence", "SQ", "1", -1, 0},
2647     { 0x21300010, "Print Management Capabilities Sequence", "SQ", "1", -1, 0},
2648     { 0x21300015, "Printer Characteristics Sequence", "SQ", "1", -1, 0},
2649     { 0x21300030, "Film Box Content Sequence", "SQ", "1", -1, 0},
2650     { 0x21300040, "Image Box Content Sequence", "SQ", "1", -1, 0},
2651     { 0x21300050, "Annotation Content Sequence", "SQ", "1", -1, 0},
2652     { 0x21300060, "Image Overlay Box Content Sequence", "SQ", "1", -1, 0},
2653     { 0x21300080, "Presentation LUT Content Sequence", "SQ", "1", -1, 0},
2654     { 0x213000A0, "Proposed Study Sequence", "SQ", "1", -1, 0},
2655     { 0x213000C0, "Original Image Sequence", "SQ", "1", -1, 0},
2656     { 0x22000001, "Label Using Information Extracted From Instances", "CS", "1", 0, 0},
2657     { 0x22000002, "Label Text", "UT", "1", 0, 0},
2658     { 0x22000003, "Label Style Selection", "CS", "1", 0, 0},
2659     { 0x22000004, "Media Disposition", "LT", "1", 0, 0},
2660     { 0x22000005, "Barcode Value", "LT", "1", 0, 0},
2661     { 0x22000006, "Barcode Symbology", "CS", "1", 0, 0},
2662     { 0x22000007, "Allow Media Splitting", "CS", "1", 0, 0},
2663     { 0x22000008, "Include Non-DICOM Objects", "CS", "1", 0, 0},
2664     { 0x22000009, "Include Display Application", "CS", "1", 0, 0},
2665     { 0x2200000A, "Preserve Composite Instances After Media Creation", "CS", "1", 0, 0},
2666     { 0x2200000B, "Total Number of Pieces of Media Created", "US", "1", 0, 0},
2667     { 0x2200000C, "Requested Media Application Profile", "LO", "1", 0, 0},
2668     { 0x2200000D, "Referenced Storage Media Sequence", "SQ", "1", 0, 0},
2669     { 0x2200000E, "Failure Attributes", "AT", "1-n", 0, 0},
2670     { 0x2200000F, "Allow Lossy Compression", "CS", "1", 0, 0},
2671     { 0x22000020, "Request Priority", "CS", "1", 0, 0},
2672     { 0x30020002, "RT Image Label", "SH", "1", 0, 0},
2673     { 0x30020003, "RT Image Name", "LO", "1", 0, 0},
2674     { 0x30020004, "RT Image Description", "ST", "1", 0, 0},
2675     { 0x3002000A, "Reported Values Origin", "CS", "1", 0, 0},
2676     { 0x3002000C, "RT Image Plane", "CS", "1", 0, 0},
2677     { 0x3002000D, "X-Ray Image Receptor Translation", "DS", "3", 0, 0},
2678     { 0x3002000E, "X-Ray Image Receptor Angle", "DS", "1", 0, 0},
2679     { 0x30020010, "RT Image Orientation", "DS", "6", 0, 0},
2680     { 0x30020011, "Image Plane Pixel Spacing", "DS", "2", 0, 0},
2681     { 0x30020012, "RT Image Position", "DS", "2", 0, 0},
2682     { 0x30020020, "Radiation Machine Name", "SH", "1", 0, 0},
2683     { 0x30020022, "Radiation Machine SAD", "DS", "1", 0, 0},
2684     { 0x30020024, "Radiation Machine SSD", "DS", "1", 0, 0},
2685     { 0x30020026, "RT Image SID", "DS", "1", 0, 0},
2686     { 0x30020028, "Source to Reference Object Distance", "DS", "1", 0, 0},
2687     { 0x30020029, "Fraction Number", "IS", "1", 0, 0},
2688     { 0x30020030, "Exposure Sequence", "SQ", "1", 0, 0},
2689     { 0x30020032, "Meterset Exposure", "DS", "1", 0, 0},
2690     { 0x30020034, "Diaphragm Position", "DS", "4", 0, 0},
2691     { 0x30020040, "Fluence Map Sequence", "SQ", "1", 0, 0},
2692     { 0x30020041, "Fluence Data Source", "CS", "1", 0, 0},
2693     { 0x30020042, "Fluence Data Scale", "DS", "1", 0, 0},
2694     { 0x30040001, "DVH Type", "CS", "1", 0, 0},
2695     { 0x30040002, "Dose Units", "CS", "1", 0, 0},
2696     { 0x30040004, "Dose Type", "CS", "1", 0, 0},
2697     { 0x30040006, "Dose Comment", "LO", "1", 0, 0},
2698     { 0x30040008, "Normalization Point", "DS", "3", 0, 0},
2699     { 0x3004000A, "Dose Summation Type", "CS", "1", 0, 0},
2700     { 0x3004000C, "Grid Frame Offset Vector", "DS", "2-n", 0, 0},
2701     { 0x3004000E, "Dose Grid Scaling", "DS", "1", 0, 0},
2702     { 0x30040010, "RT Dose ROI Sequence", "SQ", "1", 0, 0},
2703     { 0x30040012, "Dose Value", "DS", "1", 0, 0},
2704     { 0x30040014, "Tissue Heterogeneity Correction", "CS", "1-3", 0, 0},
2705     { 0x30040040, "DVH Normalization Point", "DS", "3", 0, 0},
2706     { 0x30040042, "DVH Normalization Dose Value", "DS", "1", 0, 0},
2707     { 0x30040050, "DVH Sequence", "SQ", "1", 0, 0},
2708     { 0x30040052, "DVH Dose Scaling", "DS", "1", 0, 0},
2709     { 0x30040054, "DVH Volume Units", "CS", "1", 0, 0},
2710     { 0x30040056, "DVH Number of Bins", "IS", "1", 0, 0},
2711     { 0x30040058, "DVH Data", "DS", "2-2n", 0, 0},
2712     { 0x30040060, "DVH Referenced ROI Sequence", "SQ", "1", 0, 0},
2713     { 0x30040062, "DVH ROI Contribution Type", "CS", "1", 0, 0},
2714     { 0x30040070, "DVH Minimum Dose", "DS", "1", 0, 0},
2715     { 0x30040072, "DVH Maximum Dose", "DS", "1", 0, 0},
2716     { 0x30040074, "DVH Mean Dose", "DS", "1", 0, 0},
2717     { 0x30060002, "Structure Set Label", "SH", "1", 0, 0},
2718     { 0x30060004, "Structure Set Name", "LO", "1", 0, 0},
2719     { 0x30060006, "Structure Set Description", "ST", "1", 0, 0},
2720     { 0x30060008, "Structure Set Date", "DA", "1", 0, 0},
2721     { 0x30060009, "Structure Set Time", "TM", "1", 0, 0},
2722     { 0x30060010, "Referenced Frame of Reference Sequence", "SQ", "1", 0, 0},
2723     { 0x30060012, "RT Referenced Study Sequence", "SQ", "1", 0, 0},
2724     { 0x30060014, "RT Referenced Series Sequence", "SQ", "1", 0, 0},
2725     { 0x30060016, "Contour Image Sequence", "SQ", "1", 0, 0},
2726     { 0x30060020, "Structure Set ROI Sequence", "SQ", "1", 0, 0},
2727     { 0x30060022, "ROI Number", "IS", "1", 0, -1},
2728     { 0x30060024, "Referenced Frame of Reference UID", "UI", "1", 0, 0},
2729     { 0x30060026, "ROI Name", "LO", "1", 0, -1},
2730     { 0x30060028, "ROI Description", "ST", "1", 0, 0},
2731     { 0x3006002A, "ROI Display Color", "IS", "3", 0, 0},
2732     { 0x3006002C, "ROI Volume", "DS", "1", 0, 0},
2733     { 0x30060030, "RT Related ROI Sequence", "SQ", "1", 0, 0},
2734     { 0x30060033, "RT ROI Relationship", "CS", "1", 0, 0},
2735     { 0x30060036, "ROI Generation Algorithm", "CS", "1", 0, 0},
2736     { 0x30060038, "ROI Generation Description", "LO", "1", 0, 0},
2737     { 0x30060039, "ROI Contour Sequence", "SQ", "1", 0, 0},
2738     { 0x30060040, "Contour Sequence", "SQ", "1", 0, 0},
2739     { 0x30060042, "Contour Geometric Type", "CS", "1", 0, -1},
2740     { 0x30060044, "Contour Slab Thickness", "DS", "1", 0, 0},
2741     { 0x30060045, "Contour Offset Vector", "DS", "3", 0, 0},
2742     { 0x30060046, "Number of Contour Points", "IS", "1", 0, 0},
2743     { 0x30060048, "Contour Number", "IS", "1", 0, 0},
2744     { 0x30060049, "Attached Contours", "IS", "1-n", 0, 0},
2745     { 0x30060050, "Contour Data", "DS", "3-3n", 0, 0},
2746     { 0x30060080, "RT ROI Observations Sequence", "SQ", "1", 0, 0},
2747     { 0x30060082, "Observation Number", "IS", "1", 0, -1},
2748     { 0x30060084, "Referenced ROI Number", "IS", "1", 0, 0},
2749     { 0x30060085, "ROI Observation Label", "SH", "1", 0, -1},
2750     { 0x30060086, "RT ROI Identification Code Sequence", "SQ", "1", 0, 0},
2751     { 0x30060088, "ROI Observation Description", "ST", "1", 0, 0},
2752     { 0x300600A0, "Related RT ROI Observations Sequence", "SQ", "1", 0, 0},
2753     { 0x300600A4, "RT ROI Interpreted Type", "CS", "1", 0, -1},
2754     { 0x300600A6, "ROI Interpreter", "PN", "1", 0, 0},
2755     { 0x300600B0, "ROI Physical Properties Sequence", "SQ", "1", 0, 0},
2756     { 0x300600B2, "ROI Physical Property", "CS", "1", 0, 0},
2757     { 0x300600B4, "ROI Physical Property Value", "DS", "1", 0, 0},
2758     { 0x300600B6, "ROI Elemental Composition Sequence", "SQ", "1", 0, 0},
2759     { 0x300600B7, "ROI Elemental Composition Atomic Number", "US", "1", 0, 0},
2760     { 0x300600B8, "ROI Elemental Composition Atomic Mass Fraction", "FL", "1", 0, 0},
2761     { 0x300600C0, "Frame of Reference Relationship Sequence", "SQ", "1", 0, 0},
2762     { 0x300600C2, "Related Frame of Reference UID", "UI", "1", 0, 0},
2763     { 0x300600C4, "Frame of Reference Transformation Type", "CS", "1", 0, 0},
2764     { 0x300600C6, "Frame of Reference Transformation Matrix", "DS", "16", 0, 0},
2765     { 0x300600C8, "Frame of Reference Transformation Comment", "LO", "1", 0, 0},
2766     { 0x30080010, "Measured Dose Reference Sequence", "SQ", "1", 0, 0},
2767     { 0x30080012, "Measured Dose Description", "ST", "1", 0, 0},
2768     { 0x30080014, "Measured Dose Type", "CS", "1", 0, 0},
2769     { 0x30080016, "Measured Dose Value", "DS", "1", 0, 0},
2770     { 0x30080020, "Treatment Session Beam Sequence", "SQ", "1", 0, 0},
2771     { 0x30080021, "Treatment Session Ion Beam Sequence", "SQ", "1", 0, 0},
2772     { 0x30080022, "Current Fraction Number", "IS", "1", 0, 0},
2773     { 0x30080024, "Treatment Control Point Date", "DA", "1", 0, 0},
2774     { 0x30080025, "Treatment Control Point Time", "TM", "1", 0, 0},
2775     { 0x3008002A, "Treatment Termination Status", "CS", "1", 0, 0},
2776     { 0x3008002B, "Treatment Termination Code", "SH", "1", 0, 0},
2777     { 0x3008002C, "Treatment Verification Status", "CS", "1", 0, 0},
2778     { 0x30080030, "Referenced Treatment Record Sequence", "SQ", "1", 0, 0},
2779     { 0x30080032, "Specified Primary Meterset", "DS", "1", 0, 0},
2780     { 0x30080033, "Specified Secondary Meterset", "DS", "1", 0, 0},
2781     { 0x30080036, "Delivered Primary Meterset", "DS", "1", 0, 0},
2782     { 0x30080037, "Delivered Secondary Meterset", "DS", "1", 0, 0},
2783     { 0x3008003A, "Specified Treatment Time", "DS", "1", 0, 0},
2784     { 0x3008003B, "Delivered Treatment Time", "DS", "1", 0, 0},
2785     { 0x30080040, "Control Point Delivery Sequence", "SQ", "1", 0, 0},
2786     { 0x30080041, "Ion Control Point Delivery Sequence", "SQ", "1", 0, 0},
2787     { 0x30080042, "Specified Meterset", "DS", "1", 0, 0},
2788     { 0x30080044, "Delivered Meterset", "DS", "1", 0, 0},
2789     { 0x30080045, "Meterset Rate Set", "FL", "1", 0, 0},
2790     { 0x30080046, "Meterset Rate Delivered", "FL", "1", 0, 0},
2791     { 0x30080047, "Scan Spot Metersets Delivered", "FL", "1-n", 0, 0},
2792     { 0x30080048, "Dose Rate Delivered", "DS", "1", 0, 0},
2793     { 0x30080050, "Treatment Summary Calculated Dose Reference Sequence", "SQ", "1", 0, 0},
2794     { 0x30080052, "Cumulative Dose to Dose Reference", "DS", "1", 0, 0},
2795     { 0x30080054, "First Treatment Date", "DA", "1", 0, 0},
2796     { 0x30080056, "Most Recent Treatment Date", "DA", "1", 0, 0},
2797     { 0x3008005A, "Number of Fractions Delivered", "IS", "1", 0, 0},
2798     { 0x30080060, "Override Sequence", "SQ", "1", 0, 0},
2799     { 0x30080061, "Parameter Sequence Pointer", "AT", "1", 0, 0},
2800     { 0x30080062, "Override Parameter Pointer", "AT", "1", 0, 0},
2801     { 0x30080063, "Parameter Item Index", "IS", "1", 0, 0},
2802     { 0x30080064, "Measured Dose Reference Number", "IS", "1", 0, 0},
2803     { 0x30080065, "Parameter Pointer", "AT", "1", 0, 0},
2804     { 0x30080066, "Override Reason", "ST", "1", 0, 0},
2805     { 0x30080068, "Corrected Parameter Sequence", "SQ", "1", 0, 0},
2806     { 0x3008006A, "Correction Value", "FL", "1", 0, 0},
2807     { 0x30080070, "Calculated Dose Reference Sequence", "SQ", "1", 0, 0},
2808     { 0x30080072, "Calculated Dose Reference Number", "IS", "1", 0, 0},
2809     { 0x30080074, "Calculated Dose Reference Description", "ST", "1", 0, 0},
2810     { 0x30080076, "Calculated Dose Reference Dose Value", "DS", "1", 0, 0},
2811     { 0x30080078, "Start Meterset", "DS", "1", 0, 0},
2812     { 0x3008007A, "End Meterset", "DS", "1", 0, 0},
2813     { 0x30080080, "Referenced Measured Dose Reference Sequence", "SQ", "1", 0, 0},
2814     { 0x30080082, "Referenced Measured Dose Reference Number", "IS", "1", 0, 0},
2815     { 0x30080090, "Referenced Calculated Dose Reference Sequence", "SQ", "1", 0, 0},
2816     { 0x30080092, "Referenced Calculated Dose Reference Number", "IS", "1", 0, 0},
2817     { 0x300800A0, "Beam Limiting Device Leaf Pairs Sequence", "SQ", "1", 0, 0},
2818     { 0x300800B0, "Recorded Wedge Sequence", "SQ", "1", 0, 0},
2819     { 0x300800C0, "Recorded Compensator Sequence", "SQ", "1", 0, 0},
2820     { 0x300800D0, "Recorded Block Sequence", "SQ", "1", 0, 0},
2821     { 0x300800E0, "Treatment Summary Measured Dose Reference Sequence", "SQ", "1", 0, 0},
2822     { 0x300800F0, "Recorded Snout Sequence", "SQ", "1", 0, 0},
2823     { 0x300800F2, "Recorded Range Shifter Sequence", "SQ", "1", 0, 0},
2824     { 0x300800F4, "Recorded Lateral Spreading Device Sequence", "SQ", "1", 0, 0},
2825     { 0x300800F6, "Recorded Range Modulator Sequence", "SQ", "1", 0, 0},
2826     { 0x30080100, "Recorded Source Sequence", "SQ", "1", 0, 0},
2827     { 0x30080105, "Source Serial Number", "LO", "1", 0, 0},
2828     { 0x30080110, "Treatment Session Application Setup Sequence", "SQ", "1", 0, 0},
2829     { 0x30080116, "Application Setup Check", "CS", "1", 0, 0},
2830     { 0x30080120, "Recorded Brachy Accessory Device Sequence", "SQ", "1", 0, 0},
2831     { 0x30080122, "Referenced Brachy Accessory Device Number", "IS", "1", 0, 0},
2832     { 0x30080130, "Recorded Channel Sequence", "SQ", "1", 0, 0},
2833     { 0x30080132, "Specified Channel Total Time", "DS", "1", 0, 0},
2834     { 0x30080134, "Delivered Channel Total Time", "DS", "1", 0, 0},
2835     { 0x30080136, "Specified Number of Pulses", "IS", "1", 0, 0},
2836     { 0x30080138, "Delivered Number of Pulses", "IS", "1", 0, 0},
2837     { 0x3008013A, "Specified Pulse Repetition Interval", "DS", "1", 0, 0},
2838     { 0x3008013C, "Delivered Pulse Repetition Interval", "DS", "1", 0, 0},
2839     { 0x30080140, "Recorded Source Applicator Sequence", "SQ", "1", 0, 0},
2840     { 0x30080142, "Referenced Source Applicator Number", "IS", "1", 0, 0},
2841     { 0x30080150, "Recorded Channel Shield Sequence", "SQ", "1", 0, 0},
2842     { 0x30080152, "Referenced Channel Shield Number", "IS", "1", 0, 0},
2843     { 0x30080160, "Brachy Control Point Delivered Sequence", "SQ", "1", 0, 0},
2844     { 0x30080162, "Safe Position Exit Date", "DA", "1", 0, 0},
2845     { 0x30080164, "Safe Position Exit Time", "TM", "1", 0, 0},
2846     { 0x30080166, "Safe Position Return Date", "DA", "1", 0, 0},
2847     { 0x30080168, "Safe Position Return Time", "TM", "1", 0, 0},
2848     { 0x30080200, "Current Treatment Status", "CS", "1", 0, 0},
2849     { 0x30080202, "Treatment Status Comment", "ST", "1", 0, 0},
2850     { 0x30080220, "Fraction Group Summary Sequence", "SQ", "1", 0, 0},
2851     { 0x30080223, "Referenced Fraction Number", "IS", "1", 0, 0},
2852     { 0x30080224, "Fraction Group Type", "CS", "1", 0, 0},
2853     { 0x30080230, "Beam Stopper Position", "CS", "1", 0, 0},
2854     { 0x30080240, "Fraction Status Summary Sequence", "SQ", "1", 0, 0},
2855     { 0x30080250, "Treatment Date", "DA", "1", 0, 0},
2856     { 0x30080251, "Treatment Time", "TM", "1", 0, 0},
2857     { 0x300A0002, "RT Plan Label", "SH", "1", 0, 0},
2858     { 0x300A0003, "RT Plan Name", "LO", "1", 0, 0},
2859     { 0x300A0004, "RT Plan Description", "ST", "1", 0, 0},
2860     { 0x300A0006, "RT Plan Date", "DA", "1", 0, 0},
2861     { 0x300A0007, "RT Plan Time", "TM", "1", 0, 0},
2862     { 0x300A0009, "Treatment Protocols", "LO", "1-n", 0, 0},
2863     { 0x300A000A, "Plan Intent", "CS", "1", 0, 0},
2864     { 0x300A000B, "Treatment Sites", "LO", "1-n", 0, 0},
2865     { 0x300A000C, "RT Plan Geometry", "CS", "1", 0, 0},
2866     { 0x300A000E, "Prescription Description", "ST", "1", 0, 0},
2867     { 0x300A0010, "Dose Reference Sequence", "SQ", "1", 0, 0},
2868     { 0x300A0012, "Dose Reference Number", "IS", "1", 0, 0},
2869     { 0x300A0013, "Dose Reference UID", "UI", "1", 0, 0},
2870     { 0x300A0014, "Dose Reference Structure Type", "CS", "1", 0, -1},
2871     { 0x300A0015, "Nominal Beam Energy Unit", "CS", "1", 0, 0},
2872     { 0x300A0016, "Dose Reference Description", "LO", "1", 0, -1},
2873     { 0x300A0018, "Dose Reference Point Coordinates", "DS", "3", 0, 0},
2874     { 0x300A001A, "Nominal Prior Dose", "DS", "1", 0, 0},
2875     { 0x300A0020, "Dose Reference Type", "CS", "1", 0, -1},
2876     { 0x300A0021, "Constraint Weight", "DS", "1", 0, 0},
2877     { 0x300A0022, "Delivery Warning Dose", "DS", "1", 0, 0},
2878     { 0x300A0023, "Delivery Maximum Dose", "DS", "1", 0, 0},
2879     { 0x300A0025, "Target Minimum Dose", "DS", "1", 0, 0},
2880     { 0x300A0026, "Target Prescription Dose", "DS", "1", 0, -1},
2881     { 0x300A0027, "Target Maximum Dose", "DS", "1", 0, 0},
2882     { 0x300A0028, "Target Underdose Volume Fraction", "DS", "1", 0, 0},
2883     { 0x300A002A, "Organ at Risk Full-volume Dose", "DS", "1", 0, 0},
2884     { 0x300A002B, "Organ at Risk Limit Dose", "DS", "1", 0, 0},
2885     { 0x300A002C, "Organ at Risk Maximum Dose", "DS", "1", 0, 0},
2886     { 0x300A002D, "Organ at Risk Overdose Volume Fraction", "DS", "1", 0, 0},
2887     { 0x300A0040, "Tolerance Table Sequence", "SQ", "1", 0, 0},
2888     { 0x300A0042, "Tolerance Table Number", "IS", "1", 0, 0},
2889     { 0x300A0043, "Tolerance Table Label", "SH", "1", 0, -1},
2890     { 0x300A0044, "Gantry Angle Tolerance", "DS", "1", 0, 0},
2891     { 0x300A0046, "Beam Limiting Device Angle Tolerance", "DS", "1", 0, 0},
2892     { 0x300A0048, "Beam Limiting Device Tolerance Sequence", "SQ", "1", 0, 0},
2893     { 0x300A004A, "Beam Limiting Device Position Tolerance", "DS", "1", 0, -1},
2894     { 0x300A004B, "Snout Position Tolerance", "FL", "1", 0, 0},
2895     { 0x300A004C, "Patient Support Angle Tolerance", "DS", "1", 0, 0},
2896     { 0x300A004E, "Table Top Eccentric Angle Tolerance", "DS", "1", 0, 0},
2897     { 0x300A004F, "Table Top Pitch Angle Tolerance", "FL", "1", 0, 0},
2898     { 0x300A0050, "Table Top Roll Angle Tolerance", "FL", "1", 0, 0},
2899     { 0x300A0051, "Table Top Vertical Position Tolerance", "DS", "1", 0, 0},
2900     { 0x300A0052, "Table Top Longitudinal Position Tolerance", "DS", "1", 0, 0},
2901     { 0x300A0053, "Table Top Lateral Position Tolerance", "DS", "1", 0, 0},
2902     { 0x300A0055, "RT Plan Relationship", "CS", "1", 0, 0},
2903     { 0x300A0070, "Fraction Group Sequence", "SQ", "1", 0, 0},
2904     { 0x300A0071, "Fraction Group Number", "IS", "1", 0, 0},
2905     { 0x300A0072, "Fraction Group Description", "LO", "1", 0, 0},
2906     { 0x300A0078, "Number of Fractions Planned", "IS", "1", 0, -1},
2907     { 0x300A0079, "Number of Fraction Pattern Digits Per Day", "IS", "1", 0, 0},
2908     { 0x300A007A, "Repeat Fraction Cycle Length", "IS", "1", 0, 0},
2909     { 0x300A007B, "Fraction Pattern", "LT", "1", 0, 0},
2910     { 0x300A0080, "Number of Beams", "IS", "1", 0, 0},
2911     { 0x300A0082, "Beam Dose Specification Point", "DS", "3", 0, 0},
2912     { 0x300A0084, "Beam Dose", "DS", "1", 0, 0},
2913     { 0x300A0086, "Beam Meterset", "DS", "1", 0, 0},
2914     { 0x300A0088, "Beam Dose Point Depth", "FL", "1", 0, 0},
2915     { 0x300A0089, "Beam Dose Point Equivalent Depth", "FL", "1", 0, 0},
2916     { 0x300A008A, "Beam Dose Point SSD", "FL", "1", 0, 0},
2917     { 0x300A00A0, "Number of Brachy Application Setups", "IS", "1", 0, 0},
2918     { 0x300A00A2, "Brachy Application Setup Dose Specification Point", "DS", "3", 0, 0},
2919     { 0x300A00A4, "Brachy Application Setup Dose", "DS", "1", 0, 0},
2920     { 0x300A00B0, "Beam Sequence", "SQ", "1", 0, 0},
2921     { 0x300A00B2, "Treatment Machine Name", "SH", "1", 0, -1},
2922     { 0x300A00B3, "Primary Dosimeter Unit", "CS", "1", 0, 0},
2923     { 0x300A00B4, "Source-Axis Distance", "DS", "1", 0, 0},
2924     { 0x300A00B6, "Beam Limiting Device Sequence", "SQ", "1", 0, 0},
2925     { 0x300A00B8, "RT Beam Limiting Device Type", "CS", "1", 0, -1},
2926     { 0x300A00BA, "Source to Beam Limiting Device Distance", "DS", "1", 0, 0},
2927     { 0x300A00BB, "Isocenter to Beam Limiting Device Distance", "FL", "1", 0, 0},
2928     { 0x300A00BC, "Number of Leaf/Jaw Pairs", "IS", "1", 0, 0},
2929     { 0x300A00BE, "Leaf Position Boundaries", "DS", "3-n", 0, 0},
2930     { 0x300A00C0, "Beam Number", "IS", "1", 0, -1},
2931     { 0x300A00C2, "Beam Name", "LO", "1", 0, -1},
2932     { 0x300A00C3, "Beam Description", "ST", "1", 0, 0},
2933     { 0x300A00C4, "Beam Type", "CS", "1", 0, -1},
2934     { 0x300A00C6, "Radiation Type", "CS", "1", 0, -1},
2935     { 0x300A00C7, "High-Dose Technique Type", "CS", "1", 0, 0},
2936     { 0x300A00C8, "Reference Image Number", "IS", "1", 0, 0},
2937     { 0x300A00CA, "Planned Verification Image Sequence", "SQ", "1", 0, 0},
2938     { 0x300A00CC, "Imaging Device-Specific Acquisition Parameters", "LO", "1-n", 0, 0},
2939     { 0x300A00CE, "Treatment Delivery Type", "CS", "1", 0, 0},
2940     { 0x300A00D0, "Number of Wedges", "IS", "1", 0, 0},
2941     { 0x300A00D1, "Wedge Sequence", "SQ", "1", 0, 0},
2942     { 0x300A00D2, "Wedge Number", "IS", "1", 0, 0},
2943     { 0x300A00D3, "Wedge Type", "CS", "1", 0, -1},
2944     { 0x300A00D4, "Wedge ID", "SH", "1", 0, -1},
2945     { 0x300A00D5, "Wedge Angle", "IS", "1", 0, -1},
2946     { 0x300A00D6, "Wedge Factor", "DS", "1", 0, 0},
2947     { 0x300A00D7, "Total Wedge Tray Water-Equivalent Thickness", "FL", "1", 0, 0},
2948     { 0x300A00D8, "Wedge Orientation", "DS", "1", 0, 0},
2949     { 0x300A00D9, "Isocenter to Wedge Tray Distance", "FL", "1", 0, 0},
2950     { 0x300A00DA, "Source to Wedge Tray Distance", "DS", "1", 0, 0},
2951     { 0x300A00DB, "Wedge Thin Edge Position", "FL", "1", 0, 0},
2952     { 0x300A00DC, "Bolus ID", "SH", "1", 0, 0},
2953     { 0x300A00DD, "Bolus Description", "ST", "1", 0, 0},
2954     { 0x300A00E0, "Number of Compensators", "IS", "1", 0, 0},
2955     { 0x300A00E1, "Material ID", "SH", "1", 0, -1},
2956     { 0x300A00E2, "Total Compensator Tray Factor", "DS", "1", 0, 0},
2957     { 0x300A00E3, "Compensator Sequence", "SQ", "1", 0, 0},
2958     { 0x300A00E4, "Compensator Number", "IS", "1", 0, 0},
2959     { 0x300A00E5, "Compensator ID", "SH", "1", 0, 0},
2960     { 0x300A00E6, "Source to Compensator Tray Distance", "DS", "1", 0, 0},
2961     { 0x300A00E7, "Compensator Rows", "IS", "1", 0, 0},
2962     { 0x300A00E8, "Compensator Columns", "IS", "1", 0, 0},
2963     { 0x300A00E9, "Compensator Pixel Spacing", "DS", "2", 0, 0},
2964     { 0x300A00EA, "Compensator Position", "DS", "2", 0, 0},
2965     { 0x300A00EB, "Compensator Transmission Data", "DS", "1-n", 0, 0},
2966     { 0x300A00EC, "Compensator Thickness Data", "DS", "1-n", 0, 0},
2967     { 0x300A00ED, "Number of Boli", "IS", "1", 0, 0},
2968     { 0x300A00EE, "Compensator Type", "CS", "1", 0, 0},
2969     { 0x300A00F0, "Number of Blocks", "IS", "1", 0, 0},
2970     { 0x300A00F2, "Total Block Tray Factor", "DS", "1", 0, 0},
2971     { 0x300A00F3, "Total Block Tray Water-Equivalent Thickness", "FL", "1", 0, 0},
2972     { 0x300A00F4, "Block Sequence", "SQ", "1", 0, 0},
2973     { 0x300A00F5, "Block Tray ID", "SH", "1", 0, -1},
2974     { 0x300A00F6, "Source to Block Tray Distance", "DS", "1", 0, 0},
2975     { 0x300A00F7, "Isocenter to Block Tray Distance", "FL", "1", 0, 0},
2976     { 0x300A00F8, "Block Type", "CS", "1", 0, 0},
2977     { 0x300A00F9, "Accessory Code", "LO", "1", 0, 0},
2978     { 0x300A00FA, "Block Divergence", "CS", "1", 0, 0},
2979     { 0x300A00FB, "Block Mounting Position", "CS", "1", 0, 0},
2980     { 0x300A00FC, "Block Number", "IS", "1", 0, 0},
2981     { 0x300A00FE, "Block Name", "LO", "1", 0, -1},
2982     { 0x300A0100, "Block Thickness", "DS", "1", 0, 0},
2983     { 0x300A0102, "Block Transmission", "DS", "1", 0, 0},
2984     { 0x300A0104, "Block Number of Points", "IS", "1", 0, 0},
2985     { 0x300A0106, "Block Data", "DS", "2-2n", 0, 0},
2986     { 0x300A0107, "Applicator Sequence", "SQ", "1", 0, 0},
2987     { 0x300A0108, "Applicator ID", "SH", "1", 0, -1},
2988     { 0x300A0109, "Applicator Type", "CS", "1", 0, -1},
2989     { 0x300A010A, "Applicator Description", "LO", "1", 0, 0},
2990     { 0x300A010C, "Cumulative Dose Reference Coefficient", "DS", "1", 0, 0},
2991     { 0x300A010E, "Final Cumulative Meterset Weight", "DS", "1", 0, 0},
2992     { 0x300A0110, "Number of Control Points", "IS", "1", 0, 0},
2993     { 0x300A0111, "Control Point Sequence", "SQ", "1", 0, 0},
2994     { 0x300A0112, "Control Point Index", "IS", "1", 0, -1},
2995     { 0x300A0114, "Nominal Beam Energy", "DS", "1", 0, -1},
2996     { 0x300A0115, "Dose Rate Set", "DS", "1", 0, 0},
2997     { 0x300A0116, "Wedge Position Sequence", "SQ", "1", 0, 0},
2998     { 0x300A0118, "Wedge Position", "CS", "1", 0, 0},
2999     { 0x300A011A, "Beam Limiting Device Position Sequence", "SQ", "1", 0, 0},
3000     { 0x300A011C, "Leaf/Jaw Positions", "DS", "2-2n", 0, 0},
3001     { 0x300A011E, "Gantry Angle", "DS", "1", 0, 0},
3002     { 0x300A011F, "Gantry Rotation Direction", "CS", "1", 0, 0},
3003     { 0x300A0120, "Beam Limiting Device Angle", "DS", "1", 0, 0},
3004     { 0x300A0121, "Beam Limiting Device Rotation Direction", "CS", "1", 0, 0},
3005     { 0x300A0122, "Patient Support Angle", "DS", "1", 0, 0},
3006     { 0x300A0123, "Patient Support Rotation Direction", "CS", "1", 0, 0},
3007     { 0x300A0124, "Table Top Eccentric Axis Distance", "DS", "1", 0, 0},
3008     { 0x300A0125, "Table Top Eccentric Angle", "DS", "1", 0, 0},
3009     { 0x300A0126, "Table Top Eccentric Rotation Direction", "CS", "1", 0, 0},
3010     { 0x300A0128, "Table Top Vertical Position", "DS", "1", 0, 0},
3011     { 0x300A0129, "Table Top Longitudinal Position", "DS", "1", 0, 0},
3012     { 0x300A012A, "Table Top Lateral Position", "DS", "1", 0, 0},
3013     { 0x300A012C, "Isocenter Position", "DS", "3", 0, 0},
3014     { 0x300A012E, "Surface Entry Point", "DS", "3", 0, 0},
3015     { 0x300A0130, "Source to Surface Distance", "DS", "1", 0, 0},
3016     { 0x300A0134, "Cumulative Meterset Weight", "DS", "1", 0, -1},
3017     { 0x300A0140, "Table Top Pitch Angle", "FL", "1", 0, 0},
3018     { 0x300A0142, "Table Top Pitch Rotation Direction", "CS", "1", 0, 0},
3019     { 0x300A0144, "Table Top Roll Angle", "FL", "1", 0, 0},
3020     { 0x300A0146, "Table Top Roll Rotation Direction", "CS", "1", 0, 0},
3021     { 0x300A0148, "Head Fixation Angle", "FL", "1", 0, 0},
3022     { 0x300A014A, "Gantry Pitch Angle", "FL", "1", 0, 0},
3023     { 0x300A014C, "Gantry Pitch Rotation Direction", "CS", "1", 0, 0},
3024     { 0x300A014E, "Gantry Pitch Angle Tolerance", "FL", "1", 0, 0},
3025     { 0x300A0180, "Patient Setup Sequence", "SQ", "1", 0, 0},
3026     { 0x300A0182, "Patient Setup Number", "IS", "1", 0, -1},
3027     { 0x300A0183, "Patient Setup Label", "LO", "1", 0, 0},
3028     { 0x300A0184, "Patient Additional Position", "LO", "1", 0, 0},
3029     { 0x300A0190, "Fixation Device Sequence", "SQ", "1", 0, 0},
3030     { 0x300A0192, "Fixation Device Type", "CS", "1", 0, 0},
3031     { 0x300A0194, "Fixation Device Label", "SH", "1", 0, 0},
3032     { 0x300A0196, "Fixation Device Description", "ST", "1", 0, 0},
3033     { 0x300A0198, "Fixation Device Position", "SH", "1", 0, 0},
3034     { 0x300A0199, "Fixation Device Pitch Angle", "FL", "1", 0, 0},
3035     { 0x300A019A, "Fixation Device Roll Angle", "FL", "1", 0, 0},
3036     { 0x300A01A0, "Shielding Device Sequence", "SQ", "1", 0, 0},
3037     { 0x300A01A2, "Shielding Device Type", "CS", "1", 0, 0},
3038     { 0x300A01A4, "Shielding Device Label", "SH", "1", 0, 0},
3039     { 0x300A01A6, "Shielding Device Description", "ST", "1", 0, 0},
3040     { 0x300A01A8, "Shielding Device Position", "SH", "1", 0, 0},
3041     { 0x300A01B0, "Setup Technique", "CS", "1", 0, 0},
3042     { 0x300A01B2, "Setup Technique Description", "ST", "1", 0, 0},
3043     { 0x300A01B4, "Setup Device Sequence", "SQ", "1", 0, 0},
3044     { 0x300A01B6, "Setup Device Type", "CS", "1", 0, 0},
3045     { 0x300A01B8, "Setup Device Label", "SH", "1", 0, 0},
3046     { 0x300A01BA, "Setup Device Description", "ST", "1", 0, 0},
3047     { 0x300A01BC, "Setup Device Parameter", "DS", "1", 0, 0},
3048     { 0x300A01D0, "Setup Reference Description", "ST", "1", 0, 0},
3049     { 0x300A01D2, "Table Top Vertical Setup Displacement", "DS", "1", 0, 0},
3050     { 0x300A01D4, "Table Top Longitudinal Setup Displacement", "DS", "1", 0, 0},
3051     { 0x300A01D6, "Table Top Lateral Setup Displacement", "DS", "1", 0, 0},
3052     { 0x300A0200, "Brachy Treatment Technique", "CS", "1", 0, 0},
3053     { 0x300A0202, "Brachy Treatment Type", "CS", "1", 0, 0},
3054     { 0x300A0206, "Treatment Machine Sequence", "SQ", "1", 0, 0},
3055     { 0x300A0210, "Source Sequence", "SQ", "1", 0, 0},
3056     { 0x300A0212, "Source Number", "IS", "1", 0, 0},
3057     { 0x300A0214, "Source Type", "CS", "1", 0, 0},
3058     { 0x300A0216, "Source Manufacturer", "LO", "1", 0, 0},
3059     { 0x300A0218, "Active Source Diameter", "DS", "1", 0, 0},
3060     { 0x300A021A, "Active Source Length", "DS", "1", 0, 0},
3061     { 0x300A0222, "Source Encapsulation Nominal Thickness", "DS", "1", 0, 0},
3062     { 0x300A0224, "Source Encapsulation Nominal Transmission", "DS", "1", 0, 0},
3063     { 0x300A0226, "Source Isotope Name", "LO", "1", 0, 0},
3064     { 0x300A0228, "Source Isotope Half Life", "DS", "1", 0, 0},
3065     { 0x300A0229, "Source Strength Units", "CS", "1", 0, 0},
3066     { 0x300A022A, "Reference Air Kerma Rate", "DS", "1", 0, 0},
3067     { 0x300A022B, "Source Strength", "DS", "1", 0, 0},
3068     { 0x300A022C, "Source Strength Reference Date", "DA", "1", 0, 0},
3069     { 0x300A022E, "Source Strength Reference Time", "TM", "1", 0, 0},
3070     { 0x300A0230, "Application Setup Sequence", "SQ", "1", 0, 0},
3071     { 0x300A0232, "Application Setup Type", "CS", "1", 0, 0},
3072     { 0x300A0234, "Application Setup Number", "IS", "1", 0, 0},
3073     { 0x300A0236, "Application Setup Name", "LO", "1", 0, 0},
3074     { 0x300A0238, "Application Setup Manufacturer", "LO", "1", 0, 0},
3075     { 0x300A0240, "Template Number", "IS", "1", 0, 0},
3076     { 0x300A0242, "Template Type", "SH", "1", 0, 0},
3077     { 0x300A0244, "Template Name", "LO", "1", 0, 0},
3078     { 0x300A0250, "Total Reference Air Kerma", "DS", "1", 0, 0},
3079     { 0x300A0260, "Brachy Accessory Device Sequence", "SQ", "1", 0, 0},
3080     { 0x300A0262, "Brachy Accessory Device Number", "IS", "1", 0, 0},
3081     { 0x300A0263, "Brachy Accessory Device ID", "SH", "1", 0, 0},
3082     { 0x300A0264, "Brachy Accessory Device Type", "CS", "1", 0, 0},
3083     { 0x300A0266, "Brachy Accessory Device Name", "LO", "1", 0, 0},
3084     { 0x300A026A, "Brachy Accessory Device Nominal Thickness", "DS", "1", 0, 0},
3085     { 0x300A026C, "Brachy Accessory Device Nominal Transmission", "DS", "1", 0, 0},
3086     { 0x300A0280, "Channel Sequence", "SQ", "1", 0, 0},
3087     { 0x300A0282, "Channel Number", "IS", "1", 0, 0},
3088     { 0x300A0284, "Channel Length", "DS", "1", 0, 0},
3089     { 0x300A0286, "Channel Total Time", "DS", "1", 0, 0},
3090     { 0x300A0288, "Source Movement Type", "CS", "1", 0, 0},
3091     { 0x300A028A, "Number of Pulses", "IS", "1", 0, 0},
3092     { 0x300A028C, "Pulse Repetition Interval", "DS", "1", 0, 0},
3093     { 0x300A0290, "Source Applicator Number", "IS", "1", 0, 0},
3094     { 0x300A0291, "Source Applicator ID", "SH", "1", 0, 0},
3095     { 0x300A0292, "Source Applicator Type", "CS", "1", 0, 0},
3096     { 0x300A0294, "Source Applicator Name", "LO", "1", 0, 0},
3097     { 0x300A0296, "Source Applicator Length", "DS", "1", 0, 0},
3098     { 0x300A0298, "Source Applicator Manufacturer", "LO", "1", 0, 0},
3099     { 0x300A029C, "Source Applicator Wall Nominal Thickness", "DS", "1", 0, 0},
3100     { 0x300A029E, "Source Applicator Wall Nominal Transmission", "DS", "1", 0, 0},
3101     { 0x300A02A0, "Source Applicator Step Size", "DS", "1", 0, 0},
3102     { 0x300A02A2, "Transfer Tube Number", "IS", "1", 0, 0},
3103     { 0x300A02A4, "Transfer Tube Length", "DS", "1", 0, 0},
3104     { 0x300A02B0, "Channel Shield Sequence", "SQ", "1", 0, 0},
3105     { 0x300A02B2, "Channel Shield Number", "IS", "1", 0, 0},
3106     { 0x300A02B3, "Channel Shield ID", "SH", "1", 0, 0},
3107     { 0x300A02B4, "Channel Shield Name", "LO", "1", 0, 0},
3108     { 0x300A02B8, "Channel Shield Nominal Thickness", "DS", "1", 0, 0},
3109     { 0x300A02BA, "Channel Shield Nominal Transmission", "DS", "1", 0, 0},
3110     { 0x300A02C8, "Final Cumulative Time Weight", "DS", "1", 0, 0},
3111     { 0x300A02D0, "Brachy Control Point Sequence", "SQ", "1", 0, 0},
3112     { 0x300A02D2, "Control Point Relative Position", "DS", "1", 0, 0},
3113     { 0x300A02D4, "Control Point 3D Position", "DS", "3", 0, 0},
3114     { 0x300A02D6, "Cumulative Time Weight", "DS", "1", 0, 0},
3115     { 0x300A02E0, "Compensator Divergence", "CS", "1", 0, 0},
3116     { 0x300A02E1, "Compensator Mounting Position", "CS", "1", 0, 0},
3117     { 0x300A02E2, "Source to Compensator Distance", "DS", "1-n", 0, 0},
3118     { 0x300A02E3, "Total Compensator Tray Water-Equivalent Thickness", "FL", "1", 0, 0},
3119     { 0x300A02E4, "Isocenter to Compensator Tray Distance", "FL", "1", 0, 0},
3120     { 0x300A02E5, "Compensator Column Offset", "FL", "1", 0, 0},
3121     { 0x300A02E6, "Isocenter to Compensator Distances", "FL", "1-n", 0, 0},
3122     { 0x300A02E7, "Compensator Relative Stopping Power Ratio", "FL", "1", 0, 0},
3123     { 0x300A02E8, "Compensator Milling Tool Diameter", "FL", "1", 0, 0},
3124     { 0x300A02EA, "Ion Range Compensator Sequence", "SQ", "1", 0, 0},
3125     { 0x300A02EB, "Compensator Description", "LT", "1", 0, 0},
3126     { 0x300A0302, "Radiation Mass Number", "IS", "1", 0, 0},
3127     { 0x300A0304, "Radiation Atomic Number", "IS", "1", 0, 0},
3128     { 0x300A0306, "Radiation Charge State", "SS", "1", 0, 0},
3129     { 0x300A0308, "Scan Mode", "CS", "1", 0, 0},
3130     { 0x300A030A, "Virtual Source-Axis Distances", "FL", "2", 0, 0},
3131     { 0x300A030C, "Snout Sequence", "SQ", "1", 0, 0},
3132     { 0x300A030D, "Snout Position", "FL", "1", 0, 0},
3133     { 0x300A030F, "Snout ID", "SH", "1", 0, 0},
3134     { 0x300A0312, "Number of Range Shifters", "IS", "1", 0, 0},
3135     { 0x300A0314, "Range Shifter Sequence", "SQ", "1", 0, 0},
3136     { 0x300A0316, "Range Shifter Number", "IS", "1", 0, 0},
3137     { 0x300A0318, "Range Shifter ID", "SH", "1", 0, 0},
3138     { 0x300A0320, "Range Shifter Type", "CS", "1", 0, 0},
3139     { 0x300A0322, "Range Shifter Description", "LO", "1", 0, 0},
3140     { 0x300A0330, "Number of Lateral Spreading Devices", "IS", "1", 0, 0},
3141     { 0x300A0332, "Lateral Spreading Device Sequence", "SQ", "1", 0, 0},
3142     { 0x300A0334, "Lateral Spreading Device Number", "IS", "1", 0, 0},
3143     { 0x300A0336, "Lateral Spreading Device ID", "SH", "1", 0, 0},
3144     { 0x300A0338, "Lateral Spreading Device Type", "CS", "1", 0, 0},
3145     { 0x300A033A, "Lateral Spreading Device Description", "LO", "1", 0, 0},
3146     { 0x300A033C, "Lateral Spreading Device Water Equivalent Thickness", "FL", "1", 0, 0},
3147     { 0x300A0340, "Number of Range Modulators", "IS", "1", 0, 0},
3148     { 0x300A0342, "Range Modulator Sequence", "SQ", "1", 0, 0},
3149     { 0x300A0344, "Range Modulator Number", "IS", "1", 0, 0},
3150     { 0x300A0346, "Range Modulator ID", "SH", "1", 0, 0},
3151     { 0x300A0348, "Range Modulator Type", "CS", "1", 0, 0},
3152     { 0x300A034A, "Range Modulator Description", "LO", "1", 0, 0},
3153     { 0x300A034C, "Beam Current Modulation ID", "SH", "1", 0, 0},
3154     { 0x300A0350, "Patient Support Type", "CS", "1", 0, 0},
3155     { 0x300A0352, "Patient Support ID", "SH", "1", 0, 0},
3156     { 0x300A0354, "Patient Support Accessory Code", "LO", "1", 0, 0},
3157     { 0x300A0356, "Fixation Light Azimuthal Angle", "FL", "1", 0, 0},
3158     { 0x300A0358, "Fixation Light Polar Angle", "FL", "1", 0, 0},
3159     { 0x300A035A, "Meterset Rate", "FL", "1", 0, 0},
3160     { 0x300A0360, "Range Shifter Settings Sequence", "SQ", "1", 0, 0},
3161     { 0x300A0362, "Range Shifter Setting", "LO", "1", 0, 0},
3162     { 0x300A0364, "Isocenter to Range Shifter Distance", "FL", "1", 0, 0},
3163     { 0x300A0366, "Range Shifter Water Equivalent Thickness", "FL", "1", 0, 0},
3164     { 0x300A0370, "Lateral Spreading Device Settings Sequence", "SQ", "1", 0, 0},
3165     { 0x300A0372, "Lateral Spreading Device Setting", "LO", "1", 0, 0},
3166     { 0x300A0374, "Isocenter to Lateral Spreading Device Distance", "FL", "1", 0, 0},
3167     { 0x300A0380, "Range Modulator Settings Sequence", "SQ", "1", 0, 0},
3168     { 0x300A0382, "Range Modulator Gating Start Value", "FL", "1", 0, 0},
3169     { 0x300A0384, "Range Modulator Gating Stop Value", "FL", "1", 0, 0},
3170     { 0x300A0386, "Range Modulator Gating Start Water Equivalent Thickness", "FL", "1", 0, 0},
3171     { 0x300A0388, "Range Modulator Gating Stop Water Equivalent Thickness", "FL", "1", 0, 0},
3172     { 0x300A038A, "Isocenter to Range Modulator Distance", "FL", "1", 0, 0},
3173     { 0x300A0390, "Scan Spot Tune ID", "SH", "1", 0, 0},
3174     { 0x300A0392, "Number of Scan Spot Positions", "IS", "1", 0, 0},
3175     { 0x300A0394, "Scan Spot Position Map", "FL", "1-n", 0, 0},
3176     { 0x300A0396, "Scan Spot Meterset Weights", "FL", "1-n", 0, 0},
3177     { 0x300A0398, "Scanning Spot Size", "FL", "2", 0, 0},
3178     { 0x300A039A, "Number of Paintings", "IS", "1", 0, 0},
3179     { 0x300A03A0, "Ion Tolerance Table Sequence", "SQ", "1", 0, 0},
3180     { 0x300A03A2, "Ion Beam Sequence", "SQ", "1", 0, 0},
3181     { 0x300A03A4, "Ion Beam Limiting Device Sequence", "SQ", "1", 0, 0},
3182     { 0x300A03A6, "Ion Block Sequence", "SQ", "1", 0, 0},
3183     { 0x300A03A8, "Ion Control Point Sequence", "SQ", "1", 0, 0},
3184     { 0x300A03AA, "Ion Wedge Sequence", "SQ", "1", 0, 0},
3185     { 0x300A03AC, "Ion Wedge Position Sequence", "SQ", "1", 0, 0},
3186     { 0x300A0401, "Referenced Setup Image Sequence", "SQ", "1", 0, 0},
3187     { 0x300A0402, "Setup Image Comment", "ST", "1", 0, 0},
3188     { 0x300A0410, "Motion Synchronization Sequence", "SQ", "1", 0, 0},
3189     { 0x300A0412, "Control Point Orientation", "FL", "3", 0, 0},
3190     { 0x300A0420, "General Accessory Sequence", "SQ", "1", 0, 0},
3191     { 0x300A0421, "General Accessory ID", "CS", "1", 0, 0},
3192     { 0x300A0422, "General Accessory Description", "ST", "1", 0, 0},
3193     { 0x300A0423, "General Accessory Type", "SH", "1", 0, 0},
3194     { 0x300A0424, "General Accessory Number", "IS", "1", 0, 0},
3195     { 0x300C0002, "Referenced RT Plan Sequence", "SQ", "1", 0, 0},
3196     { 0x300C0004, "Referenced Beam Sequence", "SQ", "1", 0, 0},
3197     { 0x300C0006, "Referenced Beam Number", "IS", "1", 0, 0},
3198     { 0x300C0007, "Referenced Reference Image Number", "IS", "1", 0, 0},
3199     { 0x300C0008, "Start Cumulative Meterset Weight", "DS", "1", 0, 0},
3200     { 0x300C0009, "End Cumulative Meterset Weight", "DS", "1", 0, 0},
3201     { 0x300C000A, "Referenced Brachy Application Setup Sequence", "SQ", "1", 0, 0},
3202     { 0x300C000C, "Referenced Brachy Application Setup Number", "IS", "1", 0, 0},
3203     { 0x300C000E, "Referenced Source Number", "IS", "1", 0, 0},
3204     { 0x300C0020, "Referenced Fraction Group Sequence", "SQ", "1", 0, 0},
3205     { 0x300C0022, "Referenced Fraction Group Number", "IS", "1", 0, 0},
3206     { 0x300C0040, "Referenced Verification Image Sequence", "SQ", "1", 0, 0},
3207     { 0x300C0042, "Referenced Reference Image Sequence", "SQ", "1", 0, 0},
3208     { 0x300C0050, "Referenced Dose Reference Sequence", "SQ", "1", 0, 0},
3209     { 0x300C0051, "Referenced Dose Reference Number", "IS", "1", 0, 0},
3210     { 0x300C0055, "Brachy Referenced Dose Reference Sequence", "SQ", "1", 0, 0},
3211     { 0x300C0060, "Referenced Structure Set Sequence", "SQ", "1", 0, 0},
3212     { 0x300C006A, "Referenced Patient Setup Number", "IS", "1", 0, 0},
3213     { 0x300C0080, "Referenced Dose Sequence", "SQ", "1", 0, 0},
3214     { 0x300C00A0, "Referenced Tolerance Table Number", "IS", "1", 0, 0},
3215     { 0x300C00B0, "Referenced Bolus Sequence", "SQ", "1", 0, 0},
3216     { 0x300C00C0, "Referenced Wedge Number", "IS", "1", 0, 0},
3217     { 0x300C00D0, "Referenced Compensator Number", "IS", "1", 0, 0},
3218     { 0x300C00E0, "Referenced Block Number", "IS", "1", 0, 0},
3219     { 0x300C00F0, "Referenced Control Point Index", "IS", "1", 0, 0},
3220     { 0x300C00F2, "Referenced Control Point Sequence", "SQ", "1", 0, 0},
3221     { 0x300C00F4, "Referenced Start Control Point Index", "IS", "1", 0, 0},
3222     { 0x300C00F6, "Referenced Stop Control Point Index", "IS", "1", 0, 0},
3223     { 0x300C0100, "Referenced Range Shifter Number", "IS", "1", 0, 0},
3224     { 0x300C0102, "Referenced Lateral Spreading Device Number", "IS", "1", 0, 0},
3225     { 0x300C0104, "Referenced Range Modulator Number", "IS", "1", 0, 0},
3226     { 0x300E0002, "Approval Status", "CS", "1", 0, 0},
3227     { 0x300E0004, "Review Date", "DA", "1", 0, 0},
3228     { 0x300E0005, "Review Time", "TM", "1", 0, 0},
3229     { 0x300E0008, "Reviewer Name", "PN", "1", 0, 0},
3230     { 0x40000010, "Arbitrary", "LT", "1", -1, 0},
3231     { 0x40004000, "Text Comments", "LT", "1", -1, 0},
3232     { 0x40080040, "Results ID", "SH", "1", -1, 0},
3233     { 0x40080042, "Results ID Issuer", "LO", "1", -1, 0},
3234     { 0x40080050, "Referenced Interpretation Sequence", "SQ", "1", -1, 0},
3235     { 0x40080100, "Interpretation Recorded Date", "DA", "1", -1, 0},
3236     { 0x40080101, "Interpretation Recorded Time", "TM", "1", -1, 0},
3237     { 0x40080102, "Interpretation Recorder", "PN", "1", -1, 0},
3238     { 0x40080103, "Reference to Recorded Sound", "LO", "1", -1, 0},
3239     { 0x40080108, "Interpretation Transcription Date", "DA", "1", -1, 0},
3240     { 0x40080109, "Interpretation Transcription Time", "TM", "1", -1, 0},
3241     { 0x4008010A, "Interpretation Transcriber", "PN", "1", -1, 0},
3242     { 0x4008010B, "Interpretation Text", "ST", "1", -1, 0},
3243     { 0x4008010C, "Interpretation Author", "PN", "1", -1, 0},
3244     { 0x40080111, "Interpretation Approver Sequence", "SQ", "1", -1, 0},
3245     { 0x40080112, "Interpretation Approval Date", "DA", "1", -1, 0},
3246     { 0x40080113, "Interpretation Approval Time", "TM", "1", -1, 0},
3247     { 0x40080114, "Physician Approving Interpretation", "PN", "1", -1, 0},
3248     { 0x40080115, "Interpretation Diagnosis Description", "LT", "1", -1, 0},
3249     { 0x40080117, "Interpretation Diagnosis Code Sequence", "SQ", "1", -1, 0},
3250     { 0x40080118, "Results Distribution List Sequence", "SQ", "1", -1, 0},
3251     { 0x40080119, "Distribution Name", "PN", "1", -1, 0},
3252     { 0x4008011A, "Distribution Address", "LO", "1", -1, 0},
3253     { 0x40080200, "Interpretation ID", "SH", "1", -1, 0},
3254     { 0x40080202, "Interpretation ID Issuer", "LO", "1", -1, 0},
3255     { 0x40080210, "Interpretation Type ID", "CS", "1", -1, 0},
3256     { 0x40080212, "Interpretation Status ID", "CS", "1", -1, 0},
3257     { 0x40080300, "Impressions", "ST", "1", -1, 0},
3258     { 0x40084000, "Results Comments", "ST", "1", -1, 0},
3259     { 0x4FFE0001, "MAC Parameters Sequence", "SQ", "1", 0, 0},
3260     { 0x50000005, "Curve Dimensions", "US", "1", -1, 0},
3261     { 0x50000010, "Number of Points", "US", "1", -1, 0},
3262     { 0x50000020, "Type of Data", "CS", "1", -1, 0},
3263     { 0x50000022, "Curve Description", "LO", "1", -1, 0},
3264     { 0x50000030, "Axis Units", "SH", "1-n", -1, 0},
3265     { 0x50000040, "Axis Labels", "SH", "1-n", -1, 0},
3266     { 0x50000103, "Data Value Representation", "US", "1", -1, 0},
3267     { 0x50000104, "Minimum Coordinate Value", "US", "1-n", -1, 0},
3268     { 0x50000105, "Maximum Coordinate Value", "US", "1-n", -1, 0},
3269     { 0x50000106, "Curve Range", "SH", "1-n", -1, 0},
3270     { 0x50000110, "Curve Data Descriptor", "US", "1-n", -1, 0},
3271     { 0x50000112, "Coordinate Start Value", "US", "1-n", -1, 0},
3272     { 0x50000114, "Coordinate Step Value", "US", "1-n", -1, 0},
3273     { 0x50001001, "Curve Activation Layer", "CS", "1", -1, 0},
3274     { 0x50002000, "Audio Type", "US", "1", -1, 0},
3275     { 0x50002002, "Audio Sample Format", "US", "1", -1, 0},
3276     { 0x50002004, "Number of Channels", "US", "1", -1, 0},
3277     { 0x50002006, "Number of Samples", "UL", "1", -1, 0},
3278     { 0x50002008, "Sample Rate", "UL", "1", -1, 0},
3279     { 0x5000200A, "Total Time", "UL", "1", -1, 0},
3280     { 0x5000200C, "Audio Sample Data", "OW or OB", "1", -1, 0},
3281     { 0x5000200E, "Audio Comments", "LT", "1", -1, 0},
3282     { 0x50002500, "Curve Label", "LO", "1", -1, 0},
3283     { 0x50002600, "Curve Referenced Overlay Sequence", "SQ", "1", -1, 0},
3284     { 0x50002610, "Curve Referenced Overlay Group", "US", "1", -1, 0},
3285     { 0x50003000, "Curve Data", "OW or OB", "1", -1, 0},
3286     { 0x52009229, "Shared Functional Groups Sequence", "SQ", "1", 0, 0},
3287     { 0x52009230, "Per-frame Functional Groups Sequence", "SQ", "1", 0, 0},
3288     { 0x54000100, "Waveform Sequence", "SQ", "1", 0, 0},
3289     { 0x54000110, "Channel Minimum Value", "OB or OW", "1", 0, 0},
3290     { 0x54000112, "Channel Maximum Value", "OB or OW", "1", 0, 0},
3291     { 0x54001004, "Waveform Bits Allocated", "US", "1", 0, 0},
3292     { 0x54001006, "Waveform Sample Interpretation", "CS", "1", 0, 0},
3293     { 0x5400100A, "Waveform Padding Value", "OB or OW", "1", 0, 0},
3294     { 0x54001010, "Waveform Data", "OB or OW", "1", 0, 0},
3295     { 0x56000010, "First Order Phase Correction Angle", "OF", "1", 0, 0},
3296     { 0x56000020, "Spectroscopy Data", "OF", "1", 0, 0},
3297     { 0x60000010, "Overlay Rows", "US", "1", 0, 0},
3298     { 0x60000011, "Overlay Columns", "US", "1", 0, 0},
3299     { 0x60000012, "Overlay Planes", "US", "1", -1, 0},
3300     { 0x60000015, "Number of Frames in Overlay", "IS", "1", 0, 0},
3301     { 0x60000022, "Overlay Description", "LO", "1", 0, 0},
3302     { 0x60000040, "Overlay Type", "CS", "1", 0, 0},
3303     { 0x60000045, "Overlay Subtype", "LO", "1", 0, 0},
3304     { 0x60000050, "Overlay Origin", "SS", "2", 0, 0},
3305     { 0x60000051, "Image Frame Origin", "US", "1", 0, 0},
3306     { 0x60000052, "Overlay Plane Origin", "US", "1", -1, 0},
3307     { 0x60000060, "Overlay Compression Code", "CS", "1", -1, 0},
3308     { 0x60000061, "Overlay Compression Originator", "SH", "1", -1, 0},
3309     { 0x60000062, "Overlay Compression Label", "SH", "1", -1, 0},
3310     { 0x60000063, "Overlay Compression Description", "CS", "1", -1, 0},
3311     { 0x60000066, "Overlay Compression Step Pointers", "AT", "1-n", -1, 0},
3312     { 0x60000068, "Overlay Repeat Interval", "US", "1", -1, 0},
3313     { 0x60000069, "Overlay Bits Grouped", "US", "1", -1, 0},
3314     { 0x60000100, "Overlay Bits Allocated", "US", "1", 0, 0},
3315     { 0x60000102, "Overlay Bit Position", "US", "1", 0, 0},
3316     { 0x60000110, "Overlay Format", "CS", "1", -1, 0},
3317     { 0x60000200, "Overlay Location", "US", "1", -1, 0},
3318     { 0x60000800, "Overlay Code Label", "CS", "1-n", -1, 0},
3319     { 0x60000802, "Overlay Number of Tables", "US", "1", -1, 0},
3320     { 0x60000803, "Overlay Code Table Location", "AT", "1-n", -1, 0},
3321     { 0x60000804, "Overlay Bits For Code Word", "US", "1", -1, 0},
3322     { 0x60001001, "Overlay Activation Layer", "CS", "1", 0, 0},
3323     { 0x60001100, "Overlay Descriptor - Gray", "US", "1", -1, 0},
3324     { 0x60001101, "Overlay Descriptor - Red", "US", "1", -1, 0},
3325     { 0x60001102, "Overlay Descriptor - Green", "US", "1", -1, 0},
3326     { 0x60001103, "Overlay Descriptor - Blue", "US", "1", -1, 0},
3327     { 0x60001200, "Overlays- Gray", "US", "1-n", -1, 0},
3328     { 0x60001201, "Overlays - Red", "US", "1-n", -1, 0},
3329     { 0x60001202, "Overlays - Green", "US", "1-n", -1, 0},
3330     { 0x60001203, "Overlays- Blue", "US", "1-n", -1, 0},
3331     { 0x60001301, "ROI Area", "IS", "1", 0, 0},
3332     { 0x60001302, "ROI Mean", "DS", "1", 0, 0},
3333     { 0x60001303, "ROI Standard Deviation", "DS", "1", 0, 0},
3334     { 0x60001500, "Overlay Label", "LO", "1", 0, 0},
3335     { 0x60003000, "Overlay Data", "OB or OW", "1", 0, 0},
3336     { 0x60004000, "Overlay Comments", "LT", "1", -1, 0},
3337     { 0x7FE00010, "Pixel Data", "OW or OB", "1", 0, 0},
3338     { 0x7FE00020, "Coefficients SDVN", "OW", "1", -1, 0},
3339     { 0x7FE00030, "Coefficients SDHN", "OW", "1", -1, 0},
3340     { 0x7FE00040, "Coefficients SDDN", "OW", "1", -1, 0},
3341     { 0x7F000010, "Variable Pixel Data", "OW or OB", "1", -1, 0},
3342     { 0x7F000011, "Variable Next Data Group", "US", "1", -1, 0},
3343     { 0x7F000020, "Variable Coefficients SDVN", "OW", "1", -1, 0},
3344     { 0x7F000030, "Variable Coefficients SDHN", "OW", "1", -1, 0},
3345     { 0x7F000040, "Variable Coefficients SDDN", "OW", "1", -1, 0},
3346     { 0xFFFAFFFA, "Digital Signatures Sequence", "SQ", "1", 0, 0},
3347     { 0xFFFCFFFC, "Data Set Trailing Padding", "OB", "1", 0, 0},
3348     { 0xFFFEE000, "Item", "see note", "1", 0, 0},
3349     { 0xFFFEE00D, "Item Delimitation Item", "see note", "1", 0, 0},
3350     { 0xFFFEE0DD, "Sequence Delimitation Item", "see note", "1", 0, 0},
3351     { 0x00020000, "File Meta Information Group Length", "UL", "1", 0, 0},
3352     { 0x00020001, "File Meta Information Version", "OB", "1", 0, 0},
3353     { 0x00020002, "Media Storage SOP Class UID", "UI", "1", 0, 0},
3354     { 0x00020003, "Media Storage SOP Instance UID", "UI", "1", 0, 0},
3355     { 0x00020010, "Transfer Syntax UID", "UI", "1", 0, 0},
3356     { 0x00020012, "Implementation Class UID", "UI", "1", 0, 0},
3357     { 0x00020013, "Implementation Version Name", "SH", "1", 0, 0},
3358     { 0x00020016, "Source Application Entity Title", "AE", "1", 0, 0},
3359     { 0x00020100, "Private Information Creator UID", "UI", "1", 0, 0},
3360     { 0x00020102, "Private Information", "OB", "1", 0, 0},
3361     { 0x00041130, "File-set ID", "CS", "1", 0, 0},
3362     { 0x00041141, "File-set Descriptor File ID", "CS", "1-8", 0, 0},
3363     { 0x00041142, "Specific Character Set of File-set Descriptor File", "CS", "1", 0, 0},
3364     { 0x00041200, "Offset of the First Directory Record of the Root Directory Entity", "UL", "1", 0, 0},
3365     { 0x00041202, "Offset of the Last Directory Record of the Root Directory Entity", "UL", "1", 0, 0},
3366     { 0x00041212, "File-set Consistency Flag", "US", "1", 0, 0},
3367     { 0x00041220, "Directory Record Sequence", "SQ", "1", 0, 0},
3368     { 0x00041400, "Offset of the Next Directory Record", "UL", "1", 0, 0},
3369     { 0x00041410, "Record In-use Flag", "US", "1", 0, 0},
3370     { 0x00041420, "Offset of Referenced Lower-Level Directory Entity", "UL", "1", 0, 0},
3371     { 0x00041430, "Directory Record Type", "CS", "1", 0, 0},
3372     { 0x00041432, "Private Record UID", "UI", "1", 0, 0},
3373     { 0x00041500, "Referenced File ID", "CS", "1-8", 0, 0},
3374     { 0x00041504, "MRDR Directory Record Offset", "UL", "1", -1, 0},
3375     { 0x00041510, "Referenced SOP Class UID in File", "UI", "1", 0, 0},
3376     { 0x00041511, "Referenced SOP Instance UID in File", "UI", "1", 0, 0},
3377     { 0x00041512, "Referenced Transfer Syntax UID in File", "UI", "1", 0, 0},
3378     { 0x0004151A, "Referenced Related General SOP Class UID in File", "UI", "1-n", 0, 0},
3379     { 0x00041600, "Number of References", "UL", "1", -1, 0},
3380 };
3381
3382 /* ---------------------------------------------------------------------
3383  * DICOM UID Definitions
3384
3385  * Part 6 lists following different UID Types (2006-2008)
3386
3387  * Application Context Name
3388  * Coding Scheme
3389  * DICOM UIDs as a Coding Scheme
3390  * LDAP OID
3391  * Meta SOP Class
3392  * SOP Class
3393  * Service Class
3394  * Transfer Syntax
3395  * Well-known Print Queue SOP Instance
3396  * Well-known Printer SOP Instance
3397  * Well-known SOP Instance
3398  * Well-known frame of reference
3399  */
3400
3401 typedef struct dcm_uid {
3402     const gchar *value;
3403     const gchar *name;
3404     const gchar *type;
3405 } dcm_uid_t;
3406
3407 static dcm_uid_t dcm_uid_data[] = {
3408     { "1.2.840.10008.1.1", "Verification SOP Class", "SOP Class"},
3409     { "1.2.840.10008.1.2", "Implicit VR Little Endian", "Transfer Syntax"},
3410     { "1.2.840.10008.1.2.1", "Explicit VR Little Endian", "Transfer Syntax"},
3411     { "1.2.840.10008.1.2.1.99", "Deflated Explicit VR Little Endian", "Transfer Syntax"},
3412     { "1.2.840.10008.1.2.2", "Explicit VR Big Endian", "Transfer Syntax"},
3413     { "1.2.840.10008.1.2.4.50", "JPEG Baseline (Process 1): Default Transfer Syntax for Lossy JPEG 8 Bit Image Compression", "Transfer Syntax"},
3414     { "1.2.840.10008.1.2.4.51", "JPEG Extended (Process 2 & 4): Default Transfer Syntax for Lossy JPEG 12 Bit Image Compression (Process 4 only)", "Transfer Syntax"},
3415     { "1.2.840.10008.1.2.4.52", "JPEG Extended (Process 3 & 5) (Retired)", "Transfer Syntax"},
3416     { "1.2.840.10008.1.2.4.53", "JPEG Spectral Selection, Non-Hierarchical (Process 6 & 8) (Retired)", "Transfer Syntax"},
3417     { "1.2.840.10008.1.2.4.54", "JPEG Spectral Selection, Non-Hierarchical (Process 7 & 9) (Retired)", "Transfer Syntax"},
3418     { "1.2.840.10008.1.2.4.55", "JPEG Full Progression, Non-Hierarchical (Process 10 & 12) (Retired)", "Transfer Syntax"},
3419     { "1.2.840.10008.1.2.4.56", "JPEG Full Progression, Non-Hierarchical (Process 11 & 13) (Retired)", "Transfer Syntax"},
3420     { "1.2.840.10008.1.2.4.57", "JPEG Lossless, Non-Hierarchical (Process 14)", "Transfer Syntax"},
3421     { "1.2.840.10008.1.2.4.58", "JPEG Lossless, Non-Hierarchical (Process 15) (Retired)", "Transfer Syntax"},
3422     { "1.2.840.10008.1.2.4.59", "JPEG Extended, Hierarchical (Process 16 & 18) (Retired)", "Transfer Syntax"},
3423     { "1.2.840.10008.1.2.4.60", "JPEG Extended, Hierarchical (Process 17 & 19) (Retired)", "Transfer Syntax"},
3424     { "1.2.840.10008.1.2.4.61", "JPEG Spectral Selection, Hierarchical (Process 20 & 22) (Retired)", "Transfer Syntax"},
3425     { "1.2.840.10008.1.2.4.62", "JPEG Spectral Selection, Hierarchical (Process 21 & 23) (Retired)", "Transfer Syntax"},
3426     { "1.2.840.10008.1.2.4.63", "JPEG Full Progression, Hierarchical (Process 24 & 26) (Retired)", "Transfer Syntax"},
3427     { "1.2.840.10008.1.2.4.64", "JPEG Full Progression, Hierarchical (Process 25 & 27) (Retired)", "Transfer Syntax"},
3428     { "1.2.840.10008.1.2.4.65", "JPEG Lossless, Hierarchical (Process 28) (Retired)", "Transfer Syntax"},
3429     { "1.2.840.10008.1.2.4.66", "JPEG Lossless, Hierarchical (Process 29) (Retired)", "Transfer Syntax"},
3430     { "1.2.840.10008.1.2.4.70", "JPEG Lossless, Non-Hierarchical, First-Order Prediction (Process 14 [Selection Value 1]): Default Transfer Syntax for Lossless JPEG Image Compression", "Transfer Syntax"},
3431     { "1.2.840.10008.1.2.4.80", "JPEG-LS Lossless Image Compression", "Transfer Syntax"},
3432     { "1.2.840.10008.1.2.4.81", "JPEG-LS Lossy (Near-Lossless) Image Compression", "Transfer Syntax"},
3433     { "1.2.840.10008.1.2.4.90", "JPEG 2000 Image Compression (Lossless Only)", "Transfer Syntax"},
3434     { "1.2.840.10008.1.2.4.91", "JPEG 2000 Image Compression", "Transfer Syntax"},
3435     { "1.2.840.10008.1.2.4.92", "JPEG 2000 Part 2 Multi-component Image Compression (Lossless Only)", "Transfer Syntax"},
3436     { "1.2.840.10008.1.2.4.93", "JPEG 2000 Part 2 Multi-component Image Compression", "Transfer Syntax"},
3437     { "1.2.840.10008.1.2.4.94", "JPIP Referenced", "Transfer Syntax"},
3438     { "1.2.840.10008.1.2.4.95", "JPIP Referenced Deflate", "Transfer Syntax"},
3439     { "1.2.840.10008.1.2.4.100", "MPEG2 Main Profile @ Main Level", "Transfer Syntax"},
3440     { "1.2.840.10008.1.2.5", "RLE Lossless", "Transfer Syntax"},
3441     { "1.2.840.10008.1.2.6.1", "RFC 2557 MIME encapsulation", "Transfer Syntax"},
3442     { "1.2.840.10008.1.2.6.2", "XML Encoding", "Transfer Syntax"},
3443     { "1.2.840.10008.1.3.10", "Media Storage Directory Storage", "SOP Class"},
3444     { "1.2.840.10008.1.4.1.1", "Talairach Brain Atlas Frame of Reference", "Well-known frame of reference"},
3445     { "1.2.840.10008.1.4.1.2", "SPM2 T1 Frame of Reference", "Well-known frame of reference"},
3446     { "1.2.840.10008.1.4.1.3", "SPM2 T2 Frame of Reference", "Well-known frame of reference"},
3447     { "1.2.840.10008.1.4.1.4", "SPM2 PD Frame of Reference", "Well-known frame of reference"},
3448     { "1.2.840.10008.1.4.1.5", "SPM2 EPI Frame of Reference", "Well-known frame of reference"},
3449     { "1.2.840.10008.1.4.1.6", "SPM2 FIL T1 Frame of Reference", "Well-known frame of reference"},
3450     { "1.2.840.10008.1.4.1.7", "SPM2 PET Frame of Reference", "Well-known frame of reference"},
3451     { "1.2.840.10008.1.4.1.8", "SPM2 TRANSM Frame of Reference", "Well-known frame of reference"},
3452     { "1.2.840.10008.1.4.1.9", "SPM2 SPECT Frame of Reference", "Well-known frame of reference"},
3453     { "1.2.840.10008.1.4.1.10", "SPM2 GRAY Frame of Reference", "Well-known frame of reference"},
3454     { "1.2.840.10008.1.4.1.11", "SPM2 WHITE Frame of Reference", "Well-known frame of reference"},
3455     { "1.2.840.10008.1.4.1.12", "SPM2 CSF Frame of Reference", "Well-known frame of reference"},
3456     { "1.2.840.10008.1.4.1.13", "SPM2 BRAINMASK Frame of Reference", "Well-known frame of reference"},
3457     { "1.2.840.10008.1.4.1.14", "SPM2 AVG305T1 Frame of Reference", "Well-known frame of reference"},
3458     { "1.2.840.10008.1.4.1.15", "SPM2 AVG152T1 Frame of Reference", "Well-known frame of reference"},
3459     { "1.2.840.10008.1.4.1.16", "SPM2 AVG152T2 Frame of Reference", "Well-known frame of reference"},
3460     { "1.2.840.10008.1.4.1.17", "SPM2 AVG152PD Frame of Reference", "Well-known frame of reference"},
3461     { "1.2.840.10008.1.4.1.18", "SPM2 SINGLESUBJT1 Frame of Reference", "Well-known frame of reference"},
3462     { "1.2.840.10008.1.4.2.1", "ICBM 452 T1 Frame of Reference", "Well-known frame of reference"},
3463     { "1.2.840.10008.1.4.2.2", "ICBM Single Subject MRI Frame of Reference", "Well-known frame of reference"},
3464     { "1.2.840.10008.1.9", "Basic Study Content Notification SOP Class (Retired)", "SOP Class"},
3465     { "1.2.840.10008.1.20.1", "Storage Commitment Push Model SOP Class", "SOP Class"},
3466     { "1.2.840.10008.1.20.1.1", "Storage Commitment Push Model SOP Instance", "Well-known SOP Instance"},
3467     { "1.2.840.10008.1.20.2", "Storage Commitment Pull Model SOP Class (Retired)", "SOP Class"},
3468     { "1.2.840.10008.1.20.2.1", "Storage Commitment Pull Model SOP Instance (Retired)", "Well-known SOP Instance"},
3469     { "1.2.840.10008.1.40", "Procedural Event Logging SOP Class", "SOP Class"},
3470     { "1.2.840.10008.1.40.1", "Procedural Event Logging SOP Instance", "Well-known SOP Instance"},
3471     { "1.2.840.10008.1.42", "Substance Administration Logging SOP Class", "SOP Class"},
3472     { "1.2.840.10008.1.42.1", "Substance Administration Logging SOP Instance", "Well-known SOP Instance"},
3473     { "1.2.840.10008.2.6.1", "DICOM UID Registry", "DICOM UIDs as a Coding Scheme"},
3474     { "1.2.840.10008.2.16.4", "DICOM Controlled Terminology", "Coding Scheme"},
3475     { "1.2.840.10008.3.1.1.1", "DICOM Application Context Name", "Application Context Name"},
3476     { "1.2.840.10008.3.1.2.1.1", "Detached Patient Management SOP Class (Retired)", "SOP Class"},
3477     { "1.2.840.10008.3.1.2.1.4", "Detached Patient Management Meta SOP Class (Retired)", "Meta SOP Class"},
3478     { "1.2.840.10008.3.1.2.2.1", "Detached Visit Management SOP Class (Retired)", "SOP Class"},
3479     { "1.2.840.10008.3.1.2.3.1", "Detached Study Management SOP Class (Retired)", "SOP Class"},
3480     { "1.2.840.10008.3.1.2.3.2", "Study Component Management SOP Class (Retired)", "SOP Class"},
3481     { "1.2.840.10008.3.1.2.3.3", "Modality Performed Procedure Step SOP Class", "SOP Class"},
3482     { "1.2.840.10008.3.1.2.3.4", "Modality Performed Procedure Step Retrieve SOP Class", "SOP Class"},
3483     { "1.2.840.10008.3.1.2.3.5", "Modality Performed Procedure Step Notification SOP Class", "SOP Class"},
3484     { "1.2.840.10008.3.1.2.5.1", "Detached Results Management SOP Class (Retired)", "SOP Class"},
3485     { "1.2.840.10008.3.1.2.5.4", "Detached Results Management Meta SOP Class (Retired)", "Meta SOP Class"},
3486     { "1.2.840.10008.3.1.2.5.5", "Detached Study Management Meta SOP Class (Retired)", "Meta SOP Class"},
3487     { "1.2.840.10008.3.1.2.6.1", "Detached Interpretation Management SOP Class (Retired)", "SOP Class"},
3488     { "1.2.840.10008.4.2", "Storage Service Class", "Service Class"},
3489     { "1.2.840.10008.5.1.1.1", "Basic Film Session SOP Class", "SOP Class"},
3490     { "1.2.840.10008.5.1.1.2", "Basic Film Box SOP Class", "SOP Class"},
3491     { "1.2.840.10008.5.1.1.4", "Basic Grayscale Image Box SOP Class", "SOP Class"},
3492     { "1.2.840.10008.5.1.1.4.1", "Basic Color Image Box SOP Class", "SOP Class"},
3493     { "1.2.840.10008.5.1.1.4.2", "Referenced Image Box SOP Class (Retired)", "SOP Class"},
3494     { "1.2.840.10008.5.1.1.9", "Basic Grayscale Print Management Meta SOP Class", "Meta SOP Class"},
3495     { "1.2.840.10008.5.1.1.9.1", "Referenced Grayscale Print Management Meta SOP Class (Retired)", "Meta SOP Class"},
3496     { "1.2.840.10008.5.1.1.14", "Print Job SOP Class", "SOP Class"},
3497     { "1.2.840.10008.5.1.1.15", "Basic Annotation Box SOP Class", "SOP Class"},
3498     { "1.2.840.10008.5.1.1.16", "Printer SOP Class", "SOP Class"},
3499     { "1.2.840.10008.5.1.1.16.376", "Printer Configuration Retrieval SOP Class", "SOP Class"},
3500     { "1.2.840.10008.5.1.1.17", "Printer SOP Instance", "Well-known Printer SOP Instance"},
3501     { "1.2.840.10008.5.1.1.17.376", "Printer Configuration Retrieval SOP Instance", "Well-known Printer SOP Instance"},
3502     { "1.2.840.10008.5.1.1.18", "Basic Color Print Management Meta SOP Class", "Meta SOP Class"},
3503     { "1.2.840.10008.5.1.1.18.1", "Referenced Color Print Management Meta SOP Class (Retired)", "Meta SOP Class"},
3504     { "1.2.840.10008.5.1.1.22", "VOI LUT Box SOP Class", "SOP Class"},
3505     { "1.2.840.10008.5.1.1.23", "Presentation LUT SOP Class", "SOP Class"},
3506     { "1.2.840.10008.5.1.1.24", "Image Overlay Box SOP Class (Retired)", "SOP Class"},
3507     { "1.2.840.10008.5.1.1.24.1", "Basic Print Image Overlay Box SOP Class (Retired)", "SOP Class"},
3508     { "1.2.840.10008.5.1.1.25", "Print Queue SOP Instance (Retired)", "Well-known Print Queue SOP Instance"},
3509     { "1.2.840.10008.5.1.1.26", "Print Queue Management SOP Class (Retired)", "SOP Class"},
3510     { "1.2.840.10008.5.1.1.27", "Stored Print Storage SOP Class (Retired)", "SOP Class"},
3511     { "1.2.840.10008.5.1.1.29", "Hardcopy Grayscale Image Storage SOP Class (Retired)", "SOP Class"},
3512     { "1.2.840.10008.5.1.1.30", "Hardcopy Color Image Storage SOP Class (Retired)", "SOP Class"},
3513     { "1.2.840.10008.5.1.1.31", "Pull Print Request SOP Class (Retired)", "SOP Class"},
3514     { "1.2.840.10008.5.1.1.32", "Pull Stored Print Management Meta SOP Class (Retired)", "Meta SOP Class"},
3515     { "1.2.840.10008.5.1.1.33", "Media Creation Management SOP Class UID", "SOP Class"},
3516     { "1.2.840.10008.5.1.4.1.1.1", "Computed Radiography Image Storage", "SOP Class"},
3517     { "1.2.840.10008.5.1.4.1.1.1.1", "Digital X-Ray Image Storage - For Presentation", "SOP Class"},
3518     { "1.2.840.10008.5.1.4.1.1.1.1.1", "Digital X-Ray Image Storage - For Processing", "SOP Class"},
3519     { "1.2.840.10008.5.1.4.1.1.1.2", "Digital Mammography X-Ray Image Storage - For Presentation", "SOP Class"},
3520     { "1.2.840.10008.5.1.4.1.1.1.2.1", "Digital Mammography X-Ray Image Storage - For Processing", "SOP Class"},
3521     { "1.2.840.10008.5.1.4.1.1.1.3", "Digital Intra-oral X-Ray Image Storage - For Presentation", "SOP Class"},
3522     { "1.2.840.10008.5.1.4.1.1.1.3.1", "Digital Intra-oral X-Ray Image Storage - For Processing", "SOP Class"},
3523     { "1.2.840.10008.5.1.4.1.1.2", "CT Image Storage", "SOP Class"},
3524     { "1.2.840.10008.5.1.4.1.1.2.1", "Enhanced CT Image Storage", "SOP Class"},
3525     { "1.2.840.10008.5.1.4.1.1.3", "Ultrasound Multi-frame Image Storage (Retired)", "SOP Class"},
3526     { "1.2.840.10008.5.1.4.1.1.3.1", "Ultrasound Multi-frame Image Storage", "SOP Class"},
3527     { "1.2.840.10008.5.1.4.1.1.4", "MR Image Storage", "SOP Class"},
3528     { "1.2.840.10008.5.1.4.1.1.4.1", "Enhanced MR Image Storage", "SOP Class"},
3529     { "1.2.840.10008.5.1.4.1.1.4.2", "MR Spectroscopy Storage", "SOP Class"},
3530     { "1.2.840.10008.5.1.4.1.1.5", "Nuclear Medicine Image Storage (Retired)", "SOP Class"},
3531     { "1.2.840.10008.5.1.4.1.1.6", "Ultrasound Image Storage (Retired)", "SOP Class"},
3532     { "1.2.840.10008.5.1.4.1.1.6.1", "Ultrasound Image Storage", "SOP Class"},
3533     { "1.2.840.10008.5.1.4.1.1.7", "Secondary Capture Image Storage", "SOP Class"},
3534     { "1.2.840.10008.5.1.4.1.1.7.1", "Multi-frame Single Bit Secondary Capture Image Storage", "SOP Class"},
3535     { "1.2.840.10008.5.1.4.1.1.7.2", "Multi-frame Grayscale Byte Secondary Capture Image Storage", "SOP Class"},
3536     { "1.2.840.10008.5.1.4.1.1.7.3", "Multi-frame Grayscale Word Secondary Capture Image Storage", "SOP Class"},
3537     { "1.2.840.10008.5.1.4.1.1.7.4", "Multi-frame True Color Secondary Capture Image Storage", "SOP Class"},
3538     { "1.2.840.10008.5.1.4.1.1.8", "Standalone Overlay Storage (Retired)", "SOP Class"},
3539     { "1.2.840.10008.5.1.4.1.1.9", "Standalone Curve Storage (Retired)", "SOP Class"},
3540     { "1.2.840.10008.5.1.4.1.1.9.1", "Waveform Storage - Trial (Retired)", "SOP Class"},
3541     { "1.2.840.10008.5.1.4.1.1.9.1.1", "12-lead ECG Waveform Storage", "SOP Class"},
3542     { "1.2.840.10008.5.1.4.1.1.9.1.2", "General ECG Waveform Storage", "SOP Class"},
3543     { "1.2.840.10008.5.1.4.1.1.9.1.3", "Ambulatory ECG Waveform Storage", "SOP Class"},
3544     { "1.2.840.10008.5.1.4.1.1.9.2.1", "Hemodynamic Waveform Storage", "SOP Class"},
3545     { "1.2.840.10008.5.1.4.1.1.9.3.1", "Cardiac Electrophysiology Waveform Storage", "SOP Class"},
3546     { "1.2.840.10008.5.1.4.1.1.9.4.1", "Basic Voice Audio Waveform Storage", "SOP Class"},
3547     { "1.2.840.10008.5.1.4.1.1.10", "Standalone Modality LUT Storage (Retired)", "SOP Class"},
3548     { "1.2.840.10008.5.1.4.1.1.11", "Standalone VOI LUT Storage (Retired)", "SOP Class"},
3549     { "1.2.840.10008.5.1.4.1.1.11.1", "Grayscale Softcopy Presentation State Storage SOP Class", "SOP Class"},
3550     { "1.2.840.10008.5.1.4.1.1.11.2", "Color Softcopy Presentation State Storage SOP Class", "SOP Class"},
3551     { "1.2.840.10008.5.1.4.1.1.11.3", "Pseudo-Color Softcopy Presentation State Storage SOP Class", "SOP Class"},
3552     { "1.2.840.10008.5.1.4.1.1.11.4", "Blending Softcopy Presentation State Storage SOP Class", "SOP Class"},
3553     { "1.2.840.10008.5.1.4.1.1.12.1", "X-Ray Angiographic Image Storage", "SOP Class"},
3554     { "1.2.840.10008.5.1.4.1.1.12.1.1", "Enhanced XA Image Storage", "SOP Class"},
3555     { "1.2.840.10008.5.1.4.1.1.12.2", "X-Ray Radiofluoroscopic Image Storage", "SOP Class"},
3556     { "1.2.840.10008.5.1.4.1.1.12.2.1", "Enhanced XRF Image Storage", "SOP Class"},
3557     { "1.2.840.10008.5.1.4.1.1.13.1.1", "X-Ray 3D Angiographic Image Storage", "SOP Class"},
3558     { "1.2.840.10008.5.1.4.1.1.13.1.2", "X-Ray 3D Craniofacial Image Storage", "SOP Class"},
3559     { "1.2.840.10008.5.1.4.1.1.12.3", "X-Ray Angiographic Bi-Plane Image Storage (Retired)", "SOP Class"},
3560     { "1.2.840.10008.5.1.4.1.1.20", "Nuclear Medicine Image Storage", "SOP Class"},
3561     { "1.2.840.10008.5.1.4.1.1.66", "Raw Data Storage", "SOP Class"},
3562     { "1.2.840.10008.5.1.4.1.1.66.1", "Spatial Registration Storage", "SOP Class"},
3563     { "1.2.840.10008.5.1.4.1.1.66.2", "Spatial Fiducials Storage", "SOP Class"},
3564     { "1.2.840.10008.5.1.4.1.1.66.3", "Deformable Spatial Registration Storage", "SOP Class"},
3565     { "1.2.840.10008.5.1.4.1.1.66.4", "Segmentation Storage", "SOP Class"},
3566     { "1.2.840.10008.5.1.4.1.1.67", "Real World Value Mapping Storage", "SOP Class"},
3567     { "1.2.840.10008.5.1.4.1.1.77.1", "VL Image Storage - Trial (Retired)", ""},
3568     { "1.2.840.10008.5.1.4.1.1.77.2", "VL Multi-frame Image Storage - Trial (Retired)", ""},
3569     { "1.2.840.10008.5.1.4.1.1.77.1.1", "VL Endoscopic Image Storage", "SOP Class"},
3570     { "1.2.840.10008.5.1.4.1.1.77.1.1.1", "Video Endoscopic Image Storage", "SOP Class"},
3571     { "1.2.840.10008.5.1.4.1.1.77.1.2", "VL Microscopic Image Storage", "SOP Class"},
3572     { "1.2.840.10008.5.1.4.1.1.77.1.2.1", "Video Microscopic Image Storage", "SOP Class"},
3573     { "1.2.840.10008.5.1.4.1.1.77.1.3", "VL Slide-Coordinates Microscopic Image Storage", "SOP Class"},
3574     { "1.2.840.10008.5.1.4.1.1.77.1.4", "VL Photographic Image Storage", "SOP Class"},
3575     { "1.2.840.10008.5.1.4.1.1.77.1.4.1", "Video Photographic Image Storage", "SOP Class"},
3576     { "1.2.840.10008.5.1.4.1.1.77.1.5.1", "Ophthalmic Photography 8 Bit Image Storage", "SOP Class"},
3577     { "1.2.840.10008.5.1.4.1.1.77.1.5.2", "Ophthalmic Photography 16 Bit Image Storage", "SOP Class"},
3578     { "1.2.840.10008.5.1.4.1.1.77.1.5.3", "Stereometric Relationship Storage", "SOP Class"},
3579     { "1.2.840.10008.5.1.4.1.1.77.1.5.4", "Ophthalmic Tomography Image Storage", "SOP Class"},
3580     { "1.2.840.10008.5.1.4.1.1.88.1", "Text SR Storage - Trial (Retired)", "SOP Class"},
3581     { "1.2.840.10008.5.1.4.1.1.88.2", "Audio SR Storage - Trial (Retired)", "SOP Class"},
3582     { "1.2.840.10008.5.1.4.1.1.88.3", "Detail SR Storage - Trial (Retired)", "SOP Class"},
3583     { "1.2.840.10008.5.1.4.1.1.88.4", "Comprehensive SR Storage - Trial (Retired)", "SOP Class"},
3584     { "1.2.840.10008.5.1.4.1.1.88.11", "Basic Text SR Storage", "SOP Class"},
3585     { "1.2.840.10008.5.1.4.1.1.88.22", "Enhanced SR Storage", "SOP Class"},
3586     { "1.2.840.10008.5.1.4.1.1.88.33", "Comprehensive SR Storage", "SOP Class"},
3587     { "1.2.840.10008.5.1.4.1.1.88.40", "Procedure Log Storage", "SOP Class"},
3588     { "1.2.840.10008.5.1.4.1.1.88.50", "Mammography CAD SR Storage", "SOP Class"},
3589     { "1.2.840.10008.5.1.4.1.1.88.59", "Key Object Selection Document Storage", "SOP Class"},
3590     { "1.2.840.10008.5.1.4.1.1.88.65", "Chest CAD SR Storage", "SOP Class"},
3591     { "1.2.840.10008.5.1.4.1.1.88.67", "X-Ray Radiation Dose SR Storage", "SOP Class"},
3592     { "1.2.840.10008.5.1.4.1.1.104.1", "Encapsulated PDF Storage", "SOP Class"},
3593     { "1.2.840.10008.5.1.4.1.1.104.2", "Encapsulated CDA Storage", "SOP Class"},
3594     { "1.2.840.10008.5.1.4.1.1.128", "Positron Emission Tomography Image Storage", "SOP Class"},
3595     { "1.2.840.10008.5.1.4.1.1.129", "Standalone PET Curve Storage (Retired)", "SOP Class"},
3596     { "1.2.840.10008.5.1.4.1.1.481.1", "RT Image Storage", "SOP Class"},
3597     { "1.2.840.10008.5.1.4.1.1.481.2", "RT Dose Storage", "SOP Class"},
3598     { "1.2.840.10008.5.1.4.1.1.481.3", "RT Structure Set Storage", "SOP Class"},
3599     { "1.2.840.10008.5.1.4.1.1.481.4", "RT Beams Treatment Record Storage", "SOP Class"},
3600     { "1.2.840.10008.5.1.4.1.1.481.5", "RT Plan Storage", "SOP Class"},
3601     { "1.2.840.10008.5.1.4.1.1.481.6", "RT Brachy Treatment Record Storage", "SOP Class"},
3602     { "1.2.840.10008.5.1.4.1.1.481.7", "RT Treatment Summary Record Storage", "SOP Class"},
3603     { "1.2.840.10008.5.1.4.1.1.481.8", "RT Ion Plan Storage", "SOP Class"},
3604     { "1.2.840.10008.5.1.4.1.1.481.9", "RT Ion Beams Treatment Record Storage", "SOP Class"},
3605     { "1.2.840.10008.5.1.4.1.2.1.1", "Patient Root Query/Retrieve Information Model - FIND", "SOP Class"},
3606     { "1.2.840.10008.5.1.4.1.2.1.2", "Patient Root Query/Retrieve Information Model - MOVE", "SOP Class"},
3607     { "1.2.840.10008.5.1.4.1.2.1.3", "Patient Root Query/Retrieve Information Model - GET", "SOP Class"},
3608     { "1.2.840.10008.5.1.4.1.2.2.1", "Study Root Query/Retrieve Information Model - FIND", "SOP Class"},
3609     { "1.2.840.10008.5.1.4.1.2.2.2", "Study Root Query/Retrieve Information Model - MOVE", "SOP Class"},
3610     { "1.2.840.10008.5.1.4.1.2.2.3", "Study Root Query/Retrieve Information Model - GET", "SOP Class"},
3611     { "1.2.840.10008.5.1.4.1.2.3.1", "Patient/Study Only Query/Retrieve Information Model - FIND (Retired)", "SOP Class"},
3612     { "1.2.840.10008.5.1.4.1.2.3.2", "Patient/Study Only Query/Retrieve Information Model - MOVE (Retired)", "SOP Class"},
3613     { "1.2.840.10008.5.1.4.1.2.3.3", "Patient/Study Only Query/Retrieve Information Model - GET (Retired)", "SOP Class"},
3614     { "1.2.840.10008.5.1.4.31", "Modality Worklist Information Model - FIND", "SOP Class"},
3615     { "1.2.840.10008.5.1.4.32.1", "General Purpose Worklist Information Model - FIND", "SOP Class"},
3616     { "1.2.840.10008.5.1.4.32.2", "General Purpose Scheduled Procedure Step SOP Class", "SOP Class"},
3617     { "1.2.840.10008.5.1.4.32.3", "General Purpose Performed Procedure Step SOP Class", "SOP Class"},
3618     { "1.2.840.10008.5.1.4.32", "General Purpose Worklist Management Meta SOP Class", "Meta SOP Class"},
3619     { "1.2.840.10008.5.1.4.33", "Instance Availability Notification SOP Class", "SOP Class"},
3620     { "1.2.840.10008.5.1.4.34.1", "RT Beams Delivery Instruction Storage (Supplement 74 Frozen Draft)", "SOP Class"},
3621     { "1.2.840.10008.5.1.4.34.2", "RT Conventional Machine Verification (Supplement 74 Frozen Draft)", "SOP Class"},
3622     { "1.2.840.10008.5.1.4.34.3", "RT Ion Machine Verification (Supplement 74 Frozen Draft)", "SOP Class"},
3623     { "1.2.840.10008.5.1.4.34.4", "Unified Worklist and Procedure Step Service Class", "Service Class"},
3624     { "1.2.840.10008.5.1.4.34.4.1", "Unified Procedure Step - Push SOP Class", "SOP Class"},
3625     { "1.2.840.10008.5.1.4.34.4.2", "Unified Procedure Step - Watch SOP Class", "SOP Class"},
3626     { "1.2.840.10008.5.1.4.34.4.3", "Unified Procedure Step - Pull SOP Class", "SOP Class"},
3627     { "1.2.840.10008.5.1.4.34.4.4", "Unified Procedure Step - Event SOP Class", "SOP Class"},
3628     { "1.2.840.10008.5.1.4.34.5", "Unified Worklist and Procedure Step SOP Instance", "Well-known SOP Instance"},
3629     { "1.2.840.10008.5.1.4.37.1", "General Relevant Patient Information Query", "SOP Class"},
3630     { "1.2.840.10008.5.1.4.37.2", "Breast Imaging Relevant Patient Information Query", "SOP Class"},
3631     { "1.2.840.10008.5.1.4.37.3", "Cardiac Relevant Patient Information Query", "SOP Class"},
3632     { "1.2.840.10008.5.1.4.38.1", "Hanging Protocol Storage", "SOP Class"},
3633     { "1.2.840.10008.5.1.4.38.2", "Hanging Protocol Information Model - FIND", "SOP Class"},
3634     { "1.2.840.10008.5.1.4.38.3", "Hanging Protocol Information Model - MOVE", "SOP Class"},
3635     { "1.2.840.10008.5.1.4.41", "Product Characteristics Query SOP Class", "SOP Class"},
3636     { "1.2.840.10008.5.1.4.42", "Substance Approval Query SOP Class", "SOP Class"},
3637     { "1.2.840.10008.15.0.3.1", "dicomDeviceName", "LDAP OID"},
3638     { "1.2.840.10008.15.0.3.2", "dicomDescription", "LDAP OID"},
3639     { "1.2.840.10008.15.0.3.3", "dicomManufacturer", "LDAP OID"},
3640     { "1.2.840.10008.15.0.3.4", "dicomManufacturerModelName", "LDAP OID"},
3641     { "1.2.840.10008.15.0.3.5", "dicomSoftwareVersion", "LDAP OID"},
3642     { "1.2.840.10008.15.0.3.6", "dicomVendorData", "LDAP OID"},
3643     { "1.2.840.10008.15.0.3.7", "dicomAETitle", "LDAP OID"},
3644     { "1.2.840.10008.15.0.3.8", "dicomNetworkConnectionReference", "LDAP OID"},
3645     { "1.2.840.10008.15.0.3.9", "dicomApplicationCluster", "LDAP OID"},
3646     { "1.2.840.10008.15.0.3.10", "dicomAssociationInitiator", "LDAP OID"},
3647     { "1.2.840.10008.15.0.3.11", "dicomAssociationAcceptor", "LDAP OID"},
3648     { "1.2.840.10008.15.0.3.12", "dicomHostname", "LDAP OID"},
3649     { "1.2.840.10008.15.0.3.13", "dicomPort", "LDAP OID"},
3650     { "1.2.840.10008.15.0.3.14", "dicomSOPClass", "LDAP OID"},
3651     { "1.2.840.10008.15.0.3.15", "dicomTransferRole", "LDAP OID"},
3652     { "1.2.840.10008.15.0.3.16", "dicomTransferSyntax", "LDAP OID"},
3653     { "1.2.840.10008.15.0.3.17", "dicomPrimaryDeviceType", "LDAP OID"},
3654     { "1.2.840.10008.15.0.3.18", "dicomRelatedDeviceReference", "LDAP OID"},
3655     { "1.2.840.10008.15.0.3.19", "dicomPreferredCalledAETitle", "LDAP OID"},
3656     { "1.2.840.10008.15.0.3.20", "dicomTLSCyphersuite", "LDAP OID"},
3657     { "1.2.840.10008.15.0.3.21", "dicomAuthorizedNodeCertificateReference", "LDAP OID"},
3658     { "1.2.840.10008.15.0.3.22", "dicomThisNodeCertificateReference", "LDAP OID"},
3659     { "1.2.840.10008.15.0.3.23", "dicomInstalled", "LDAP OID"},
3660     { "1.2.840.10008.15.0.3.24", "dicomStationName", "LDAP OID"},
3661     { "1.2.840.10008.15.0.3.25", "dicomDeviceSerialNumber", "LDAP OID"},
3662     { "1.2.840.10008.15.0.3.26", "dicomInstitutionName", "LDAP OID"},
3663     { "1.2.840.10008.15.0.3.27", "dicomInstitutionAddress", "LDAP OID"},
3664     { "1.2.840.10008.15.0.3.28", "dicomInstitutionDepartmentName", "LDAP OID"},
3665     { "1.2.840.10008.15.0.3.29", "dicomIssuerOfPatientID", "LDAP OID"},
3666     { "1.2.840.10008.15.0.3.30", "dicomPreferredCallingAETitle", "LDAP OID"},
3667     { "1.2.840.10008.15.0.3.31", "dicomSupportedCharacterSet", "LDAP OID"},
3668     { "1.2.840.10008.15.0.4.1", "dicomConfigurationRoot", "LDAP OID"},
3669     { "1.2.840.10008.15.0.4.2", "dicomDevicesRoot", "LDAP OID"},
3670     { "1.2.840.10008.15.0.4.3", "dicomUniqueAETitlesRegistryRoot", "LDAP OID"},
3671     { "1.2.840.10008.15.0.4.4", "dicomDevice", "LDAP OID"},
3672     { "1.2.840.10008.15.0.4.5", "dicomNetworkAE", "LDAP OID"},
3673     { "1.2.840.10008.15.0.4.6", "dicomNetworkConnection", "LDAP OID"},
3674     { "1.2.840.10008.15.0.4.7", "dicomUniqueAETitle", "LDAP OID"},
3675     { "1.2.840.10008.15.0.4.8", "dicomTransferCapability", "LDAP OID"},
3676
3677     { "1.2.840.113619.5.2", "Implicit VR Little Endian, Big Endian Pixels, GE Private", "Transfer Syntax"},
3678
3679 };
3680
3681 /* following definitions are used to call dissect_dcm_assoc_item() */
3682 #define DCM_ITEM_VALUE_TYPE_UID     1
3683 #define DCM_ITEM_VALUE_TYPE_STRING  2
3684 #define DCM_ITEM_VALUE_TYPE_UINT32  3
3685
3686 /* A few function declarations to ensure consitency*/
3687
3688 /* Per object, a xxx_new() and a xxx_get() function. The _get() will create one if specified. */
3689
3690 static dcm_state_t*      dcm_state_new(void);
3691 static dcm_state_t*      dcm_state_get(packet_info *pinfo, gboolean create);
3692
3693 static dcm_state_assoc_t*   dcm_state_assoc_new (dcm_state_t *dcm_data, guint32 packet_no);
3694 static dcm_state_assoc_t*   dcm_state_assoc_get (dcm_state_t *dcm_data, guint32 packet_no, gboolean create);
3695 static dcm_state_pctx_t*    dcm_state_pctx_new  (dcm_state_assoc_t *assoc, guint8 pctx_id);
3696 static dcm_state_pctx_t*    dcm_state_pctx_get  (dcm_state_assoc_t *assoc, guint8 pctx_id, gboolean create);
3697 static dcm_state_pdv_t*     dcm_state_pdv_new   (dcm_state_pctx_t *pctx, guint32 packet_no, guint32 offset);
3698 static dcm_state_pdv_t*     dcm_state_pdv_get   (dcm_state_pctx_t *pctx, guint32 packet_no, guint32 offset, gboolean create);
3699
3700 /* Following three functions by purpose only return int, since we request data consolidation */
3701 static int  dissect_dcm_static      (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
3702
3703 /* ToDo: The heuristic one should actually return true/false only */
3704 static int  dissect_dcm_heuristic   (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
3705 static int  dissect_dcm_main        (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean is_port_static);
3706
3707 /* And from here on, only use unsigned 32 bit values. Offset is always positive number in respect to the tvb buffer start */
3708 static guint32  dissect_dcm_pdu     (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset);
3709
3710 static guint32  dissect_dcm_assoc_detail(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti,   dcm_state_assoc_t *assoc, guint32 offset, guint32 len);
3711 static void     dissect_dcm_pctx        (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, dcm_state_assoc_t *assoc, guint32 offset, guint32 len, const gchar *pitem_prefix, gboolean request);
3712 static void     dissect_dcm_assoc_item  (tvbuff_t *tvb, proto_tree *tree, guint32 offset, const gchar *pitem_prefix, int item_value_type, gchar **item_value, const gchar **item_description, int *hf_type, int *hf_len, int *hf_value, int ett_subtree);
3713 static void     dissect_dcm_userinfo    (tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 len, const gchar *pitem_prefix);
3714
3715 static guint32  dissect_dcm_pdu_data        (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, dcm_state_assoc_t *assoc, guint32 offset, guint32 pdu_len, gchar **pdu_data_description);
3716 static guint32  dissect_dcm_pdv_header      (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, dcm_state_assoc_t *assoc, guint32 offset, dcm_state_pdv_t **pdv);
3717 static guint32  dissect_dcm_pdv_fragmented  (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, dcm_state_assoc_t *assoc, guint32 offset, guint32 pdv_len, gchar **pdv_description);
3718 static guint32  dissect_dcm_pdv_body        (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, dcm_state_pdv_t *pdv, guint32 offset, guint32 pdv_body_len, gchar **pdv_description);
3719
3720 static guint32  dissect_dcm_tag             (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, dcm_state_pdv_t *pdv, guint32 offset, guint32 endpos, gboolean is_first_tag, gchar **tag_description, gboolean *end_of_seq_or_item);
3721 static guint32  dissect_dcm_tag_open        (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, dcm_state_pdv_t *pdv, guint32 offset, guint32 endpos, gboolean *is_first_tag);
3722 static guint32  dissect_dcm_tag_value       (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, dcm_state_pdv_t *pdv, guint32 offset, guint16 grp, guint16 elm, guint32 vl, guint32 vl_max, const gchar* vr, gchar **tag_value);
3723
3724 static void dcm_set_syntax              (dcm_state_pctx_t *pctx, gchar *xfer_uid, const gchar *xfer_desc);
3725 static void dcm_export_create_object    (packet_info *pinfo, dcm_state_assoc_t *assoc, dcm_state_pdv_t *pdv);
3726
3727 static void
3728
3729 dcm_init(void)
3730 {
3731     guint   i;
3732
3733     /* Add UID objects to hash table */
3734     if (dcm_uid_table == NULL) {
3735         dcm_uid_table = g_hash_table_new(g_str_hash, g_str_equal);
3736         for (i = 0; i < array_length(dcm_uid_data); i++) {
3737             g_hash_table_insert(dcm_uid_table, (gpointer) dcm_uid_data[i].value,
3738             (gpointer) &dcm_uid_data[i]);
3739         }
3740     }
3741
3742     /* Add Tag objects to hash table */
3743     if (dcm_tag_table == NULL) {
3744         dcm_tag_table = g_hash_table_new(NULL, NULL);
3745         for (i = 0; i < array_length(dcm_tag_data); i++) {
3746             g_hash_table_insert(dcm_tag_table, GUINT_TO_POINTER(dcm_tag_data[i].tag),
3747             (gpointer) &dcm_tag_data[i]);
3748         }
3749     }
3750
3751    /* Add Status Values to hash table */
3752     if (dcm_status_table == NULL) {
3753         dcm_status_table = g_hash_table_new(NULL, NULL);
3754         for (i = 0; i < array_length(dcm_status_data); i++) {
3755             g_hash_table_insert(dcm_status_table, GUINT_TO_POINTER((guint32)dcm_status_data[i].value),
3756             (gpointer)&dcm_status_data[i]);
3757         }
3758     }
3759
3760     /* Register processing of fragmented DICOM PDVs */
3761     fragment_table_init(&dcm_pdv_fragment_table);
3762     reassembled_table_init(&dcm_pdv_reassembled_table);
3763 }
3764
3765 static dcm_state_t *
3766 dcm_state_new(void)
3767 {
3768     /* Not much fun. Just create very simple root structure */
3769
3770     dcm_state_t *ds;
3771
3772     ds = (dcm_state_t *) se_alloc0(sizeof(dcm_state_t));
3773     return ds;
3774 }
3775
3776 static dcm_state_t *
3777 dcm_state_get(packet_info *pinfo, gboolean create)
3778 {
3779
3780     /*  Get or create converstation and DICOM data structure if desired
3781         Return new or existing dicom struture, which is used to store context IDs and xfer Syntax
3782         Return NULL in case of the structure couldn't be created
3783     */
3784
3785     conversation_t  *conv=NULL;
3786     dcm_state_t     *dcm_data=NULL;
3787
3788     conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
3789         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
3790
3791     if (conv == NULL) {
3792         /* Conversation does not exist, create one.
3793            Usually set for the first packet already. Probably by dissect-tcp
3794         */
3795         conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
3796             pinfo->srcport, pinfo->destport, 0);
3797     }
3798     else {                      /* conversation exists, try to get data already filled */
3799         dcm_data = (dcm_state_t *)conversation_get_proto_data(conv, proto_dcm);
3800     }
3801
3802
3803     if (dcm_data == NULL && create) {
3804
3805         dcm_data = dcm_state_new();
3806         conversation_add_proto_data(conv, proto_dcm, dcm_data);
3807
3808         /*  Mark it as DICOM conversation. Needed for the heuristic mode,
3809             to prevent stealing subsequent packets by other dissectors
3810         */
3811         conversation_set_dissector(conv, dcm_handle);
3812     }
3813
3814     return dcm_data;
3815 }
3816
3817
3818 static dcm_state_assoc_t *
3819 dcm_state_assoc_new(dcm_state_t *dcm_data, guint32 packet_no)
3820 {
3821     /* Create new accociation object and initalize the members */
3822
3823     dcm_state_assoc_t *assoc;
3824
3825     assoc = (dcm_state_assoc_t *) se_alloc0(sizeof(dcm_state_assoc_t));
3826     assoc->packet_no = packet_no;           /* Identifier */
3827
3828     /* add to the end of the list */
3829     if (dcm_data->last_assoc) {
3830         dcm_data->last_assoc->next = assoc;
3831         assoc->prev = dcm_data->last_assoc;
3832     }
3833     else {
3834         dcm_data->first_assoc = assoc;
3835     }
3836     dcm_data->last_assoc = assoc;
3837     return assoc;
3838 }
3839
3840 static dcm_state_assoc_t *
3841 dcm_state_assoc_get(dcm_state_t *dcm_data, guint32 packet_no, gboolean create)
3842 {
3843   /*  Find or create Association object.
3844       Return NULL, if Association was not found, based on packet number
3845   */
3846
3847     dcm_state_assoc_t *assoc = NULL;
3848
3849     assoc=dcm_data->first_assoc;
3850
3851     while (assoc) {
3852
3853         if (assoc->next) {
3854             /* we have more associations in the same stream */
3855             if ((assoc->packet_no <= packet_no) && (packet_no < assoc->next->packet_no))
3856                 break;
3857         }
3858         else {
3859             /* last or only associations in the same stream */
3860             if (assoc->packet_no <= packet_no)
3861                 break;
3862         }
3863         assoc = assoc->next;
3864     }
3865
3866     if (assoc == NULL && create) {
3867         assoc = dcm_state_assoc_new(dcm_data, packet_no);
3868     }
3869     return assoc;
3870 }
3871
3872 static dcm_state_pctx_t *
3873 dcm_state_pctx_new(dcm_state_assoc_t *assoc, guint8 pctx_id)
3874 {
3875     /* Create new presentation context object and initalize the members */
3876
3877     dcm_state_pctx_t *pctx=NULL;
3878
3879     pctx = (dcm_state_pctx_t *)se_alloc0(sizeof(dcm_state_pctx_t));
3880     pctx->id = pctx_id;
3881     pctx->syntax = DCM_UNK;
3882
3883     /* add to the end of the list list */
3884     if (assoc->last_pctx) {
3885         assoc->last_pctx->next = pctx;
3886         pctx->prev = assoc->last_pctx;
3887     }
3888     else {
3889         assoc->first_pctx = pctx;
3890     }
3891     assoc->last_pctx = pctx;
3892
3893     return pctx;
3894 }
3895
3896 static dcm_state_pctx_t *
3897 dcm_state_pctx_get(dcm_state_assoc_t *assoc, guint8 pctx_id, gboolean create)
3898 {
3899     /*  Find or create presentation context object. Return NULL, if Context ID was not found */
3900
3901     dcm_state_pctx_t *pctx =NULL;
3902
3903     pctx = assoc->first_pctx;
3904     /*
3905     static char notfound[] = "not found - click on ASSOC Request";
3906     static dcm_state_pctx_t dunk = { NULL, NULL, FALSE, 0, notfound, notfound, notfound, notfound, DCM_UNK };
3907     */
3908     while (pctx) {
3909         if (pctx->id == pctx_id)
3910             break;
3911         pctx = pctx->next;
3912     }
3913
3914     if (pctx == NULL && create) {
3915         pctx = dcm_state_pctx_new(assoc, pctx_id);
3916     }
3917
3918     return pctx;
3919 }
3920
3921
3922 static dcm_state_pdv_t*
3923 dcm_state_pdv_new(dcm_state_pctx_t *pctx, guint32 packet_no, guint32 offset)
3924 {
3925     /* Create new PDV object and initalize the members */
3926
3927     dcm_state_pdv_t *pdv = NULL;
3928
3929     pdv = (dcm_state_pdv_t *) se_alloc0(sizeof(dcm_state_pdv_t));
3930     pdv->syntax = DCM_UNK;
3931     pdv->is_last_fragment = TRUE;       /* Continuation PDVs are more tricky */
3932     pdv->packet_no = packet_no;
3933     pdv->offset = offset;
3934
3935     /* add to the end of the list list */
3936     if (pctx->last_pdv) {
3937         pctx->last_pdv->next = pdv;
3938         pdv->prev = pctx->last_pdv;
3939     }
3940     else {
3941         pctx->first_pdv = pdv;
3942     }
3943     pctx->last_pdv = pdv;
3944     return pdv;
3945 }
3946
3947
3948 static dcm_state_pdv_t*
3949 dcm_state_pdv_get(dcm_state_pctx_t *pctx, guint32 packet_no, guint32 offset, gboolean create)
3950 {
3951     /*  Find or create PDV object. Return NULL, if PDV was not found, based on packet number and offset */
3952
3953     dcm_state_pdv_t *pdv = NULL;
3954
3955     pdv=pctx->first_pdv;
3956
3957     while (pdv) {
3958         if ((pdv->packet_no == packet_no) && (pdv->offset == offset))
3959             break;
3960         pdv = pdv->next;
3961     }
3962
3963     if (pdv == NULL && create) {
3964         pdv = dcm_state_pdv_new(pctx, packet_no, offset);
3965     }
3966     return pdv;
3967 }
3968
3969 static dcm_state_pdv_t*
3970 dcm_state_pdv_get_obj_start(dcm_state_pdv_t *pdv_curr)
3971 {
3972
3973     dcm_state_pdv_t *pdv_first=pdv_curr;
3974
3975     /* Get First PDV of the DICOM Object */
3976     while (pdv_first->prev && !pdv_first->prev->is_last_fragment) {
3977         pdv_first = pdv_first->prev;
3978     }
3979
3980     return pdv_first;
3981 }
3982
3983 static const char *
3984 dcm_pdu2str(guint8 item)
3985 {
3986     const char *s = "";
3987     switch (item) {
3988     case 1: s = "ASSOC Request"; break;
3989     case 2: s = "ASSOC Accept"; break;
3990     case 3: s = "ASSOC Reject"; break;
3991     case 4: s = "Data"; break;
3992     case 5: s = "RELEASE Request"; break;
3993     case 6: s = "RELEASE Response"; break;
3994     case 7: s = "ABORT"; break;
3995     default: break;
3996     }
3997     return s;
3998 }
3999
4000
4001 static const char *
4002 dcm_cmd2str(guint16 us)
4003 {
4004     const char *s = "";
4005     /* there should be a better way to do this */
4006     switch (us) {
4007     case 0x0001:  s = "C-STORE-RQ"; break;
4008     case 0x8001:  s = "C-STORE-RSP"; break;
4009     case 0x0010:  s = "C-GET-RQ"; break;
4010     case 0x8010:  s = "C-GET-RSP"; break;
4011     case 0x0020:  s = "C-FIND-RQ"; break;
4012     case 0x8020:  s = "C-FIND-RSP"; break;
4013     case 0x0021:  s = "C-MOVE-RQ"; break;
4014     case 0x8021:  s = "C-MOVE-RSP"; break;
4015     case 0x0030:  s = "C-ECHO-RQ"; break;
4016     case 0x8030:  s = "C-ECHO-RSP"; break;
4017     case 0x0100:  s = "N-EVENT-REPORT-RQ"; break;
4018     case 0x8100:  s = "N-EVENT-REPORT-RSP"; break;
4019     case 0x0110:  s = "N-GET-RQ"; break;
4020     case 0x8110:  s = "N-GET-RSP"; break;
4021     case 0x0120:  s = "N-SET-RQ"; break;
4022     case 0x8120:  s = "N-SET-RSP"; break;
4023     case 0x0130:  s = "N-ACTION-RQ"; break;
4024     case 0x8130:  s = "N-ACTION-RSP"; break;
4025     case 0x0140:  s = "N-CREATE-RQ"; break;
4026     case 0x8140:  s = "N-CREATE-RSP"; break;
4027     case 0x0150:  s = "N-DELETE-RQ"; break;
4028     case 0x8150:  s = "N-DELETE-RSP"; break;
4029     case 0x0fff:  s = "C-CANCEL-RQ"; break;
4030     default: break;
4031     }
4032     return s;
4033 }
4034
4035 static const gchar *
4036 dcm_rsp2str(guint16 status_value)
4037 {
4038
4039     dcm_status_t    *status = NULL;
4040
4041     const gchar *s = "";
4042
4043     /*
4044         Clasification
4045         0x0000          : SUCCESS
4046         0x0001 & Bxxx   : WARNING
4047         0xFE00          : CANCEL
4048         0XFFxx          : PENDING
4049
4050         All other       : FAILURE
4051     */
4052
4053     /* Use specific text first */
4054     status = (dcm_status_t*) g_hash_table_lookup(dcm_status_table, GUINT_TO_POINTER((guint32)status_value));
4055
4056     if (status) {
4057          s = status->description;
4058     }
4059     else {
4060
4061         if ((status_value & 0xFF00) == 0xA700) {
4062             /* 0xA7xx */
4063             s = "Refused: Out of Resources";
4064         }
4065         else if ((status_value & 0xFF00) == 0xA900) {
4066             /* 0xA9xx */
4067             s = "Error: Data Set does not match SOP Class";
4068         }
4069         else if ((status_value & 0xF000) == 0xC000) {
4070             /* 0xCxxx */
4071             s = "Error: Cannot understand/Unable to Process";
4072         }
4073         else {
4074             /* At least came across 0xD001 in one capture */
4075             s = "Unknown";
4076         }
4077     }
4078
4079     return s;
4080 }
4081
4082 static const gchar*
4083 dcm_uid_or_desc(gchar *dcm_uid, gchar *dcm_desc)
4084 {
4085     /* Return Description, UID or error */
4086
4087     return (dcm_desc == NULL ? (dcm_uid == NULL ? "Malformed Packet" : dcm_uid) : dcm_desc);
4088 }
4089
4090 static void
4091 dcm_set_syntax(dcm_state_pctx_t *pctx, gchar *xfer_uid, const gchar *xfer_desc)
4092 {
4093     if ((pctx == NULL) || (xfer_uid == NULL) || (xfer_desc == NULL))
4094         return;
4095
4096     g_free(pctx->xfer_uid);     /* free prev allocated xfer */
4097     g_free(pctx->xfer_desc);    /* free prev allocated xfer */
4098
4099     pctx->syntax = 0;
4100     pctx->xfer_uid = g_strdup(xfer_uid);
4101     pctx->xfer_desc = g_strdup(xfer_desc);
4102
4103     /* this would be faster to skip the common parts, and have a FSA to
4104      * find the syntax.
4105      * Absent of coding that, this is in descending order of probability */
4106     if (0 == strcmp(xfer_uid, "1.2.840.10008.1.2"))
4107         pctx->syntax = DCM_ILE;  /* implicit little endian */
4108     else if (0 == strcmp(xfer_uid, "1.2.840.10008.1.2.1"))
4109         pctx->syntax = DCM_ELE;  /* explicit little endian */
4110     else if (0 == strcmp(xfer_uid, "1.2.840.10008.1.2.2"))
4111         pctx->syntax = DCM_EBE;  /* explicit big endian */
4112     else if (0 == strcmp(xfer_uid, "1.2.840.113619.5.2"))
4113         pctx->syntax = DCM_ILE;  /* implicit little endian, big endian pixels, GE private */
4114     else if (0 == strcmp(xfer_uid, "1.2.840.10008.1.2.4.70"))
4115         pctx->syntax = DCM_ELE;  /* explicit little endian, jpeg */
4116     else if (0 == strncmp(xfer_uid, "1.2.840.10008.1.2.4", 18))
4117         pctx->syntax = DCM_ELE;  /* explicit little endian, jpeg */
4118     else if (0 == strcmp(xfer_uid, "1.2.840.10008.1.2.1.99"))
4119         pctx->syntax = DCM_ELE;  /* explicit little endian, deflated */
4120 }
4121
4122 static void
4123 dcm_guint16_to_le(guint8 *buffer, guint16 value)
4124 {
4125
4126     buffer[0]=(guint8) (value & 0x00FF);
4127     buffer[1]=(guint8)((value & 0xFF00) >> 8);
4128 }
4129
4130 static void
4131 dcm_guint32_to_le(guint8 *buffer, guint32 value)
4132 {
4133
4134     buffer[0]=(guint8) (value & 0x000000FF);
4135     buffer[1]=(guint8)((value & 0x0000FF00) >>  8);
4136     buffer[2]=(guint8)((value & 0x00FF0000) >> 16);
4137     buffer[3]=(guint8)((value & 0xFF000000) >> 24);
4138
4139 }
4140
4141 static guint32
4142 dcm_export_create_tag_base(guint8 *buffer, guint32 bufflen, guint32 offset,
4143                            guint16 grp, guint16 elm, guint16 vr,
4144                            const guint8 *value_buffer, guint32 value_len)
4145 {
4146     /*  Only Explict Littele Endian is needed to create Metafile Header
4147         Generic function to write a TAG, VR, LEN & VALUE to a combined buffer
4148         The value (buffer, len) must be preprocessed by a VR specific function
4149     */
4150
4151     if (offset + 6 > bufflen) return bufflen;
4152
4153     dcm_guint16_to_le(buffer + offset, grp);
4154     offset += 2;
4155     dcm_guint16_to_le(buffer + offset, elm);
4156     offset += 2;
4157     memmove(buffer + offset, dcm_tag_vr_lookup[vr], 2);
4158     offset += 2;
4159
4160     switch (vr) {
4161     case DCM_VR_OB:
4162     case DCM_VR_OW:
4163     case DCM_VR_OF:
4164     case DCM_VR_SQ:
4165     case DCM_VR_UT:
4166     case DCM_VR_UN:
4167         /* DICOM likes it complicated. Special handling for these types */
4168
4169         if (offset + 6 > bufflen) return bufflen;
4170
4171         /* Add two reserved 0x00 bytes */
4172         dcm_guint16_to_le(buffer + offset, 0);
4173         offset += 2;
4174
4175         /* Length is a 4 byte field */
4176         dcm_guint32_to_le(buffer + offset, value_len);
4177         offset += 4;
4178
4179         break;
4180
4181     default:
4182         /* Length is a 2 byte field */
4183         if (offset + 2 > bufflen) return bufflen;
4184
4185         dcm_guint16_to_le(buffer + offset, (guint16)value_len);
4186         offset += 2;
4187     }
4188
4189     if (offset + value_len > bufflen) return bufflen;
4190
4191     memmove(buffer + offset, value_buffer, value_len);
4192     offset += value_len;
4193
4194     return offset;
4195 }
4196
4197 static guint32
4198 dcm_export_create_tag_guint16(guint8 *buffer, guint32 bufflen, guint32 offset,
4199                               guint16 grp, guint16 elm, guint16 vr, guint16 value)
4200 {
4201
4202     return dcm_export_create_tag_base(buffer, bufflen, offset, grp, elm, vr, (guint8*)&value, 2);
4203 }
4204
4205 static guint32
4206 dcm_export_create_tag_guint32(guint8 *buffer, guint32 bufflen, guint32 offset,
4207                               guint16 grp, guint16 elm, guint16 vr, guint32 value)
4208 {
4209
4210     return dcm_export_create_tag_base(buffer, bufflen, offset, grp, elm, vr, (guint8*)&value, 4);
4211 }
4212
4213 static guint32
4214 dcm_export_create_tag_str(guint8 *buffer, guint32 bufflen, guint32 offset,
4215                           guint16 grp, guint16 elm, guint16 vr,
4216                           const gchar *value)
4217 {
4218     guint32 len;
4219
4220     if (!value) {
4221         /* NULL object. E.g. happens if UID was not found/set. Don't create element*/
4222         return offset;
4223     }
4224
4225     len=(int)strlen(value);
4226
4227     if ((len & 0x01) == 1) {
4228         /*  Odd length: since buffer is 0 initalized, pad with a 0x00 */
4229         len += 1;
4230     }
4231
4232     return dcm_export_create_tag_base(buffer, bufflen, offset, grp, elm, vr, (const guint8 *)value, len);
4233 }
4234
4235
4236 static guint8*
4237 dcm_export_create_header(guint32 *dcm_header_len, gchar *sop_class_uid, gchar *sop_instance_uid, gchar *xfer_uid)
4238 {
4239     guint8      *dcm_header=NULL;
4240     guint32     offset=0;
4241     guint32     offset_header_len=0;
4242
4243 #define DCM_HEADER_MAX 512
4244
4245     dcm_header=(guint8 *)ep_alloc0(DCM_HEADER_MAX);   /* Slightly longer than needed */
4246                                                       /* The subsequent functions rely on a 0 intitalized buffer */
4247     offset=128;
4248
4249     memmove(dcm_header+offset, "DICM", 4);
4250     offset+=4;
4251
4252     offset_header_len=offset;   /* remember for later */
4253
4254     offset+=12;
4255
4256     /*
4257         (0002,0000)     File Meta Information Group Length  UL
4258         (0002,0001)     File Meta Information Version       OB
4259         (0002,0002)     Media Storage SOP Class UID         UI
4260         (0002,0003)     Media Storage SOP Instance UID      UI
4261         (0002,0010)     Transfer Syntax UID                 UI
4262         (0002,0012)     Implementation Class UID            UI
4263         (0002,0013)     Implementation Version Name         SH
4264     */
4265
4266     offset=dcm_export_create_tag_guint16(dcm_header, DCM_HEADER_MAX, offset,
4267         0x0002, 0x0001, DCM_VR_OB, 0x0100);  /* will result on 00 01 since it is little endian */
4268
4269     offset=dcm_export_create_tag_str(dcm_header, DCM_HEADER_MAX, offset,
4270         0x0002, 0x0002, DCM_VR_UI, sop_class_uid);
4271
4272     offset=dcm_export_create_tag_str(dcm_header, DCM_HEADER_MAX, offset,
4273         0x0002, 0x0003, DCM_VR_UI, sop_instance_uid);
4274
4275     offset=dcm_export_create_tag_str(dcm_header, DCM_HEADER_MAX, offset,
4276         0x0002, 0x0010, DCM_VR_UI, xfer_uid);
4277
4278     offset=dcm_export_create_tag_str(dcm_header, DCM_HEADER_MAX, offset,
4279         0x0002, 0x0012, DCM_VR_UI, WIRESHARK_IMPLEMENTATION_UID);
4280
4281     offset=dcm_export_create_tag_str(dcm_header, DCM_HEADER_MAX, offset,
4282         0x0002, 0x0013, DCM_VR_SH, WIRESHARK_IMPLEMENTATION_VERSION);
4283
4284     /* Finally write the meta header length */
4285     dcm_export_create_tag_guint32(dcm_header, DCM_HEADER_MAX, offset_header_len,
4286         0x0002, 0x0000, DCM_VR_UL, offset-offset_header_len-12);
4287
4288     *dcm_header_len=offset;
4289
4290     return dcm_header;
4291
4292 }
4293
4294 static void
4295 dcm_export_create_object(packet_info *pinfo, dcm_state_assoc_t *assoc, dcm_state_pdv_t *pdv)
4296 {
4297
4298     /* Concat different PDVs into one buffer and add it to export object list
4299        This function caused quite a few crashes, with all the string pointers
4300
4301        Every since the adding fragment_add_seq_next() and process_reassembled_data(),
4302        this function would not need to perform any reassembly anymore, but it's
4303        left unchagned, to still support export, even when global_dcm_reassemble
4304        is not set.
4305
4306        Using process_reassembled_data(), all data will be in the last PDV, and all
4307        it's predecessor will zero data.
4308     */
4309
4310     dicom_eo_t          *eo_info = NULL;
4311
4312     dcm_state_pdv_t     *pdv_curr = NULL;
4313     dcm_state_pdv_t     *pdv_same_pkt = NULL;
4314     dcm_state_pctx_t    *pctx = NULL;
4315
4316     guint8     *pdv_combined = NULL;
4317     guint8     *pdv_combined_curr = NULL;
4318     guint8     *dcm_header = NULL;
4319     guint32     pdv_combined_len = 0;
4320     guint32     dcm_header_len = 0;
4321     guint16     cnt_same_pkt = 1;
4322     gchar      *filename;
4323     const gchar *hostname;
4324
4325     gchar       *sop_class_uid;
4326     gchar       *sop_instance_uid;
4327
4328     /* Calculate total PDV length, i.e. all packets until last PDV without continuation  */
4329     pdv_curr = pdv;
4330     pdv_same_pkt = pdv;
4331     pdv_combined_len=pdv_curr->data_len;
4332
4333     while (pdv_curr->prev && !pdv_curr->prev->is_last_fragment) {
4334         pdv_curr = pdv_curr->prev;
4335         pdv_combined_len += pdv_curr->data_len;
4336     }
4337
4338     /* Count number of PDVs with the same Packet Number */
4339     while (pdv_same_pkt->prev && (pdv_same_pkt->prev->packet_no == pdv_same_pkt->packet_no)) {
4340         pdv_same_pkt = pdv_same_pkt->prev;
4341         cnt_same_pkt += 1;
4342     }
4343
4344     pctx=dcm_state_pctx_get(assoc, pdv_curr->pctx_id, FALSE);
4345
4346     if (strlen(assoc->ae_calling)>0 && strlen(assoc->ae_called)>0 ) {
4347         hostname = ep_strdup_printf("%s <-> %s", assoc->ae_calling, assoc->ae_called);
4348     }
4349     else {
4350         hostname = "AE title(s) unknown";
4351     }
4352
4353     if (pdv->is_storage &&
4354         pdv_curr->sop_class_uid    && strlen(pdv_curr->sop_class_uid)>0 &&
4355         pdv_curr->sop_instance_uid && strlen(pdv_curr->sop_instance_uid)>0) {
4356
4357         sop_class_uid = ep_strndup(pdv_curr->sop_class_uid, MAX_BUF_LEN);
4358         sop_instance_uid = ep_strndup(pdv_curr->sop_instance_uid, MAX_BUF_LEN);
4359
4360         /* Make sure filename does not contain invalid character. Rather conservative.
4361            Eventhough this should be a valid DICOM UID, apply the same filter rules
4362            in case of bogus data.
4363         */
4364         filename = ep_strdup_printf("%06d-%d-%s.dcm", pinfo->fd->num, cnt_same_pkt,
4365             g_strcanon(pdv_curr->sop_instance_uid, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-.", '-'));
4366     }
4367     else {
4368         /* No SOP Instance or SOP Class UID found in PDV. Use wireshark ones */
4369
4370         sop_class_uid = ep_strdup(WIRESHARK_MEDIA_STORAGE_SOP_CLASS_UID);
4371         sop_instance_uid = ep_strdup_printf("%s.%d.%d",
4372             WIRESHARK_MEDIA_STORAGE_SOP_INSTANCE_UID_PREFIX, pinfo->fd->num, cnt_same_pkt);
4373
4374         /* Make sure filename does not contain invalid character. Rather conservative.*/
4375         filename = ep_strdup_printf("%06d-%d-%s.dcm", pinfo->fd->num, cnt_same_pkt,
4376             g_strcanon(pdv->desc, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-.", '-'));
4377
4378     }
4379
4380     if (global_dcm_export_header) {
4381         if (pctx && pctx->xfer_uid && strlen(pctx->xfer_uid)>0) {
4382             dcm_header=dcm_export_create_header(&dcm_header_len, sop_class_uid, sop_instance_uid, pctx->xfer_uid);
4383         }
4384         else {
4385             /* We are running blind, i.e. no presentation context/syntax found.
4386                Don't invent one, so the meta header will miss
4387                the transfer syntax UID tag (even though it is mandatory)
4388             */
4389             dcm_header=dcm_export_create_header(&dcm_header_len, sop_class_uid, sop_instance_uid, NULL);
4390         }
4391     }
4392
4393
4394     if (dcm_header_len + pdv_combined_len >= global_dcm_export_minsize) {
4395         /* Allocate the final size */
4396
4397         /* The complete eo_info structure and its elements will be freed in
4398            export_object.c -> eo_win_destroy_cb() using g_free()
4399         */
4400
4401         pdv_combined = (guint8 *)g_malloc0(dcm_header_len + pdv_combined_len);
4402
4403         pdv_combined_curr = pdv_combined;
4404
4405         if (dcm_header_len != 0) {  /* Will be 0 when global_dcm_export_header is FALSE */
4406             memmove(pdv_combined, dcm_header, dcm_header_len);
4407             pdv_combined_curr += dcm_header_len;
4408         }
4409
4410         /* Copy PDV per PDV to target buffer */
4411         while (!pdv_curr->is_last_fragment) {
4412             memmove(pdv_combined_curr, pdv_curr->data, pdv_curr->data_len);         /* this is a copy not move */
4413             g_free(pdv_curr->data);
4414             pdv_combined_curr += pdv_curr->data_len;
4415             pdv_curr = pdv_curr->next;
4416         }
4417
4418         /* Last packet */
4419         memmove(pdv_combined_curr, pdv->data, pdv->data_len);       /* this is a copy not a move */
4420         g_free(pdv_curr->data);
4421
4422         /* Add to list */
4423         eo_info = (dicom_eo_t *)g_malloc0(sizeof(dicom_eo_t));
4424         eo_info->hostname = g_strdup(hostname);
4425         eo_info->filename = g_strdup(filename);
4426         eo_info->content_type = g_strdup(pdv->desc);
4427
4428         eo_info->payload_data = pdv_combined;
4429         eo_info->payload_len  = dcm_header_len + pdv_combined_len;
4430
4431         tap_queue_packet(dicom_eo_tap, pinfo, eo_info);
4432     }
4433 }
4434
4435 static guint32
4436 dissect_dcm_assoc_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, dcm_state_assoc_t *assoc,
4437                          guint8 pdu_type, guint32 pdu_len)
4438 {
4439     /*
4440      *  Decode association header
4441      */
4442
4443     proto_item *assoc_header_pitem = NULL;
4444     proto_tree *assoc_header_ptree = NULL;      /* Tree for item details */
4445
4446     guint16  assoc_ver;
4447
4448     gchar        *buf_desc = NULL;
4449     const char   *reject_result_desc = "";
4450     const char   *reject_source_desc = "";
4451     const char   *reject_reason_desc = "";
4452     const char   *abort_source_desc = "";
4453     const char   *abort_reason_desc = "";
4454
4455     guint8  reject_result;
4456     guint8  reject_source;
4457     guint8  reject_reason;
4458     guint8  abort_source;
4459     guint8  abort_reason;
4460
4461     buf_desc = (gchar *)ep_alloc0(MAX_BUF_LEN);     /* Valid for this packet */
4462
4463     assoc_header_pitem = proto_tree_add_text(tree, tvb, offset, pdu_len-6, "Association Header");
4464     assoc_header_ptree = proto_item_add_subtree(assoc_header_pitem, ett_assoc_header);
4465
4466     switch (pdu_type) {
4467     case 1:                                     /* Association Request */
4468
4469         assoc_ver = tvb_get_ntohs(tvb, offset);
4470         proto_tree_add_uint(assoc_header_ptree, hf_dcm_assoc_version, tvb, offset, 2, assoc_ver);
4471         offset += 2;
4472
4473         offset += 2;                            /* Two reserved bytes*/
4474
4475         tvb_memcpy(tvb, assoc->ae_called, offset, 16);
4476         assoc->ae_called[AEEND] = 0;
4477         proto_tree_add_string(assoc_header_ptree, hf_dcm_assoc_called, tvb, offset, 16, assoc->ae_called);
4478         offset += 16;
4479
4480         tvb_memcpy(tvb, assoc->ae_calling, offset, 16);
4481         assoc->ae_calling[AEEND] = 0;
4482         proto_tree_add_string(assoc_header_ptree, hf_dcm_assoc_calling, tvb, offset, 16, assoc->ae_calling);
4483         offset += 16;
4484
4485         offset += 32;                           /* 32 reserved bytes */
4486
4487         g_snprintf(buf_desc, MAX_BUF_LEN, "A-ASSOCIATE request %s --> %s",
4488             g_strstrip(assoc->ae_calling), g_strstrip(assoc->ae_called));
4489
4490         offset = dissect_dcm_assoc_detail(tvb, pinfo, assoc_header_ptree, assoc,
4491             offset, pdu_len-offset);
4492
4493         break;
4494     case 2:                                     /* Association Accept */
4495
4496         assoc_ver = tvb_get_ntohs(tvb, offset+2);
4497         proto_tree_add_uint(assoc_header_ptree, hf_dcm_assoc_version, tvb, offset, 2, assoc_ver);
4498         offset += 2;
4499
4500         offset += 2;                            /* Two reserved bytes*/
4501
4502         tvb_memcpy(tvb, assoc->ae_called_resp, offset, 16);
4503         assoc->ae_called_resp[AEEND] = 0;
4504         proto_tree_add_string(assoc_header_ptree, hf_dcm_assoc_called, tvb, offset, 16, assoc->ae_called_resp);
4505         offset += 16;
4506
4507         tvb_memcpy(tvb, assoc->ae_calling_resp, offset, 16);
4508         assoc->ae_calling_resp[AEEND] = 0;
4509         proto_tree_add_string(assoc_header_ptree, hf_dcm_assoc_calling, tvb, offset, 16, assoc->ae_calling_resp);
4510         offset += 16;
4511
4512         offset += 32;                           /* 32 reserved bytes */
4513
4514         g_snprintf(buf_desc, MAX_BUF_LEN, "A-ASSOCIATE accept  %s <-- %s",
4515             g_strstrip(assoc->ae_calling_resp), g_strstrip(assoc->ae_called_resp));
4516
4517         offset = dissect_dcm_assoc_detail(tvb, pinfo, assoc_header_ptree, assoc,
4518             offset, pdu_len-offset);
4519
4520         break;
4521     case 3:                                     /* Association Reject */
4522
4523         offset += 1;                            /* One reserved byte */
4524
4525         reject_result = tvb_get_guint8(tvb, offset);
4526         reject_source = tvb_get_guint8(tvb, offset+1);
4527         reject_reason = tvb_get_guint8(tvb, offset+2);
4528
4529         switch (reject_result) {
4530         case 1:  reject_result_desc = "Reject Permanent"; break;
4531         case 2:  reject_result_desc = "Reject Transient"; break;
4532         default: break;
4533         }
4534
4535         switch (reject_source) {
4536         case 1:
4537             reject_source_desc = "User";
4538             switch (reject_reason) {
4539             case 1:  reject_reason_desc = "No reason given"; break;
4540             case 2:  reject_reason_desc = "Application context name not supported"; break;
4541             case 3:  reject_reason_desc = "Calling AE title not recognized"; break;
4542             case 7:  reject_reason_desc = "Called AE title not recognized"; break;
4543             }
4544             break;
4545         case 2:
4546             reject_source_desc = "Provider (ACSE)";
4547             switch (reject_reason) {
4548             case 1:  reject_reason_desc = "No reason given"; break;
4549             case 2:  reject_reason_desc = "Protocol version not supported"; break;
4550             }
4551             break;
4552         case 3:
4553             reject_source_desc = "Provider (Presentation)";
4554             switch (reject_reason) {
4555             case 1:  reject_reason_desc = "Temporary congestion"; break;
4556             case 2:  reject_reason_desc = "Local limit exceeded"; break;
4557             }
4558             break;
4559         }
4560
4561         proto_tree_add_uint_format(assoc_header_ptree, hf_dcm_assoc_reject_result, tvb,
4562             offset  , 1, reject_result, "Result: %s", reject_result_desc);
4563
4564         proto_tree_add_uint_format(assoc_header_ptree, hf_dcm_assoc_reject_source, tvb,
4565             offset+1, 1, reject_source, "Source: %s", reject_source_desc);
4566
4567         proto_tree_add_uint_format(assoc_header_ptree, hf_dcm_assoc_reject_reason, tvb,
4568             offset+2, 1, reject_reason, "Reason: %s", reject_reason_desc);
4569
4570         offset += 3;
4571
4572         /* Provider aborted */
4573         g_snprintf(buf_desc, MAX_BUF_LEN,"A-ASSOCIATE reject  %s <-- %s (%s)",
4574             g_strstrip(assoc->ae_calling), g_strstrip(assoc->ae_called), reject_reason_desc);
4575
4576         expert_add_info_format(pinfo, assoc_header_pitem,
4577             PI_RESPONSE_CODE, PI_WARN, "Association rejected");
4578
4579         break;
4580     case 5:                                     /* RELEASE Request */
4581
4582         offset += 2;                            /* Two reserved bytes */
4583         buf_desc="A-RELEASE request";
4584
4585         break;
4586     case 6:                                     /* RELEASE Response */
4587
4588         offset += 2;                            /* Two reserved bytes */
4589         buf_desc="A-RELEASE response";
4590
4591         break;
4592     case 7:                                     /* ABORT */
4593
4594         offset += 2;                            /* Two reserved bytes */
4595
4596         abort_source = tvb_get_guint8(tvb, offset);
4597         abort_reason = tvb_get_guint8(tvb, offset+1);
4598
4599         switch (abort_source) {
4600         case 0:
4601             abort_source_desc = "User";
4602             abort_reason_desc = "N/A";          /* No details can be provided*/
4603             break;
4604         case 1:
4605             /* reserved */
4606             break;
4607         case 2:
4608             abort_source_desc = "Provider";
4609
4610             switch (abort_reason) {
4611             case 0:  abort_reason_desc = "Not specified"; break;
4612             case 1:  abort_reason_desc = "Unrecognized PDU"; break;
4613             case 2:  abort_reason_desc = "Unexpected PDU"; break;
4614             case 4:  abort_reason_desc = "Unrecognized PDU parameter"; break;
4615             case 5:  abort_reason_desc = "Unexpected PDU parameter"; break;
4616             case 6:  abort_reason_desc = "Invalid PDU parameter value"; break;
4617             }
4618
4619             break;
4620         }
4621
4622         proto_tree_add_uint_format(assoc_header_ptree, hf_dcm_assoc_abort_source,
4623             tvb, offset  , 1, abort_source, "Source: %s", abort_source_desc);
4624
4625         proto_tree_add_uint_format(assoc_header_ptree, hf_dcm_assoc_abort_reason,
4626             tvb, offset+1, 1, abort_reason, "Reason: %s", abort_reason_desc);
4627         offset += 2;
4628
4629         if (abort_source == 0) {
4630             /* User aborted */
4631             g_snprintf(buf_desc, MAX_BUF_LEN,"ABORT %s --> %s",
4632                 g_strstrip(assoc->ae_calling), g_strstrip(assoc->ae_called));
4633         }
4634         else {
4635             /* Provider aborted, slightly more information */
4636             g_snprintf(buf_desc, MAX_BUF_LEN,"ABORT %s <-- %s (%s)",
4637                 g_strstrip(assoc->ae_calling), g_strstrip(assoc->ae_called), abort_reason_desc);
4638         }
4639
4640         expert_add_info_format(pinfo, assoc_header_pitem,
4641             PI_RESPONSE_CODE, PI_WARN, "Association aborted");
4642
4643         break;
4644     }
4645
4646     proto_item_set_text(assoc_header_pitem, "%s", buf_desc);
4647     col_append_str(pinfo->cinfo, COL_INFO, buf_desc);
4648
4649     col_clear(pinfo->cinfo, COL_INFO);
4650     col_set_str(pinfo->cinfo, COL_INFO, se_strdup(buf_desc));   /* requires SE not EP memory */
4651
4652     /* proto_item and proto_tree are one and the same */
4653     proto_item_append_text(tree, ", %s", buf_desc);
4654
4655     return offset;
4656 }
4657
4658 static void
4659 dissect_dcm_assoc_item(tvbuff_t *tvb, proto_tree *tree, guint32 offset,
4660                        const gchar *pitem_prefix, int item_value_type,
4661                        gchar **item_value, const gchar **item_description,
4662                        int *hf_type, int *hf_len, int *hf_value, int ett_subtree)
4663 {
4664     /*
4665      *  Decode one item in a association request or response. Lookup UIDs if requested
4666      *
4667      *  If dcm_tree is set, create a Subtree Node with summary and three elements
4668      *  - item_type
4669      *  - item_len
4670      *  - value
4671      *
4672      */
4673
4674     proto_tree *assoc_item_ptree = NULL;        /* Tree for item details */
4675     proto_item *assoc_item_pitem = NULL;
4676     dcm_uid_t  *uid = NULL;
4677
4678     guint32 item_number = 0;
4679
4680     guint8  item_type = 0;
4681     guint16 item_len  = 0;
4682
4683     gchar *buf_desc = NULL;             /* Used for item text */
4684
4685     *item_value = NULL;
4686     *item_description = NULL;
4687
4688     buf_desc = (gchar *)ep_alloc0(MAX_BUF_LEN); /* Valid for this packet */
4689
4690     item_type = tvb_get_guint8(tvb, offset);
4691     item_len  = tvb_get_ntohs(tvb, offset+2);
4692
4693     assoc_item_pitem = proto_tree_add_text(tree, tvb, offset, item_len+4, "%s", pitem_prefix);
4694     assoc_item_ptree = proto_item_add_subtree(assoc_item_pitem, ett_subtree);
4695
4696     proto_tree_add_uint(assoc_item_ptree, *hf_type, tvb, offset, 1, item_type);
4697     proto_tree_add_uint(assoc_item_ptree, *hf_len, tvb, offset+2, 2, item_len);
4698
4699     switch (item_value_type) {
4700     case DCM_ITEM_VALUE_TYPE_UID:
4701         *item_value = (gchar *)tvb_get_ephemeral_string(tvb, offset+4, item_len);
4702
4703         uid = (dcm_uid_t *)g_hash_table_lookup(dcm_uid_table, (gpointer) *item_value);
4704         if (uid) {
4705             *item_description = uid->name;
4706             g_snprintf(buf_desc, MAX_BUF_LEN, "%s (%s)", *item_description, *item_value);
4707         }
4708         else {
4709             /* Unknown UID, or no UID at all */
4710             g_snprintf(buf_desc, MAX_BUF_LEN, "%s", *item_value);
4711         }
4712
4713         proto_item_append_text(assoc_item_pitem, "%s", buf_desc);
4714         proto_tree_add_string(assoc_item_ptree, *hf_value, tvb, offset+4, item_len, buf_desc);
4715
4716         break;
4717
4718     case DCM_ITEM_VALUE_TYPE_STRING:
4719         *item_value = (gchar *)tvb_get_ephemeral_string(tvb, offset+4, item_len);
4720         proto_item_append_text(assoc_item_pitem, "%s", *item_value);
4721         proto_tree_add_string(assoc_item_ptree, *hf_value, tvb, offset+4, item_len, *item_value);
4722
4723         break;
4724
4725     case DCM_ITEM_VALUE_TYPE_UINT32:
4726         item_number = tvb_get_ntohl(tvb, offset+4);
4727         *item_value = (gchar *)se_alloc0(MAX_BUF_LEN);
4728         g_snprintf(*item_value, MAX_BUF_LEN, "%d", item_number);
4729
4730         proto_item_append_text(assoc_item_pitem, "%s", *item_value);
4731         proto_tree_add_item(assoc_item_ptree, *hf_value, tvb, offset+4, 4, FALSE);
4732
4733         break;
4734
4735     default:
4736         break;
4737     }
4738 }
4739
4740
4741 static void
4742 dissect_dcm_pctx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4743                  dcm_state_assoc_t *assoc, guint32 offset, guint32 len,
4744                  const gchar *pitem_prefix, gboolean is_assoc_request)
4745 {
4746     /*
4747         Decode a presentation context item in a Association Request or Response
4748         In the response, set the accepted transfer syntax, if any
4749     */
4750
4751     proto_tree *pctx_ptree = NULL;      /* Tree for presentation context details */
4752     proto_item *pctx_pitem = NULL;
4753
4754     dcm_state_pctx_t *pctx = NULL;
4755
4756     guint8  item_type = 0;
4757     guint16 item_len = 0;
4758
4759     guint8  pctx_id = 0;                    /* Presentation Context ID */
4760     guint8  pctx_result = 0;
4761
4762     const char  *pctx_result_desc = "";
4763
4764     gchar *pctx_abss_uid  = NULL;           /* Abstract Syntax UID alias SOP Class UID */
4765     const gchar *pctx_abss_desc = NULL;     /* Description of UID */
4766
4767     gchar *pctx_xfer_uid = NULL;            /* Transfer Syntax UID */
4768     const gchar *pctx_xfer_desc = NULL;     /* Description of UID */
4769
4770     gchar *buf_desc = NULL;         /* Used in infor mode for item text */
4771
4772     guint32 endpos = 0;
4773     int     cnt_abbs = 0;           /* Number of Abstract Syntax Items */
4774     int     cnt_xfer = 0;           /* Number of Trasfer Syntax Items */
4775
4776     buf_desc = (gchar *)ep_alloc0(MAX_BUF_LEN); /* Valid for this packet */
4777
4778     endpos = offset + len;
4779
4780     item_type = tvb_get_guint8(tvb, offset-4);
4781     item_len  = tvb_get_ntohs(tvb, offset-2);
4782
4783     pctx_pitem = proto_tree_add_text(tree, tvb, offset-4, item_len+4, "%s", pitem_prefix);
4784     pctx_ptree = proto_item_add_subtree(pctx_pitem, ett_assoc_pctx);
4785
4786     pctx_id     = tvb_get_guint8(tvb, offset);
4787     pctx_result = tvb_get_guint8(tvb, 2 + offset);      /* only set in responses, otherwise reserved and 0x00 */
4788
4789     /* Find or create dicom context object */
4790     pctx = dcm_state_pctx_get(assoc, pctx_id, TRUE);
4791     if (pctx == NULL) { /* Internal error. Failed to create data structre */
4792         return;
4793     }
4794
4795     proto_tree_add_uint(pctx_ptree, hf_dcm_assoc_item_type, tvb, offset-4, 2, item_type);
4796     proto_tree_add_uint(pctx_ptree, hf_dcm_assoc_item_len,  tvb, offset-2, 2, item_len);
4797
4798     proto_tree_add_uint_format(pctx_ptree, hf_dcm_pctx_id, tvb, offset, 1, pctx_id, "Context ID: 0x%02x", pctx_id);
4799
4800     if (!is_assoc_request) {
4801         /* Accociation response. */
4802
4803         switch (pctx_result) {
4804         case 0:  pctx_result_desc = "Accept"; break;
4805         case 1:  pctx_result_desc = "User Reject"; break;
4806         case 2:  pctx_result_desc = "No Reason"; break;
4807         case 3:  pctx_result_desc = "Abstract Syntax Unsupported"; break;
4808         case 4:  pctx_result_desc = "Transfer Syntax Unsupported"; break;
4809         }
4810
4811         proto_tree_add_uint_format(pctx_ptree, hf_dcm_pctx_result, tvb, offset+2, 1,
4812             pctx_result, "Result: %s (0x%x)", pctx_result_desc, pctx_result);
4813     }
4814
4815     offset += 4;
4816     while (offset < endpos) {
4817
4818         item_type = tvb_get_guint8(tvb, offset);
4819         item_len = tvb_get_ntohs(tvb, 2 + offset);
4820
4821         offset += 4;
4822         switch (item_type) {
4823         case 0x30:              /* Abstract syntax */
4824
4825             /* Parse Item. Works also in info mode where dcm_pctx_tree is NULL */
4826             dissect_dcm_assoc_item(tvb, pctx_ptree, offset-4,
4827                 "Abstract Syntax: ", DCM_ITEM_VALUE_TYPE_UID, &pctx_abss_uid, &pctx_abss_desc,
4828                 &hf_dcm_assoc_item_type, &hf_dcm_assoc_item_len, &hf_dcm_pctx_abss_syntax, ett_assoc_pctx_abss);
4829
4830             cnt_abbs += 1;
4831             offset += item_len;
4832             break;
4833
4834         case 0x40:              /* Transfer syntax */
4835
4836             dissect_dcm_assoc_item(tvb, pctx_ptree, offset-4,
4837                 "Transfer Syntax: ", DCM_ITEM_VALUE_TYPE_UID, &pctx_xfer_uid, &pctx_xfer_desc,
4838                 &hf_dcm_assoc_item_type, &hf_dcm_assoc_item_len, &hf_dcm_pctx_xfer_syntax, ett_assoc_pctx_xfer);
4839
4840             /*
4841                In a correct Association Response, only one Transfer syntax shall be present.
4842                Therefore, pctx_xfer_uid, pctx_xfer_desc are used for the accept scenario in the info mode
4843             */
4844
4845             if (!is_assoc_request && pctx_result == 0) {
4846                 /* Association Response, Context Accepted */
4847                 dcm_set_syntax(pctx, pctx_xfer_uid, pctx_xfer_desc);
4848             }
4849             cnt_xfer += 1;
4850             offset += item_len;
4851             break;
4852
4853         default:
4854             offset += item_len;
4855             break;
4856         }
4857     }
4858
4859     if (is_assoc_request) {
4860
4861         if (cnt_abbs<1) {
4862             expert_add_info_format(pinfo, pctx_pitem, PI_MALFORMED, PI_ERROR,
4863                 "No Abstract Syntax provided for this Presentation Context");
4864             return;
4865         }
4866         else if (cnt_abbs>1) {
4867             expert_add_info_format(pinfo, pctx_pitem, PI_MALFORMED, PI_ERROR,
4868                 "More than one Abstract Syntax provided for this Presentation Context");
4869             return;
4870         }
4871
4872         if (cnt_xfer==0) {
4873             expert_add_info_format(pinfo, pctx_pitem, PI_MALFORMED, PI_ERROR,
4874                 "No Transfer Syntax provided for this Presentation Context");
4875             return;
4876         }
4877
4878         if (pctx_abss_uid==NULL) {
4879             expert_add_info_format(pinfo, pctx_pitem, PI_MALFORMED, PI_ERROR,
4880                 "No Abstract Syntax UID found for this Presentation Context");
4881             return;
4882         }
4883
4884     }
4885     else {
4886
4887         if (cnt_xfer>1) {
4888             expert_add_info_format(pinfo, pctx_pitem, PI_MALFORMED, PI_ERROR,
4889                 "Only one Transfer Syntax allowed in a Association Response");
4890             return;
4891         }
4892     }
4893
4894     if (pctx->abss_uid==NULL) {
4895         /* Permanent copy information into structure */
4896         pctx->abss_uid  = se_strdup(pctx_abss_uid);
4897         pctx->abss_desc = se_strdup(pctx_abss_desc);
4898     }
4899
4900     /*
4901       Copy to buffer first, because proto_item_append_text()
4902       crashed for an unknown reason using 'ID 0x%02x, %s, %s'
4903       and in my opinion correctly set parameters.
4904     */
4905
4906     if (is_assoc_request) {
4907         if (pctx_abss_desc == NULL) {
4908             g_snprintf(buf_desc, MAX_BUF_LEN, "%s", pctx_abss_uid);
4909         }
4910         else {
4911             g_snprintf(buf_desc, MAX_BUF_LEN, "%s (%s)", pctx_abss_desc, pctx_abss_uid);
4912         }
4913     }
4914     else
4915     {
4916         /* g_snprintf() does not like NULL pointers */
4917
4918         if (pctx_result==0) {
4919             /* Accepted */
4920             g_snprintf(buf_desc, MAX_BUF_LEN, "ID 0x%02x, %s, %s, %s",
4921                 pctx_id, pctx_result_desc,
4922                 dcm_uid_or_desc(pctx->xfer_uid, pctx->xfer_desc),
4923                 dcm_uid_or_desc(pctx->abss_uid, pctx->abss_desc));
4924         }
4925         else {
4926             /* Rejected */
4927             g_snprintf(buf_desc, MAX_BUF_LEN, "ID 0x%02x, %s, %s",
4928                 pctx_id, pctx_result_desc,
4929                 dcm_uid_or_desc(pctx->abss_uid, pctx->abss_desc));
4930         }
4931     }
4932     proto_item_append_text(pctx_pitem, "%s", buf_desc);
4933
4934 }
4935
4936 static void
4937 dissect_dcm_userinfo(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 len, const gchar *pitem_prefix)
4938 {
4939     /*
4940         Decode the user info item in a Association Request or Response
4941     */
4942
4943     proto_item *userinfo_pitem = NULL;
4944     proto_tree *userinfo_ptree = NULL;  /* Tree for presentation context details */
4945
4946     guint8  item_type;
4947     guint16 item_len;
4948
4949     gboolean first_item=TRUE;
4950
4951     gchar *info_max_pdu=NULL;
4952     gchar *info_impl_uid=NULL;
4953     gchar *info_impl_version=NULL;
4954     const gchar *dummy=NULL;
4955
4956     guint32 endpos;
4957
4958     endpos = offset + len;
4959
4960     item_type = tvb_get_guint8(tvb, offset-4);
4961     item_len  = tvb_get_ntohs(tvb, offset-2);
4962
4963     userinfo_pitem = proto_tree_add_text(tree, tvb, offset-4, item_len+4, "%s", pitem_prefix);
4964     userinfo_ptree = proto_item_add_subtree(userinfo_pitem, ett_assoc_info);
4965
4966     proto_tree_add_uint(userinfo_ptree, hf_dcm_assoc_item_type, tvb, offset-4, 2, item_type);
4967     proto_tree_add_uint(userinfo_ptree, hf_dcm_assoc_item_len, tvb, offset-2, 2, item_len);
4968
4969     while (offset < endpos) {
4970
4971         item_type = tvb_get_guint8(tvb, offset);
4972         item_len = tvb_get_ntohs(tvb, 2 + offset);
4973
4974         offset += 4;
4975         switch (item_type) {
4976         case 0x51:              /* Max length */
4977
4978             dissect_dcm_assoc_item(tvb, userinfo_ptree, offset-4,
4979                 "Max PDU Length: ", DCM_ITEM_VALUE_TYPE_UINT32, &info_max_pdu, &dummy,
4980                 &hf_dcm_assoc_item_type, &hf_dcm_assoc_item_len, &hf_dcm_pdu_maxlen, ett_assoc_info_uid);
4981
4982             if (!first_item) {
4983                 proto_item_append_text(userinfo_pitem, ", ");
4984             }
4985             proto_item_append_text(userinfo_pitem, "Max PDU Length %s", info_max_pdu);
4986             first_item=FALSE;
4987
4988             offset += item_len;
4989             break;
4990
4991         case 0x52:              /* UID */
4992
4993             /* Parse Item. Works also in info mode where dcm_pctx_tree is NULL */
4994             dissect_dcm_assoc_item(tvb, userinfo_ptree, offset-4,
4995                 "Implementation UID: ", DCM_ITEM_VALUE_TYPE_STRING, &info_impl_uid, &dummy,
4996                 &hf_dcm_assoc_item_type, &hf_dcm_assoc_item_len, &hf_dcm_info_uid, ett_assoc_info_uid);
4997
4998             if (!first_item) {
4999                 proto_item_append_text(userinfo_pitem, ", ");
5000             }
5001             proto_item_append_text(userinfo_pitem, "Implementation UID %s", info_impl_uid);
5002             first_item=FALSE;
5003
5004             offset += item_len;
5005             break;
5006
5007         case 0x55:              /* version */
5008
5009             dissect_dcm_assoc_item(tvb, userinfo_ptree, offset-4,
5010                 "Implementation Version: ", DCM_ITEM_VALUE_TYPE_STRING, &info_impl_version, &dummy,
5011                 &hf_dcm_assoc_item_type, &hf_dcm_assoc_item_len, &hf_dcm_info_version, ett_assoc_info_version);
5012
5013             if (!first_item) {
5014                 proto_item_append_text(userinfo_pitem, ", ");
5015             }
5016             proto_item_append_text(userinfo_pitem, "Version %s", info_impl_version);
5017             first_item=FALSE;
5018
5019             offset += item_len;
5020             break;
5021
5022         case 0x53:              /* async negotion */
5023             /* hf_dcm_async */
5024             offset += item_len;
5025             break;
5026
5027         default:
5028             offset += item_len;
5029             break;
5030         }
5031     }
5032 }
5033
5034
5035 static guint32
5036 dissect_dcm_assoc_detail(tvbuff_t *tvb, packet_info *pinfo, proto_item *ti,
5037                          dcm_state_assoc_t *assoc, guint32 offset, guint32 len)
5038 {
5039     proto_tree *assoc_tree  = NULL;     /* Tree for PDU details */
5040
5041     guint8  item_type;
5042     guint16 item_len;
5043
5044     guint32 endpos;
5045
5046     gchar *item_value = NULL;
5047     const gchar *item_description = NULL;
5048
5049     endpos = offset + len;
5050
5051     assoc_tree = proto_item_add_subtree(ti, ett_assoc);
5052     while (offset < endpos) {
5053
5054         item_type = tvb_get_guint8(tvb, offset);
5055         item_len  = tvb_get_ntohs(tvb, 2 + offset);
5056
5057         if (item_len == 0) {
5058             expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR, "Invalid Association Item Length");
5059             return endpos;
5060         }
5061
5062         offset += 4;
5063
5064         switch (item_type) {
5065         case 0x10:              /* Application context */
5066             dissect_dcm_assoc_item(tvb, assoc_tree, offset-4,
5067                 "Application Context: ", DCM_ITEM_VALUE_TYPE_UID, &item_value, &item_description,
5068                 &hf_dcm_assoc_item_type, &hf_dcm_assoc_item_len, &hf_dcm_actx, ett_assoc_actx);
5069
5070             offset += item_len;
5071             break;
5072
5073         case 0x20:              /* Presentation context request */
5074             dissect_dcm_pctx(tvb, pinfo, assoc_tree, assoc, offset, item_len,
5075                 "Presentation Context: ", TRUE);
5076             offset += item_len;
5077             break;
5078
5079         case 0x21:              /* Presentation context reply */
5080             dissect_dcm_pctx(tvb, pinfo, assoc_tree, assoc, offset, item_len,
5081                 "Presentation Context: ", FALSE);
5082             offset += item_len;
5083             break;
5084
5085         case 0x50:              /* User Info */
5086             dissect_dcm_userinfo(tvb, assoc_tree, offset, item_len, "User Info: ");
5087             offset += item_len;
5088             break;
5089
5090         default:
5091             offset += item_len;
5092             break;
5093         }
5094     }
5095
5096     return offset;
5097
5098 }
5099
5100 static guint32
5101 dissect_dcm_pdv_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5102                        dcm_state_assoc_t *assoc, guint32 offset, dcm_state_pdv_t **pdv)
5103 {
5104     /* Dissect Context and Flags of a PDV and create new PDV stucture */
5105
5106     proto_item *pdv_ctx_pitem = NULL;
5107     proto_item *pdv_flags_pitem = NULL;
5108
5109     dcm_state_pctx_t    *pctx = NULL;
5110     dcm_state_pdv_t     *pdv_first_data = NULL;
5111
5112     const gchar *desc_flag = NULL;      /* Flag Description in tree */
5113     gchar *desc_header = NULL;          /* Used for PDV description */
5114
5115     guint8  flags = 0;
5116     guint8  pctx_id = 0;
5117
5118     /* 1 Byte Context */
5119     pctx_id = tvb_get_guint8(tvb, offset);
5120     pctx = dcm_state_pctx_get(assoc, pctx_id, FALSE);
5121
5122     if (pctx && pctx->xfer_uid) {
5123         proto_tree_add_uint_format(tree, hf_dcm_pdv_ctx, tvb, offset, 1,
5124             pctx_id, "Context: 0x%02x (%s, %s)", pctx_id,
5125         dcm_uid_or_desc(pctx->xfer_uid, pctx->xfer_desc),
5126         dcm_uid_or_desc(pctx->abss_uid, pctx->abss_desc));
5127     }
5128     else {
5129         pdv_ctx_pitem=proto_tree_add_uint_format(tree, hf_dcm_pdv_ctx, tvb,  offset, 1,
5130             pctx_id, "Context: 0x%02x not found. A-ASSOCIATE request not found in capture.", pctx_id);
5131
5132         expert_add_info_format(pinfo, pdv_ctx_pitem, PI_MALFORMED, PI_ERROR, "Invalid Presentation Context ID");
5133
5134         if (pctx == NULL) {
5135             /* only create presentation context, if it does not yet exist */
5136
5137             /* Create fake PCTX and guess Syntax ILE, ELE, EBE */
5138             pctx = dcm_state_pctx_new(assoc, pctx_id);
5139
5140             /* To be done: Guess Syntax */
5141             pctx->syntax = DCM_UNK;
5142         }
5143     }
5144     offset +=1;
5145
5146     /* Create PDV structure:
5147
5148        Since we can have multiple PDV per packet (offset) and
5149        multiple merged packets per PDV (the tvb raw_offset)
5150        we need both values to uniquely identify a PDV
5151     */
5152
5153     *pdv = dcm_state_pdv_get(pctx, pinfo->fd->num, tvb_raw_offset(tvb)+offset, TRUE);
5154     if (*pdv == NULL) {
5155         return 0;                   /* Failed to allocate memory */
5156     }
5157
5158     /* 1 Byte Flag */
5159     flags = tvb_get_guint8(tvb, offset);
5160
5161     (*pdv)->pctx_id = pctx_id;
5162
5163     desc_header=(gchar *)se_alloc0(MAX_BUF_LEN);        /* Valid for this capture, since we return this buffer */
5164
5165     switch (flags) {
5166     case 0:     /* 00 */
5167         desc_flag = "Data, More Fragments";
5168
5169         (*pdv)->is_flagvalid = TRUE;
5170         (*pdv)->is_command = FALSE;
5171         (*pdv)->is_last_fragment = FALSE;
5172         (*pdv)->syntax = pctx->syntax;      /* Inherit syntax for data PDVs*/
5173         break;
5174
5175     case 2:     /* 10 */
5176         desc_flag = "Data, Last Fragment";
5177
5178         (*pdv)->is_flagvalid = TRUE;
5179         (*pdv)->is_command = FALSE;
5180         (*pdv)->is_last_fragment = TRUE;
5181         (*pdv)->syntax = pctx->syntax;      /* Inherit syntax for data PDVs*/
5182         break;
5183
5184     case 1:     /* 01 */
5185         desc_flag = "Command, More Fragments";
5186         g_snprintf(desc_header, MAX_BUF_LEN, "Command");                /* Will be overwritten with real command tag */
5187
5188         (*pdv)->is_flagvalid = TRUE;
5189         (*pdv)->is_command = TRUE;
5190         (*pdv)->is_last_fragment = FALSE;
5191         (*pdv)->syntax = DCM_ILE;           /* Command tags are always little endian*/
5192         break;
5193
5194     case 3:     /* 11 */
5195         desc_flag = "Command, Last Fragment";
5196         g_snprintf(desc_header, MAX_BUF_LEN, "Command");
5197
5198         (*pdv)->is_flagvalid = TRUE;
5199         (*pdv)->is_command = TRUE;
5200         (*pdv)->is_last_fragment = TRUE;
5201         (*pdv)->syntax = DCM_ILE;           /* Command tags are always little endian*/
5202         break;
5203
5204     default:
5205         desc_flag = "Invalid Flags";
5206         g_snprintf(desc_header, MAX_BUF_LEN, "Invalid Flags");
5207
5208         (*pdv)->is_flagvalid = FALSE;
5209         (*pdv)->is_command = FALSE;
5210         (*pdv)->is_last_fragment = FALSE;
5211         (*pdv)->syntax = DCM_UNK;
5212     }
5213
5214     if (flags == 0 || flags == 2) {
5215         /* Data PDV */
5216         pdv_first_data = dcm_state_pdv_get_obj_start(*pdv);
5217
5218         if (pdv_first_data->prev && pdv_first_data->prev->is_command) {
5219             /* Every Data PDV sequence should be preceeded by a Command PDV,
5220                so we should always hit this for a correct capture
5221             */
5222
5223             if (pctx->abss_desc && g_str_has_suffix(pctx->abss_desc, "Storage")) {
5224                 /* Should be done far more intelligent, e.g. does not catch the (Retired) ones */
5225                 if (flags == 0) {
5226                     g_snprintf(desc_header, MAX_BUF_LEN, "%s Fragment", pctx->abss_desc);
5227                 }
5228                 else {
5229                     g_snprintf(desc_header, MAX_BUF_LEN, "%s", pctx->abss_desc);
5230                 }
5231                 (*pdv)->is_storage = TRUE;
5232             }
5233             else {
5234                 /* Use previous command and append DATA*/
5235                 g_snprintf(desc_header, MAX_BUF_LEN, "%s-DATA", pdv_first_data->prev->desc);
5236             }
5237         }
5238         else {
5239             g_snprintf(desc_header, MAX_BUF_LEN, "DATA");
5240         }
5241     }
5242
5243     (*pdv)->desc = desc_header;
5244
5245     pdv_flags_pitem = proto_tree_add_uint_format(tree, hf_dcm_pdv_flags, tvb, offset, 1,
5246         flags, "Flags: 0x%02x (%s)", flags, desc_flag);
5247
5248     if (flags>3) {
5249         expert_add_info_format(pinfo, pdv_flags_pitem, PI_MALFORMED, PI_ERROR, "Invalid Flags");
5250     }
5251     offset +=1;
5252
5253     return offset;
5254 }
5255
5256 static guint32
5257 dissect_dcm_tag_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, dcm_state_pdv_t *pdv,
5258                       guint32 offset, guint16 grp, guint16 elm,
5259                       guint32 vl, guint32 vl_max, const gchar* vr, gchar **tag_value)
5260 {
5261     /* Based on the value representation, decode the value of one tag. Returns new offset */
5262
5263     proto_item *pitem = NULL;
5264
5265     gboolean is_little_endian;
5266
5267     if (pdv->syntax == DCM_EBE) is_little_endian = FALSE;
5268     else                        is_little_endian = TRUE;
5269
5270
5271     /* ---------------------------------------------------------------------------
5272        Potentially long types. Obey vl_max
5273        ---------------------------------------------------------------------------
5274     */
5275
5276     if ((strncmp(vr, "AE", 2) == 0) || (strncmp(vr, "AS", 2) == 0) || (strncmp(vr, "CS", 2) == 0) ||
5277         (strncmp(vr, "DA", 2) == 0) || (strncmp(vr, "DS", 2) == 0) || (strncmp(vr, "DT", 2) == 0) ||
5278         (strncmp(vr, "IS", 2) == 0) || (strncmp(vr, "LO", 2) == 0) || (strncmp(vr, "LT", 2) == 0) ||
5279         (strncmp(vr, "PN", 2) == 0) || (strncmp(vr, "SH", 2) == 0) || (strncmp(vr, "ST", 2) == 0) ||
5280         (strncmp(vr, "TM", 2) == 0) || (strncmp(vr, "UI", 2) == 0) || (strncmp(vr, "UT", 2) == 0) ) {
5281         /* 15 ways to represent a string ... */
5282
5283         gchar   *vals;
5284         dcm_uid_t *uid = NULL;
5285         guint8 val8;
5286
5287         val8 = tvb_get_guint8(tvb, offset + vl_max - 1);
5288         if (val8 == 0x00) {
5289             /* Last byte of string is 0x00, i.e. padded */
5290             vals = tvb_format_text(tvb, offset, vl_max - 1);
5291         }
5292         else {
5293             vals = tvb_format_text(tvb, offset, vl_max);
5294         }
5295
5296         if ((strncmp(vr, "UI", 2) == 0)) {
5297             /* This is a UID. Attempt a lookup. Will only return something for classes of course */
5298
5299             uid = (dcm_uid_t *)g_hash_table_lookup(dcm_uid_table, (gpointer) vals);
5300             if (uid) {
5301                 g_snprintf(*tag_value, MAX_BUF_LEN, "%s (%s)", vals, uid->name);
5302             }
5303             else {
5304                 g_snprintf(*tag_value, MAX_BUF_LEN, "%s", vals);
5305             }
5306         }
5307         else {
5308             if (strlen(vals) > 50) {
5309                 g_snprintf(*tag_value, MAX_BUF_LEN, "%-50.50s...", vals);
5310             }
5311             else {
5312                 g_snprintf(*tag_value, MAX_BUF_LEN, "%s", vals);
5313             }
5314         }
5315         proto_tree_add_string_format(tree, hf_dcm_tag_value_str, tvb, offset, vl_max, *tag_value, "%-8.8s%s", "Value:", *tag_value);
5316
5317         if (grp == 0x0000 && elm == 0x0902) {
5318             /* The error comment */
5319             pdv->comment = se_strdup(g_strstrip(vals));
5320         }
5321     }
5322     else if ((strncmp(vr, "OB", 2) == 0) || (strncmp(vr, "OF", 2) == 0) ||
5323              (strncmp(vr, "OW", 2) == 0)) {
5324         /* Array of Bytes, Float or Words. Don't perform any decoding */
5325
5326         proto_tree_add_bytes_format(tree, hf_dcm_tag_value_byte, tvb, offset, vl_max,
5327             NULL, "%-8.8s%s", "Value:", "(binary)");
5328
5329         g_snprintf(*tag_value, MAX_BUF_LEN, "(binary)");
5330     }
5331     else if (strncmp(vr, "UN", 2) == 0) {
5332         /* Usually the case for private tags in implicit syntax, since tag was not found and vr not specified */
5333         guint8    val8;
5334         gchar    *vals;
5335         guint32  i;
5336
5337         /* String detector, i.e. check if we only have alpha-numeric character */
5338         gboolean        is_string = TRUE;
5339         gboolean        is_padded = FALSE;
5340
5341         for (i = 0; i < vl_max ; i++) {
5342             val8 = tvb_get_guint8(tvb, offset + i);
5343
5344             if ((val8 == 0x09) || (val8 == 0x0A) || (val8 == 0x0D)) {
5345                 /* TAB, LF, CR */
5346             }
5347             else if ((val8 >= 0x20) && (val8 <= 0x7E)) {
5348                 /* No extended ASCII, 0-9, A-Z, a-z */
5349             }
5350             else if ((i == vl_max -1) && (val8 == 0x00)) {
5351                 /* Last Byte can be null*/
5352                 is_padded = TRUE;
5353             }
5354             else {
5355                 /* Here's the code */
5356                 is_string = FALSE;
5357             }
5358         }
5359
5360         if (is_string) {
5361             vals = tvb_format_text(tvb, offset, (is_padded ? vl_max - 1 : vl_max));
5362             proto_tree_add_string_format(tree, hf_dcm_tag_value_str, tvb, offset, vl_max,
5363                 vals, "%-8.8s%s", "Value:", vals);
5364
5365             g_snprintf(*tag_value, MAX_BUF_LEN, "%s", vals);
5366         }
5367         else {
5368             proto_tree_add_bytes_format(tree, hf_dcm_tag_value_byte, tvb, offset, vl_max,
5369                 NULL, "%-8.8s%s", "Value:", "(binary)");
5370
5371             g_snprintf(*tag_value, MAX_BUF_LEN, "(binary)");
5372         }
5373     }
5374     /* ---------------------------------------------------------------------------
5375        Smaller types. vl/vl_max are not used. Fixed item length from 2 to 8 bytes
5376        ---------------------------------------------------------------------------
5377     */
5378     else if (strncmp(vr, "AT", 2) == 0)  {      /* Attribute Tag */
5379         /* 2*2 Bytes */
5380
5381         guint16 at_grp;
5382         guint16 at_elm;
5383
5384         if (is_little_endian)   at_grp = tvb_get_letohs(tvb, offset);
5385         else                    at_grp = tvb_get_ntohs(tvb, offset);
5386
5387         if (is_little_endian)   at_elm = tvb_get_letohs(tvb, offset);
5388         else                    at_elm = tvb_get_ntohs(tvb, offset);
5389
5390         proto_tree_add_uint_format(tree, hf_dcm_tag_value_32u, tvb, offset, 4,
5391             (at_grp << 16) | at_elm, "%-8.8s%04x,%04x", "Value:", at_grp, at_elm);
5392
5393         g_snprintf(*tag_value, MAX_BUF_LEN, "(%04x,%04x)", at_grp, at_elm);
5394     }
5395     else if (strncmp(vr, "FL", 2) == 0)  {      /* Single Float */
5396
5397         gfloat valf;
5398
5399         if (is_little_endian) valf = tvb_get_letohieee_float(tvb, offset);
5400         else                  valf = tvb_get_ntohieee_float(tvb, offset);
5401
5402         proto_tree_add_bytes_format(tree, hf_dcm_tag_value_byte, tvb, offset, 4,
5403             NULL, "%-8.8s%f", "Value:", valf);
5404
5405         g_snprintf(*tag_value, MAX_BUF_LEN, "%f", valf);
5406     }
5407     else if (strncmp(vr, "FD", 2) == 0)  {      /* Double Float */
5408
5409         gdouble vald;
5410
5411         if (is_little_endian) vald = tvb_get_letohieee_double(tvb, offset);
5412         else                  vald = tvb_get_ntohieee_double(tvb, offset);
5413
5414         proto_tree_add_bytes_format(tree, hf_dcm_tag_value_byte, tvb, offset, 8,
5415             NULL, "%-8.8s%f", "Value:", vald);
5416
5417         g_snprintf(*tag_value, MAX_BUF_LEN, "%f", vald);
5418     }
5419     else if (strncmp(vr, "SL", 2) == 0)  {          /* Signed Long */
5420         gint32  val32;
5421
5422         if (is_little_endian)   val32 = tvb_get_letohl(tvb, offset);
5423         else                    val32 = tvb_get_ntohl(tvb, offset);
5424
5425         proto_tree_add_int_format(tree, hf_dcm_tag_value_32s, tvb, offset, 4,
5426             val32, "%-8.8s%d", "Value:", val32);
5427
5428         g_snprintf(*tag_value, MAX_BUF_LEN, "%d", val32);
5429     }
5430     else if (strncmp(vr, "SS", 2) == 0)  {          /* Signed Short */
5431         gint16  val16;
5432
5433         if (is_little_endian)   val16 = tvb_get_letohs(tvb, offset);
5434         else                    val16 = tvb_get_ntohs(tvb, offset);
5435
5436         proto_tree_add_int_format(tree, hf_dcm_tag_value_16s, tvb, offset, 2,
5437             val16, "%-8.8s%d", "Value:", val16);
5438
5439         g_snprintf(*tag_value, MAX_BUF_LEN, "%d", val16);
5440     }
5441     else if (strncmp(vr, "UL", 2) == 0)  {          /* Unsigned Long */
5442         guint32  val32;
5443
5444         if (is_little_endian)   val32 = tvb_get_letohl(tvb, offset);
5445         else                    val32 = tvb_get_ntohl(tvb, offset);
5446
5447         proto_tree_add_uint_format(tree, hf_dcm_tag_value_32u, tvb, offset, 4,
5448             val32, "%-8.8s%u", "Value:", val32);
5449
5450         g_snprintf(*tag_value, MAX_BUF_LEN, "%u", val32);
5451     }
5452     else if (strncmp(vr, "US", 2) == 0)  {          /* Unsigned Short */
5453         const gchar *status_message = NULL;
5454         guint16     val16;
5455
5456         if (is_little_endian)   val16 = tvb_get_letohs(tvb, offset);
5457         else                    val16 = tvb_get_ntohs(tvb, offset);
5458
5459         if (grp == 0x0000 && elm == 0x0100) {
5460             /* This is a command */
5461             g_snprintf(*tag_value, MAX_BUF_LEN, "%s", dcm_cmd2str(val16));
5462
5463             pdv->command = se_strdup(*tag_value);
5464         }
5465         else if (grp == 0x0000 && elm == 0x0900) {
5466             /* This is a status message. If value is not 0x0000, add an expert info */
5467
5468             status_message = dcm_rsp2str(val16);
5469             g_snprintf(*tag_value, MAX_BUF_LEN, "%s (0x%02x)", status_message, val16);
5470
5471             if (val16 != 0x0000 && ((val16 & 0xFF00) != 0xFF00)) {
5472                 /* Not 0x0000 0xFFxx */
5473                 pdv->is_warning = TRUE;
5474             }
5475
5476             pdv->status = se_strdup(status_message);
5477
5478         }
5479         else {
5480             g_snprintf(*tag_value, MAX_BUF_LEN, "%u", val16);
5481         }
5482
5483         if (grp == 0x0000) {
5484             if (elm == 0x0110) {                /* (0000,0110) Message ID */
5485                 pdv->message_id = val16;
5486             }
5487             else if (elm == 0x0120) {           /* (0000,0120) Message ID Being Responded To */
5488                 pdv->message_id_resp = val16;
5489             }
5490             else if (elm == 0x1020) {           /* (0000,1020) Number of Remaining Sub-operations */
5491                 pdv->no_remaining = val16;
5492             }
5493             else if (elm == 0x1021) {           /* (0000,1021) Number of Completed Sub-operations */
5494                 pdv->no_completed = val16;
5495             }
5496             else if (elm == 0x1022) {           /* (0000,1022) Number of Failed Sub-operations  */
5497                 pdv->no_failed = val16;
5498             }
5499             else if (elm == 0x1023) {           /* (0000,1023) Number of Warning Sub-operations */
5500                 pdv->no_warning = val16;
5501             }
5502         }
5503
5504         pitem = proto_tree_add_uint_format(tree, hf_dcm_tag_value_16u, tvb, offset, 2,
5505                     val16, "%-8.8s%s", "Value:", *tag_value);
5506
5507         if (pdv->is_warning && status_message) {
5508             expert_add_info_format(pinfo, pitem, PI_RESPONSE_CODE, PI_WARN, "%s", status_message);
5509         }
5510     }
5511     /* Invalid VR, can only occur with Explicit syntax */
5512     else {
5513         proto_tree_add_bytes_format(tree, hf_dcm_tag_value_byte, tvb, offset, vl_max,
5514             NULL, "%-8.8s%s", "Value:", (vl > vl_max ? "" : "(unknown VR)"));
5515
5516         g_snprintf(*tag_value, MAX_BUF_LEN, "(unknown VR)");
5517     }
5518     offset += vl_max;
5519
5520     return offset;
5521
5522 }
5523
5524 static gboolean
5525 dcm_tag_is_open(dcm_state_pdv_t *pdv, guint32 startpos, guint32 offset, guint32 endpos, guint32 size_required)
5526 {
5527     /* Return true, if the required size does not fit at position 'offset'.
5528        Copy memory from startpos to endpos into pdv structure
5529     */
5530
5531     if (offset + size_required > endpos) {
5532
5533         pdv->open_tag.is_header_fragmented = TRUE;
5534         pdv->open_tag.len_decoded = endpos - startpos;
5535
5536         return TRUE;
5537     }
5538     else {
5539         return FALSE;
5540     }
5541 }
5542
5543 static dcm_tag_t*
5544 dcm_tag_lookup(guint16 grp, guint16 elm)
5545 {
5546
5547     static dcm_tag_t *tag_def = NULL;
5548
5549     static dcm_tag_t tag_unknown         = { 0x00000000, "(unknown)", "UN", "1", 0, 0};
5550     static dcm_tag_t tag_private         = { 0x00000000, "Private Tag", "UN", "1", 0, 0 };
5551     static dcm_tag_t tag_private_grp_len = { 0x00000000, "Private Tag Group Length", "UL", "1", 0, 0 };
5552     static dcm_tag_t tag_grp_length      = { 0x00000000, "Group Length", "UL", "1", 0, 0 };
5553
5554     /* Try a direct hit first before doing a masked search */
5555     tag_def = (dcm_tag_t *)g_hash_table_lookup(dcm_tag_table, GUINT_TO_POINTER((grp << 16) | elm));
5556
5557     if (tag_def == NULL) {
5558
5559         /* No match found */
5560         if ((grp & 0x0001) && (elm == 0x0000)) {
5561             tag_def = &tag_private_grp_len;
5562         }
5563         else if (grp & 0x0001) {
5564             tag_def = &tag_private;
5565         }
5566         else if (elm == 0x0000) {
5567             tag_def = &tag_grp_length;
5568         }
5569
5570         /* There are a few tags that require a mask to be found */
5571         else if (((grp & 0xFF00) == 0x5000) || ((grp & 0xFF00) == 0x6000) || ((grp & 0xFF00) == 0x7F00)) {
5572             /* Do a special for groups 0x50xx, 0x60xx and 0x7Fxx */
5573             tag_def = (dcm_tag_t *)g_hash_table_lookup(dcm_tag_table, GUINT_TO_POINTER(((grp & 0xFF00) << 16) | elm));
5574         }
5575         else if ((grp == 0x0020) && ((elm & 0xFF00) == 0x3100)) {
5576             tag_def = (dcm_tag_t *)g_hash_table_lookup(dcm_tag_table, GUINT_TO_POINTER((grp << 16) | (elm & 0xFF00)));
5577         }
5578         else if ((grp == 0x0028) && ((elm & 0xFF00) == 0x0400)) {
5579             /* This map was done to 0x041x */
5580             tag_def = (dcm_tag_t *)g_hash_table_lookup(dcm_tag_table, GUINT_TO_POINTER((grp << 16) | (elm & 0xFF0F) | 0x0010));
5581         }
5582         else if ((grp == 0x0028) && ((elm & 0xFF00) == 0x0800)) {
5583             tag_def = (dcm_tag_t *)g_hash_table_lookup(dcm_tag_table, GUINT_TO_POINTER((grp << 16) | (elm & 0xFF0F)));
5584         }
5585         else if (grp == 0x1000) {
5586             tag_def = (dcm_tag_t *)g_hash_table_lookup(dcm_tag_table, GUINT_TO_POINTER((grp << 16) | (elm & 0x000F)));
5587         }
5588         else if (grp == 0x1010) {
5589             tag_def = (dcm_tag_t *)g_hash_table_lookup(dcm_tag_table, GUINT_TO_POINTER((grp << 16) | (elm & 0x0000)));
5590         }
5591
5592         if (tag_def == NULL) {
5593             /* Still no match found */
5594             tag_def = &tag_unknown;
5595         }
5596     }
5597
5598     return tag_def;
5599 }
5600
5601 static gchar*
5602 dcm_tag_summary(guint16 grp, guint16 elm, guint32 vl, const gchar *tag_desc, const gchar *vr,
5603                 gboolean is_retired, gboolean is_implicit)
5604 {
5605
5606     gchar *desc_mod;
5607     gchar *tag_vl;
5608     gchar *tag_sum;
5609
5610     if (is_retired) {
5611         desc_mod = ep_strdup_printf("(Retired) %-35.35s", tag_desc);
5612     }
5613     else {
5614         desc_mod = ep_strdup_printf("%-45.45s", tag_desc);
5615     }
5616
5617     if (vl == 0xFFFFFFFF) {
5618         tag_vl = ep_strdup_printf("%10.10s", "<udef>");
5619     }
5620     else {
5621         tag_vl = ep_strdup_printf("%10u", vl);          /* Show as dec */
5622     }
5623
5624     if (is_implicit)    tag_sum = ep_strdup_printf("(%04x,%04x) %s %s",      grp, elm, tag_vl, desc_mod);
5625     else                tag_sum = ep_strdup_printf("(%04x,%04x) %s %s [%s]", grp, elm, tag_vl, desc_mod, vr);
5626
5627     return tag_sum;
5628 }
5629
5630 static guint32
5631 dissect_dcm_tag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5632                 dcm_state_pdv_t *pdv, guint32 offset, guint32 endpos,
5633                 gboolean is_first_tag, gchar **tag_description,
5634                 gboolean *end_of_seq_or_item)
5635 {
5636     /* Decode one tag. If it is a sequence or item start create a subtree.
5637        Returns new offset.
5638     */
5639
5640     proto_tree  *tag_ptree = NULL;      /* Tree for decoded tag details */
5641     proto_tree  *seq_ptree = NULL;      /* Possible subtree for sequences and items */
5642
5643     proto_item  *tag_pitem = NULL;
5644     dcm_tag_t   *tag_def   = NULL;
5645
5646     const gchar *vr = NULL;
5647     gchar       *tag_value = NULL;      /* Tag Value converted to a string      */
5648     gchar       *tag_summary;
5649
5650     guint32 vl = 0;
5651     guint16 vl_1 = 0;
5652     guint16 vl_2 = 0;
5653
5654     guint32 offset_tag   = 0;           /* Remember offsets for tree, since the tree    */
5655     guint32 offset_vr    = 0;           /* header is created pretty late                */
5656     guint32 offset_vl    = 0;
5657
5658     guint32 vl_max = 0;                 /* Max Value Length to Parse */
5659
5660     guint16 grp = 0;
5661     guint16 elm = 0;
5662
5663     guint32 len_decoded_remaing = 0;
5664
5665     gboolean is_little_endian = FALSE;
5666     gboolean is_implicit = FALSE;
5667     gboolean is_vl_long = FALSE;            /* True for 4 Bytes length fields */
5668
5669     gboolean is_sequence = FALSE;           /* True for Sequence Tags */
5670     gboolean is_item = FALSE;               /* True for Sequence Item Tags */
5671
5672     *tag_description = NULL;                /* Reset description. It's ep_ memory, so not really bad*/
5673
5674     tag_value = (gchar *)ep_alloc0(MAX_BUF_LEN);
5675
5676     /* Decode the syntax a little more */
5677     if (pdv->syntax == DCM_EBE) is_little_endian = FALSE;
5678     else                        is_little_endian = TRUE;
5679
5680     if (pdv->syntax == DCM_ILE) is_implicit = TRUE;
5681     else                        is_implicit = FALSE;
5682
5683     offset_tag = offset;
5684
5685
5686     if (pdv->prev && is_first_tag) {
5687         len_decoded_remaing = pdv->prev->open_tag.len_decoded;
5688     }
5689
5690
5691     /* Since we may have a fragmented header, check for every attribute,
5692        whether we have already decoded left-overs from the previous PDV.
5693        Since we have implicit & explicit syntax, copying the open tag to
5694        a buffer without decoding, would have caused tvb_get_xxtohs()
5695        implemnetations on the copy.
5696
5697        An alternative approach would have been to resemble the PDVs first.
5698
5699        The attemtps to reassemblye without named sources (to be implemented)
5700        were very sensitive to missing packets. In such a case, no packet
5701        of a PDV chain was decoded, not even the start.
5702
5703        So for the time being, use this rather cumbersome approach.
5704
5705        For every two bytes (PDV length are always a factor of 2)
5706        check whether we have enough data in the buffer and store the value
5707        accordingly. In the next frame check, whether we have decoded this yet.
5708     */
5709
5710     /* Group */
5711     if (len_decoded_remaing >= 2) {
5712         grp = pdv->prev->open_tag.grp;
5713         len_decoded_remaing -= 2;
5714     }
5715     else {
5716
5717         if (dcm_tag_is_open(pdv, offset_tag, offset, endpos, 2)) return endpos; /* Exit if needed */
5718
5719         if (is_little_endian)   grp = tvb_get_letohs(tvb, offset);
5720         else                    grp = tvb_get_ntohs (tvb, offset);
5721         offset += 2;
5722         pdv->open_tag.grp = grp;
5723     }
5724
5725     /* Element */
5726     if (len_decoded_remaing >= 2) {
5727         elm = pdv->prev->open_tag.elm;
5728         len_decoded_remaing -= 2;
5729     }
5730     else {
5731
5732         if (dcm_tag_is_open(pdv, offset_tag, offset, endpos, 2)) return endpos;    /* Exit if needed */
5733
5734         if (is_little_endian)   elm = tvb_get_letohs(tvb, offset);
5735         else                    elm = tvb_get_ntohs (tvb, offset);
5736         offset += 2;
5737         pdv->open_tag.elm = elm;
5738     }
5739
5740     /* Find the best matching tag */
5741     tag_def = dcm_tag_lookup(grp, elm);
5742
5743     /* Value Representation */
5744     offset_vr = offset;
5745     if ((grp == 0xFFFE) && (elm == 0xE000 || elm == 0xE00D || elm == 0xE0DD))  {
5746         /* Item start, Item Delimitation or Sequence Delimitation */
5747         vr = "UL";
5748         is_vl_long = TRUE;                          /* These tags always have a 4 byte lentgh field */
5749     }
5750     else if (is_implicit) {
5751         /* Get VR from tag definition */
5752         vr = ep_strdup(tag_def->vr);
5753         is_vl_long = TRUE;                          /* Implict always has 4 byte lentgh field */
5754     }
5755     else {
5756
5757         if (len_decoded_remaing >= 2) {
5758             vr = ep_strdup(pdv->prev->open_tag.vr);
5759             len_decoded_remaing -= 2;
5760         }
5761         else {
5762
5763             /* Controlled exit, if VR does not fit. */
5764             if (dcm_tag_is_open(pdv, offset_tag, offset_vr, endpos, 2)) return endpos;
5765
5766             vr = (gchar *)tvb_get_ephemeral_string(tvb, offset, 2);
5767             offset += 2;
5768
5769             g_free(pdv->open_tag.vr);
5770             pdv->open_tag.vr = g_strdup(vr);        /* needs to survive withing a session */
5771         }
5772
5773
5774         if ((strcmp(vr, "OB") == 0) || (strcmp(vr, "OW") == 0) || (strcmp(vr, "OF") == 0) ||
5775             (strcmp(vr, "SQ") == 0) || (strcmp(vr, "UT") == 0) || (strcmp(vr, "UN") == 0)) {
5776             /* 4 bytes specials: OB, OW, OF, SQ, UT or UN */
5777             is_vl_long = TRUE;
5778
5779             /* Skip 2 Bytes */
5780             if (len_decoded_remaing >= 2) {
5781                 len_decoded_remaing -= 2;
5782             }
5783             else {
5784                 if (dcm_tag_is_open(pdv, offset_tag, offset_vr, endpos, 2)) return endpos;
5785                 offset += 2;
5786             }
5787         }
5788         else {
5789             is_vl_long = FALSE;
5790         }
5791     }
5792
5793
5794     /* Value Length. This is rather cumbersume code to get a 4 byte length, but in the
5795        fragmented case, we have 2*2 bytes. So always use that pattern
5796     */
5797
5798     offset_vl = offset;
5799     if (len_decoded_remaing >= 2) {
5800         vl_1 = pdv->prev->open_tag.vl_1;
5801         len_decoded_remaing -= 2;
5802     }
5803     else {
5804
5805         if (dcm_tag_is_open(pdv, offset_tag, offset_vl, endpos, 2)) return endpos;
5806         if (is_little_endian)   vl_1 = tvb_get_letohs(tvb, offset);
5807         else                    vl_1 = tvb_get_ntohs(tvb, offset);
5808         offset += 2;
5809         pdv->open_tag.vl_1 = vl_1;
5810     }
5811
5812     if (is_vl_long) {
5813
5814         if (len_decoded_remaing >= 2) {
5815             vl_2 = pdv->prev->open_tag.vl_2;
5816             len_decoded_remaing -= 2;
5817         }
5818         else {
5819
5820             if (dcm_tag_is_open(pdv, offset_tag, offset_vl+2, endpos, 2)) return endpos;
5821             if (is_little_endian)       vl_2 = tvb_get_letohs(tvb, offset);
5822             else                        vl_2 = tvb_get_ntohs(tvb, offset);
5823             offset += 2;
5824             pdv->open_tag.vl_2 = vl_2;
5825         }
5826
5827         if (is_little_endian)   vl = (vl_2 << 16) + vl_1;
5828         else                    vl = (vl_1 << 16) + vl_2;
5829     }
5830     else {
5831         vl = vl_1;
5832     }
5833
5834     /* Now we have most of the information, excpet for sequences and items with undefined
5835        length :-/. But, whether we know the length or not, we now need to create the tree
5836        item and subtree, before we can loop into sequences and items
5837
5838        Display the information we collected so far. Don't wait until the value is parsed,
5839        because that parsing might cause an exception. If that happens within a sequence,
5840        the sequence tag would not show up with the value
5841     */
5842
5843     tag_summary = dcm_tag_summary(grp, elm, vl, tag_def->description, vr, tag_def->is_retired, is_implicit);
5844
5845     if (vl == 0xFFFFFFFF) {
5846         /* 'Just' mark header as the length of the item */
5847         tag_pitem = proto_tree_add_text(tree, tvb, offset_tag, offset - offset_tag, "%s", tag_summary);
5848         vl_max = 0;         /* We don't know who long this sequence/item is */
5849     }
5850     else if (offset + vl <= endpos) {
5851         /* Show real length of item */
5852         tag_pitem = proto_tree_add_text(tree, tvb, offset_tag, offset + vl - offset_tag, "%s", tag_summary);
5853         vl_max = vl;
5854     }
5855     else {
5856         /* Value is longer than what we have in the PDV, -> we do have a OPEN tag */
5857         tag_pitem = proto_tree_add_text(tree, tvb, offset_tag, endpos - offset_tag, "%s", tag_summary);
5858         vl_max = endpos - offset;
5859     }
5860
5861     is_sequence = (strcmp(vr, "SQ") == 0) || (vl == 0xFFFFFFFF);
5862     is_item = ((grp == 0xFFFE) && (elm == 0xE000));
5863
5864
5865     /* If you are going to touch the following 25 lines, make sure you reserve a few hours to go
5866        through both display options and check for proper tree display :-)
5867     */
5868     if (is_sequence | is_item) {
5869
5870         if (global_dcm_seq_subtree) {
5871             /* Use different ett_ for Sequences & Items, so that fold/unfold state makes sense */
5872             seq_ptree = proto_item_add_subtree(tag_pitem, (is_sequence ? ett_dcm_data_seq : ett_dcm_data_item));
5873             if (global_dcm_tag_subtree)     tag_ptree = seq_ptree;
5874             else                            tag_ptree = NULL;
5875         }
5876         else {
5877             seq_ptree = tree;
5878             if (global_dcm_tag_subtree) {
5879                 tag_ptree = proto_item_add_subtree(tag_pitem, ett_dcm_data_tag);
5880             }
5881             else {
5882                 tag_ptree = NULL;
5883             }
5884         }
5885     }
5886     else {
5887         /* For tags */
5888         if (global_dcm_tag_subtree) {
5889             tag_ptree = proto_item_add_subtree(tag_pitem, ett_dcm_data_tag);
5890         }
5891         else {
5892             tag_ptree = NULL;
5893         }
5894     }
5895
5896     /*  ---------------------------------------------------------------
5897         Tag details as separate items
5898         ---------------------------------------------------------------
5899     */
5900
5901     proto_tree_add_uint_format(tag_ptree, hf_dcm_tag, tvb, offset_tag, 4,
5902         (grp << 16) | elm, "Tag:    %04x,%04x (%s)", grp, elm, tag_def->description);
5903
5904     /* Add VR to tag detail, excpet for dicom items */
5905     if (!is_item)  {
5906         if (is_implicit) {
5907             /* Select header, since no VR is present in implicit syntax */
5908             proto_tree_add_string_format(tag_ptree, hf_dcm_tag_vr, tvb, offset_tag, 4, vr, "%-8.8s%s", "VR:", vr);
5909         }
5910         else {
5911             proto_tree_add_string_format(tag_ptree, hf_dcm_tag_vr, tvb, offset_vr,  2, vr, "%-8.8s%s", "VR:", vr);
5912         }
5913     }
5914
5915     /* Add length to tag detail */
5916     proto_tree_add_uint_format(tag_ptree, hf_dcm_tag_vl, tvb, offset_vl, (is_vl_long ? 4 : 2), vl, "%-8.8s%u", "Length:", vl);
5917
5918
5919     /*  ---------------------------------------------------------------
5920         Finally the Tag Value
5921         ---------------------------------------------------------------
5922     */
5923     if ((is_sequence || is_item) && (vl > 0)) {
5924         /* Sequence or Item Start */
5925
5926         guint32 endpos_item = 0;
5927         gboolean local_end_of_seq_or_item = FALSE;
5928         gboolean is_first_desc = TRUE;
5929
5930         gchar *item_description = NULL;     /* Will be allocated as ep_ memory in dissect_dcm_tag() */
5931
5932         if (vl == 0xFFFFFFFF) {
5933             /* Undefined length */
5934
5935             while ((!local_end_of_seq_or_item) && (!pdv->open_tag.is_header_fragmented) && (offset < endpos)) {
5936
5937                 offset = dissect_dcm_tag(tvb, pinfo, seq_ptree, pdv, offset, endpos, FALSE,
5938                     &item_description, &local_end_of_seq_or_item);
5939
5940                 if (item_description && global_dcm_seq_subtree) {
5941                     proto_item_append_text(tag_pitem, (is_first_desc ? " %s" : ", %s"), item_description);
5942                     is_first_desc = FALSE;
5943                 }
5944             }
5945         }
5946         else {
5947             /* Defined length */
5948             endpos_item = offset + vl_max;
5949
5950             while (offset < endpos_item) {
5951
5952                 offset = dissect_dcm_tag(tvb, pinfo, seq_ptree, pdv, offset, endpos_item, FALSE,
5953                     &item_description, &local_end_of_seq_or_item);
5954
5955                 if (item_description && global_dcm_seq_subtree) {
5956                     proto_item_append_text(tag_pitem, (is_first_desc ? " %s" : ", %s"), item_description);
5957                     is_first_desc = FALSE;
5958                 }
5959             }
5960         }
5961     } /*  if ((is_sequence || is_item) && (vl > 0)) */
5962     else if ((grp == 0xFFFE) && (elm == 0xE00D)) {
5963         /* Item delimitation for items with undefined length */
5964         *end_of_seq_or_item = TRUE;
5965     }
5966     else if ((grp == 0xFFFE) && (elm == 0xE0DD)) {
5967         /* Sequence delimitation for sequences with undefined length */
5968         *end_of_seq_or_item = TRUE;
5969     }
5970     else if (vl == 0) {
5971         /* No value */
5972         g_strlcpy(tag_value, "<Empty>", MAX_BUF_LEN);
5973     }
5974     else if (vl > vl_max) {
5975         /* Tag is longer than the PDV/PDU. Don't perform any decoding */
5976
5977         gchar *tag_desc;
5978
5979         proto_tree_add_bytes_format(tag_ptree, hf_dcm_tag_value_byte, tvb, offset, vl_max,
5980             NULL, "%-8.8sBytes %d - %d [start]", "Value:", 1, vl_max);
5981
5982         g_snprintf(tag_value, MAX_BUF_LEN, "<Bytes %d - %d, start>", 1, vl_max);
5983         offset += vl_max;
5984
5985         /*  Save the needed data for reuse, and subsequent packets
5986             This will leak a little within the session.
5987
5988             But since we may have tags being closed and reopen in the same PDV
5989             we will always need to store this
5990         */
5991
5992         tag_desc = dcm_tag_summary(grp, elm, vl, tag_def->description, vr, tag_def->is_retired, is_implicit);
5993
5994         if (pdv->open_tag.desc == NULL) {
5995             pdv->open_tag.is_value_fragmented = TRUE;
5996             pdv->open_tag.desc = se_strdup(tag_desc);
5997             pdv->open_tag.len_total = vl;
5998             pdv->open_tag.len_remaining = vl - vl_max;
5999         }
6000     }
6001     else {
6002         /* Regular value. Identify the type, decode and display */
6003
6004         offset = dissect_dcm_tag_value(tvb, pinfo, tag_ptree, pdv, offset, grp, elm, vl, vl_max, vr, &tag_value);
6005
6006         /* -------------------------------------------------------------
6007            We have decoded the value. Now store those tags of interest
6008            -------------------------------------------------------------
6009         */
6010
6011         /* Store SOP Class and Instance UID in first PDV of this object */
6012         if (grp == 0x0008 && elm == 0x0016) {
6013             dcm_state_pdv_get_obj_start(pdv)->sop_class_uid = se_strdup(tag_value);
6014         }
6015         else if (grp == 0x0008 && elm == 0x0018) {
6016             dcm_state_pdv_get_obj_start(pdv)->sop_instance_uid = se_strdup(tag_value);
6017         }
6018         else if (grp == 0x0000 && elm == 0x0100) {
6019             /* This is the command tag -> overwrite existing PDV description */
6020             pdv->desc = se_strdup(tag_value);
6021         }
6022     }
6023
6024
6025     /* -------------------------------------------------------------------
6026        Adde the value to the already constructued item
6027        -------------------------------------------------------------------
6028     */
6029
6030     proto_item_append_text(tag_pitem, " %s", tag_value);
6031
6032     if (tag_def->add_to_summary) {
6033         *tag_description = ep_strdup(g_strstrip(tag_value));
6034     }
6035
6036     return offset;
6037 }
6038
6039 static guint32
6040 dissect_dcm_tag_open(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6041                 dcm_state_pdv_t *pdv, guint32 offset, guint32 endpos, gboolean *is_first_tag)
6042 {
6043     /* 'Decode' open tags from previous PDV */
6044
6045     proto_item *pitem = NULL;
6046
6047     guint32 tag_value_fragment_len = 0;
6048
6049     if ((pdv->prev) && (pdv->prev->open_tag.len_remaining > 0))  {
6050         /* Not first PDV in the given presentation context (Those don't have remaining data to parse :-) */
6051         /* And previous PDV has left overs, i.e. this is a continuation PDV */
6052
6053         if (endpos - offset >= pdv->prev->open_tag.len_remaining) {
6054             /*
6055                Remaining bytes are equal or more than we expect for the open tag
6056                Finally reach the end of this tag. Don't touch the open_tag structure
6057                of this PDV, as we may see a new open tag at the end
6058             */
6059             tag_value_fragment_len = pdv->prev->open_tag.len_remaining;
6060             pdv->is_corrupt = FALSE;
6061         }
6062         else if (pdv->is_flagvalid && pdv->is_last_fragment) {
6063             /*
6064               The tag is not yet complete, however, the flag indicates that it should be
6065               Therefore end this tag and issue an expert_add_info. Don't touch the
6066               open_tag structure of this PDV, as we may see a new open tag at the end
6067             */
6068             tag_value_fragment_len = endpos - offset;
6069             pdv->is_corrupt = TRUE;
6070         }
6071         else {
6072             /*
6073              * More to do for this tag
6074              */
6075             tag_value_fragment_len = endpos - offset;
6076
6077             /* Set data in current PDV structure */
6078             if (!pdv->open_tag.is_value_fragmented)  {
6079                 /* No need to do it twice or more */
6080
6081                 pdv->open_tag.is_value_fragmented = TRUE;
6082                 pdv->open_tag.len_total = pdv->prev->open_tag.len_total;
6083                 pdv->open_tag.len_remaining = pdv->prev->open_tag.len_remaining - tag_value_fragment_len;
6084                 pdv->open_tag.desc = se_strdup(pdv->prev->open_tag.desc);
6085
6086             }
6087             pdv->is_corrupt = FALSE;
6088         }
6089
6090         if (pdv->is_corrupt) {
6091             pitem = proto_tree_add_bytes_format(tree, hf_dcm_data_tag, tvb,
6092                 offset, tag_value_fragment_len, NULL,
6093                 "%s <incomplete>", pdv->prev->open_tag.desc);
6094
6095             expert_add_info_format(pinfo, pitem, PI_MALFORMED, PI_ERROR,
6096                 "Early termination of tag. Data is missing");
6097
6098         }
6099         else {
6100             proto_tree_add_bytes_format(tree, hf_dcm_data_tag, tvb,
6101                 offset, tag_value_fragment_len, NULL,
6102                 "%s <Bytes %d - %d, %s>", pdv->prev->open_tag.desc,
6103                 pdv->prev->open_tag.len_total - pdv->prev->open_tag.len_remaining + 1,
6104                 pdv->prev->open_tag.len_total - pdv->prev->open_tag.len_remaining + tag_value_fragment_len,
6105                 (pdv->prev->open_tag.len_remaining > tag_value_fragment_len ? "continuation" : "end") );
6106         }
6107
6108         offset += tag_value_fragment_len;
6109         *is_first_tag = FALSE;
6110     }
6111
6112     return offset;
6113 }
6114
6115 static guint32
6116 dissect_dcm_pdv_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6117                 dcm_state_pdv_t *pdv, guint32 offset, guint32 pdv_body_len,
6118                 gchar **pdv_description)
6119 {
6120     /* Handle one PDV inside a data PDU */
6121
6122     gchar *tag_value = NULL;
6123     gboolean dummy = FALSE;
6124     guint32 endpos = 0;
6125
6126     endpos = offset + pdv_body_len;
6127
6128     if (pdv->syntax == DCM_UNK) {
6129         /* Eventually, we will have a syntax detector. Until then, don't decode */
6130
6131         proto_tree_add_bytes_format(tree, hf_dcm_data_tag, tvb,
6132             offset, pdv_body_len, NULL,
6133             "(%04x,%04x) %-8x Unparsed data", 0, 0, pdv_body_len);
6134         offset = endpos;
6135     }
6136     else {
6137
6138         gboolean is_first_tag = TRUE;
6139
6140         /* Treat the left overs */
6141         offset = dissect_dcm_tag_open(tvb, pinfo, tree, pdv, offset, endpos, &is_first_tag);
6142
6143         /* Decode all tags, sequences and items in this PDV recursively */
6144         while (offset < endpos) {
6145             offset = dissect_dcm_tag(tvb, pinfo, tree, pdv, offset, endpos, is_first_tag, &tag_value, &dummy);
6146             is_first_tag = FALSE;
6147         }
6148     }
6149
6150     if (pdv->is_command) {
6151
6152         *pdv_description = (gchar *)se_alloc0(MAX_BUF_LEN);
6153
6154         if (pdv->is_warning) {
6155             if (pdv->comment) {
6156                 g_snprintf(*pdv_description, MAX_BUF_LEN, "%s (%s, %s)", pdv->desc, pdv->status, pdv->comment);
6157             }
6158             else {
6159                 g_snprintf(*pdv_description, MAX_BUF_LEN, "%s (%s)", pdv->desc, pdv->status);
6160             }
6161
6162         }
6163         else if (global_dcm_cmd_details) {
6164             /* Show command details in header */
6165
6166             if (pdv->message_id > 0) {
6167                 g_snprintf(*pdv_description, MAX_BUF_LEN, "%s ID=%d", pdv->desc, pdv->message_id);
6168             }
6169             else if (pdv->message_id_resp > 0) {
6170
6171                 g_snprintf(*pdv_description, MAX_BUF_LEN, "%s ID=%d", pdv->desc, pdv->message_id_resp);
6172
6173                 if (pdv->no_completed > 0) {
6174                     g_snprintf(*pdv_description, MAX_BUF_LEN, "%s C=%d", *pdv_description, pdv->no_completed);
6175                 }
6176                 if (pdv->no_remaining > 0) {
6177                     g_snprintf(*pdv_description, MAX_BUF_LEN, "%s R=%d", *pdv_description, pdv->no_remaining);
6178                 }
6179                 if (pdv->no_warning > 0) {
6180                     g_snprintf(*pdv_description, MAX_BUF_LEN, "%s W=%d", *pdv_description, pdv->no_warning);
6181                 }
6182                 if (pdv->no_failed > 0) {
6183                     g_snprintf(*pdv_description, MAX_BUF_LEN, "%s F=%d", *pdv_description, pdv->no_failed);
6184                 }
6185             }
6186             else {
6187                 *pdv_description = pdv->desc;
6188             }
6189         }
6190         else {
6191             *pdv_description = pdv->desc;
6192         }
6193     }
6194     else {
6195         *pdv_description = pdv->desc;
6196     }
6197
6198     return endpos;      /* we could try offset as return value */
6199 }
6200
6201
6202 static guint32
6203 dissect_dcm_pdv_fragmented(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6204                 dcm_state_assoc_t *assoc, guint32 offset, guint32 pdv_len, gchar **pdv_description)
6205 {
6206     /* Handle one PDV inside a data PDU. Perform the necessary reassembly
6207        Create PDV object when needed
6208     */
6209
6210     conversation_t  *conv=NULL;
6211
6212     dcm_state_pdv_t *pdv = NULL;
6213
6214     tvbuff_t *next_tvb = NULL;
6215     fragment_data *head = NULL;
6216
6217     guint32 reassembly_id;
6218     guint32 pdv_body_len;
6219     guint32 startpos;
6220
6221     startpos = offset;
6222     pdv_body_len = pdv_len-2;
6223
6224     /* Dissect Context ID, Find PDV object, Decode Command/Data flag and More Fragments flag */
6225     offset = dissect_dcm_pdv_header(tvb, pinfo, tree, assoc, offset, &pdv);
6226
6227     /* When fragmented, do reassambly and subsequently decode merged PDV */
6228     if (global_dcm_reassemble)
6229     {
6230
6231         conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
6232                             pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
6233
6234         /* Try to create somewhat unique ID.
6235            Include the conversation index, to separate TCP session
6236         */
6237         reassembly_id = (((conv->index) & 0x00FFFFFF) << 8) + pdv->pctx_id;
6238
6239         head = fragment_add_seq_next(tvb, offset, pinfo, reassembly_id,
6240                                 dcm_pdv_fragment_table,
6241                                 dcm_pdv_reassembled_table,
6242                                 pdv_body_len,
6243                                 !(pdv->is_last_fragment));
6244
6245         if (head && (head->next == NULL)) {
6246             /* Was not really fragmented, therefore use 'conventional' decoding
6247                fragment_add_seq_next() won't add any items to the list, when last fragment only
6248             */
6249
6250             offset = dissect_dcm_pdv_body(tvb, pinfo, tree, pdv, offset, pdv_body_len, pdv_description);
6251         }
6252         else {
6253             next_tvb = process_reassembled_data(tvb, offset, pinfo,
6254                                         "Reassembled PDV", head,
6255                                         &dcm_pdv_fragment_items, NULL, tree);
6256
6257             if (next_tvb == NULL) {
6258                 /* Just show this as a fragment */
6259
6260                 *pdv_description = (gchar *)se_alloc0(MAX_BUF_LEN);
6261
6262                 if (head && head->reassembled_in != pinfo->fd->num) {
6263
6264                     if (pdv->desc) {
6265                         /* We know the presentation context already */
6266                         g_snprintf(*pdv_description, MAX_BUF_LEN, "%s (reassembled in #%u)", pdv->desc, head->reassembled_in);
6267                     }
6268                     else {
6269                         /* Decoding of the presentation context did not occure yet or did not succeed */
6270                         g_snprintf(*pdv_description, MAX_BUF_LEN, "PDV Fragment (reassembled in #%u)", head->reassembled_in);
6271                     }
6272                 }
6273                 else {
6274                     /* We have done done any tag decoding yet */
6275                     g_snprintf(*pdv_description, MAX_BUF_LEN, "PDV Fragment");
6276                 }
6277
6278                 offset += pdv_body_len;
6279             }
6280             else {
6281                 guint next_tvb_length = tvb_length(next_tvb);
6282                 /* Decode reassembled data */
6283
6284                 if (tree || have_tap_listener(dicom_eo_tap)) {
6285                     /* The performance optimization now starts at tag level.
6286
6287                        During, tree can be NULL, but we need a few tags to be decoded,
6288                        i.e Class & Instance UID, so the export dialog has all information and
6289                        that the dicome header is complete
6290                     */
6291                     offset += dissect_dcm_pdv_body(next_tvb, pinfo, tree, pdv, 0, next_tvb_length, pdv_description);
6292                 }
6293
6294                 if (have_tap_listener(dicom_eo_tap)) {
6295                     /* Copy pure DICOM data to buffer, no PDV flags */
6296
6297                     pdv->data = g_malloc(next_tvb_length);      /* will be freed in dcm_export_create_object() */
6298                     tvb_memcpy(next_tvb, pdv->data, 0, next_tvb_length);
6299                     pdv->data_len = next_tvb_length;
6300
6301                     /* Copy to export buffer */
6302                     dcm_export_create_object(pinfo, assoc, pdv);
6303                 }
6304             }
6305         }
6306     }
6307     else if (tree) {
6308         /* Do not reassemble PDVs, i.e. decode PDV one by one. Only execute when in detail mode */
6309         offset = dissect_dcm_pdv_body(tvb, pinfo, tree, pdv, offset, pdv_body_len, pdv_description);
6310
6311         /* During DICOM Export, perform a few extra steps */
6312         if (have_tap_listener(dicom_eo_tap)) {
6313             /* Copy pure DICOM data to buffer, no PDV flags */
6314
6315             pdv->data = g_malloc(pdv_body_len);      /* will be freed in dcm_export_create_object() */
6316             tvb_memcpy(tvb, pdv->data, startpos, pdv_body_len);
6317             pdv->data_len = pdv_body_len;
6318
6319             if ((pdv_body_len > 0) && (pdv->is_last_fragment)) {
6320                 /* At the last segment, merge all related previous PDVs and copy to export buffer */
6321                 dcm_export_create_object(pinfo, assoc, pdv);
6322             }
6323         }
6324     }
6325
6326     return offset;
6327
6328 }
6329 static guint32
6330 dissect_dcm_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6331                      dcm_state_assoc_t *assoc, guint32 offset, guint32 pdu_len, gchar **pdu_data_description)
6332 {
6333
6334     /*  04 P-DATA-TF
6335          1  1 reserved
6336          2  4 length
6337               - (1+) presentation data value (PDV) items
6338          6  4 length
6339         10  1 Presentation Context ID (odd ints 1 - 255)
6340               - PDV
6341         11  1 header
6342               0x01 if set, contains Message Command info, else Message Data
6343               0x02 if set, contains last fragment
6344     */
6345
6346     proto_tree *pdv_ptree = NULL;       /* Tree for item details */
6347     proto_item *pdv_pitem = NULL;
6348
6349     gchar  *buf_desc = NULL;            /* PDU description */
6350     gchar  *pdv_description = NULL;
6351
6352     gboolean first_pdv = TRUE;
6353
6354     guint32 endpos = 0;
6355     guint32 pdv_len = 0;
6356
6357     endpos = offset + pdu_len;
6358
6359     buf_desc=(gchar *)se_alloc0(MAX_BUF_LEN);   /* Valid for this capture, since we return this buffer */
6360
6361     /* Loop through multiple PDVs */
6362     while (offset < endpos) {
6363
6364         pdv_len = tvb_get_ntohl(tvb, offset);
6365
6366         pdv_pitem = proto_tree_add_text(tree, tvb, offset, pdv_len+4, "PDV");
6367         pdv_ptree = proto_item_add_subtree(pdv_pitem, ett_dcm_data_pdv);
6368
6369         if (pdv_len + 4 > pdu_len) {
6370             expert_add_info_format(pinfo, pdv_pitem, PI_MALFORMED, PI_ERROR,
6371                 "Invalid PDV length (too large)");
6372             return endpos;
6373         }
6374         else if (pdv_len <= 2) {
6375             expert_add_info_format(pinfo, pdv_pitem, PI_MALFORMED, PI_ERROR,
6376                 "Invalid PDV length (too small)");
6377             return endpos;
6378         }
6379         else if (((pdv_len >> 1) << 1) != pdv_len) {
6380             expert_add_info_format(pinfo, pdv_pitem, PI_MALFORMED, PI_ERROR,
6381                 "Invalid PDV length (not even)");
6382             return endpos;
6383         }
6384
6385         proto_tree_add_item(pdv_ptree, hf_dcm_pdv_len, tvb, offset, 4, ENC_BIG_ENDIAN);
6386         offset += 4;
6387
6388         offset = dissect_dcm_pdv_fragmented(tvb, pinfo, pdv_ptree, assoc, offset, pdv_len, &pdv_description);
6389
6390         /* The following doesn't seem to work anymore */
6391         if (pdv_description) {
6392             if (first_pdv) {
6393                 g_snprintf(buf_desc, MAX_BUF_LEN, "%s", pdv_description);
6394             }
6395             else {
6396                 g_snprintf(buf_desc, MAX_BUF_LEN, "%s, %s", buf_desc, pdv_description);
6397             }
6398         }
6399
6400         proto_item_append_text(pdv_pitem, ", %s", pdv_description);
6401         first_pdv=FALSE;
6402
6403     }
6404
6405     *pdu_data_description = buf_desc;
6406
6407     return offset;
6408 }
6409
6410 static int
6411 dissect_dcm_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean is_port_static)
6412 {
6413     /* Code to actually dissect the packets */
6414
6415     guint8  pdu_type = 0;
6416     guint32 pdu_start = 0;
6417     guint32 pdu_len = 0;
6418     guint16 vers = 0;
6419     guint32 tlen = 0;
6420
6421     int offset = 0;
6422
6423     /*
6424         Modified orignal code, which was optimized for a heuristic detection, and therefore
6425         caused some load and memory consumption, for every non DICOM packet not processed
6426         by someone else.
6427
6428         Since tcp packets are now assembled well by wireshark (in conjunction with the dissectors)
6429         we will only see properly alligned PDUs, at the beginnig of the buffer, else its not DICOM
6430         traffic.
6431
6432         Therfore do the byte checking as early as possible
6433         The heurisitc hook requires an association request
6434
6435         DICOM PDU are nice, but need to be managed
6436
6437         We can have any combination:
6438         - One or more DICOM PDU per TCP packet
6439         - PDU split over different TCP packets
6440         - And both together, i.e. some complete PDUs and then a fraction of a new PDU in a TCP packet
6441
6442         This function will handle multiple PDUs per TCP packet and will ask for more data,
6443         if the last PDU does not fit
6444
6445         It does not reassamble fragmented PDVs by purpose, since the Tag Value parsing needs to be done
6446         per Tag, and PDU recombinaion here would
6447         a) need to eliminate PDU/PDV/Ctx header (12 bytes)
6448         b) not show the true DICOM logic in transfer
6449
6450         The length check is tricky. If not a PDV continuation, 10 Bytes are required. For PDV continuation
6451         anything seems to be possible, depending on the buffer alignment of the sending process.
6452
6453     */
6454
6455     tlen = tvb_reported_length(tvb);
6456
6457     pdu_type = tvb_get_guint8(tvb, 0);
6458     if (pdu_type == 0 || pdu_type > 7)          /* Wrong PDU type. 'Or' is slightly more efficient than 'and' */
6459         return 0;                               /* No bytes taken from the stack */
6460
6461     if (is_port_static) {
6462         /* Port is defined explicitly, or association request was previously found succesfully.
6463            Be more tolerant on minimum packet size. Also accept < 6
6464         */
6465
6466         if (tlen < 6) {
6467             /* we need 6 bytes at least to get PDU length */
6468             pinfo->desegment_offset = offset;
6469             pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
6470             return TRUE;
6471         }
6472     }
6473     else {
6474         /* We operate in heuristic mode, be picky out of performance reasons:
6475
6476            - Minimum 10 Bytes
6477            - Look for the association request
6478            - Reasonable PDU size
6479
6480            Tried find_conversation() and dcm_state_get() with no benefit
6481
6482            But since we are called in static mode, once we decoded the associtaion reqest and
6483            called conversation_set_dissector(), we really only need to filter for an associtaion reqest
6484
6485         */
6486
6487         if (tlen < 10) {
6488             /* For all association handling ones, 10 bytes would be needed. Be happy with 6 */
6489             return 0;
6490         }
6491
6492         pdu_len = tvb_get_ntohl(tvb, 2);
6493         vers = tvb_get_ntohs(tvb, 6);
6494
6495         /* Exit, if not a association request at version 1*/
6496         if (!(pdu_type == 1 && vers == 1)) {
6497             return 0;
6498         }
6499
6500         /* Exit if TCP payload is bigger than PDU length (plus header)
6501            ok. for PRESENTATION_DATA, questionable for ASSOCIATION requests
6502         */
6503         if (pdu_len+6 < tlen) {
6504             return 0;
6505         }
6506     }
6507
6508
6509     /* Passing this point, we should always have tlen >= 6 */
6510
6511     pdu_len = tvb_get_ntohl(tvb, 2);
6512     if (pdu_len < 4)                /* The smallest PDUs are ASSOC Rejects & Release Msgs */
6513         return 0;
6514
6515     /* Mark it. This is a DICOM packet */
6516
6517     col_set_str(pinfo->cinfo, COL_PROTOCOL, "DICOM");
6518
6519      /* Process all PDUs in the buffer */
6520     while (pdu_start < tlen) {
6521         guint32 old_pdu_start;
6522
6523         if ((pdu_len+6) > (tlen-offset)) {
6524
6525             /*  PDU is larger than the remaing packet (buffer), therefore request whole PDU
6526                 The next time this function is called, tlen will be equal to pdu_len
6527             */
6528
6529             pinfo->desegment_offset = offset;
6530             pinfo->desegment_len = (pdu_len+6) - (tlen-offset);
6531
6532             /*  Why return a boolean for a deliberate int function? No clue, but
6533                 no better working example found.
6534             */
6535             return TRUE;
6536         }
6537
6538         /* Process a whole PDU */
6539         offset=dissect_dcm_pdu(tvb, pinfo, tree, pdu_start);
6540
6541         /* Next PDU */
6542         old_pdu_start = pdu_start;
6543         pdu_start =  pdu_start + pdu_len + 6;
6544         if (pdu_start <= old_pdu_start) {
6545             expert_add_info_format(pinfo, NULL, PI_MALFORMED, PI_ERROR,
6546                 "Invalid PDU length (%u)", pdu_len);
6547             THROW(ReportedBoundsError);
6548         }
6549
6550         if (pdu_start < tlen - 6) {
6551             /* we got at least 6 bytes of the next PDU still in the buffer */
6552              pdu_len = tvb_get_ntohl(tvb, pdu_start+2);
6553         }
6554         else {
6555             pdu_len = 0;
6556         }
6557     }
6558     return offset;
6559 }
6560
6561 /* Call back functions used to register */
6562 static int
6563 dissect_dcm_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
6564 {
6565     /* Less checking on ports that match */
6566     return dissect_dcm_main(tvb, pinfo, tree, TRUE);
6567 }
6568
6569 static int
6570 dissect_dcm_heuristic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
6571 {
6572     /* Only decode conerstations, which include an Association Request */
6573     /* This will be potentially called for every packet */
6574     return dissect_dcm_main(tvb, pinfo, tree, FALSE);
6575 }
6576
6577 static guint32
6578 dissect_dcm_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset)
6579 {
6580     proto_tree *dcm_ptree=NULL;     /* Root DICOM tree and its item */
6581     proto_item *dcm_pitem=NULL;
6582
6583     dcm_state_t *dcm_data=NULL;
6584     dcm_state_assoc_t *assoc=NULL;
6585
6586     guint8  pdu_type=0;
6587     guint32 pdu_len=0;
6588
6589     gchar *pdu_data_description=NULL;
6590
6591     /* Get or create converstation. Used to store context IDs and xfer Syntax */
6592
6593     dcm_data = dcm_state_get(pinfo, TRUE);
6594     if (dcm_data == NULL) {     /* Internal error. Failed to create main dicom data structre */
6595         return offset;
6596     }
6597
6598     dcm_pitem = proto_tree_add_item(tree, proto_dcm, tvb, offset, -1, ENC_NA);
6599     dcm_ptree = proto_item_add_subtree(dcm_pitem, ett_dcm);
6600
6601     pdu_type = tvb_get_guint8(tvb, offset);
6602     proto_tree_add_uint_format(dcm_ptree, hf_dcm_pdu, tvb, offset, 2,
6603         pdu_type, "PDU Type 0x%x (%s)", pdu_type, dcm_pdu2str(pdu_type));
6604     offset += 2;
6605
6606     pdu_len = tvb_get_ntohl(tvb, offset);
6607     proto_tree_add_item(dcm_ptree, hf_dcm_pdu_len, tvb, offset, 4, ENC_BIG_ENDIAN);
6608     offset += 4;
6609
6610     /* Find previously detected association, else create a new one object*/
6611     assoc = dcm_state_assoc_get(dcm_data, pinfo->fd->num, TRUE);
6612
6613     if (assoc == NULL) {        /* Internal error. Failed to create association structre */
6614         return offset;
6615     }
6616
6617     if (pdu_type == 4) {
6618         col_add_str(pinfo->cinfo, COL_INFO, "P-DATA");
6619
6620         offset = dissect_dcm_pdu_data(tvb, pinfo, dcm_ptree, assoc, offset, pdu_len, &pdu_data_description);
6621
6622         if (pdu_data_description) {
6623             proto_item_append_text(dcm_pitem, ", %s", pdu_data_description);
6624             col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", pdu_data_description);
6625         }
6626     }
6627     else {
6628
6629         /* Decode Association request, response, reject, abort details */
6630         offset = dissect_dcm_assoc_header(tvb, pinfo, dcm_ptree, offset, assoc, pdu_type, pdu_len);
6631     }
6632
6633     return offset;          /* return the number of processed bytes */
6634 }
6635
6636 static void range_delete_dcm_tcp_callback(guint32 port) {
6637     dissector_delete_uint("tcp.port", port, dcm_handle);
6638 }
6639
6640 static void range_add_dcm_tcp_callback(guint32 port) {
6641     dissector_add_uint("tcp.port", port, dcm_handle);
6642 }
6643
6644 static void dcm_apply_settings(void) {
6645
6646     /* deregister first */
6647     range_foreach(global_dcm_tcp_range_backup, range_delete_dcm_tcp_callback);
6648     g_free(global_dcm_tcp_range_backup);
6649
6650     heur_dissector_delete("tcp", dissect_dcm_heuristic, proto_dcm);
6651
6652     /*  Register 'static' tcp port range specified in properties
6653         Statically defined ports take precedence over a heuristic one,
6654         I.e., if an foreign protocol claims a port, where dicom is running on
6655         We would never be called, by just having the heuristic registration
6656     */
6657
6658     range_foreach(global_dcm_tcp_range, range_add_dcm_tcp_callback);
6659
6660     /* remember settings for next time */
6661     global_dcm_tcp_range_backup = range_copy(global_dcm_tcp_range);
6662
6663     /*  Add heuristic search, if user selected it */
6664
6665     if (global_dcm_heuristic)
6666         heur_dissector_add("tcp", dissect_dcm_heuristic, proto_dcm);
6667
6668 }
6669
6670 /* Register the protocol with Wireshark */
6671
6672 void
6673 proto_register_dcm(void)
6674 {
6675 /* Setup list of header fields  See Section 1.6.1 for details*/
6676     static hf_register_info hf[] = {
6677     { &hf_dcm_pdu, { "PDU Type", "dicom.pdu.type",
6678         FT_UINT8, BASE_HEX, VALS(dcm_pdu_ids), 0, NULL, HFILL } },
6679     { &hf_dcm_pdu_len, { "PDU Length", "dicom.pdu.len",
6680         FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
6681     { &hf_dcm_pdu_type, { "PDU Detail", "dicom.pdu.detail",
6682         FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
6683
6684     { &hf_dcm_assoc_version, { "Protocol Version", "dicom.assoc.version",
6685         FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
6686     { &hf_dcm_assoc_called, { "Called  AE Title", "dicom.assoc.ae.called",
6687         FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
6688     { &hf_dcm_assoc_calling, { "Calling AE Title", "dicom.assoc.ae.calling",
6689         FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
6690     { &hf_dcm_assoc_reject_result, { "Result", "dicom.assoc.reject.result",
6691         FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
6692     { &hf_dcm_assoc_reject_source, { "Source", "dicom.assoc.reject.source",
6693         FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
6694     { &hf_dcm_assoc_reject_reason, { "Reason", "dicom.assoc.reject.reason",
6695         FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
6696     { &hf_dcm_assoc_abort_source, { "Source", "dicom.assoc.abort.source",
6697         FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
6698     { &hf_dcm_assoc_abort_reason, { "Reason", "dicom.assoc.abort.reason",
6699         FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
6700     { &hf_dcm_assoc_item_type, { "Item Type", "dicom.assoc.item.type",
6701         FT_UINT8, BASE_HEX, VALS(dcm_assoc_item_type), 0, NULL, HFILL } },
6702     { &hf_dcm_assoc_item_len, { "Item Length", "dicom.assoc.item.len",
6703         FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
6704
6705     { &hf_dcm_actx, { "Application Context", "dicom.actx",
6706         FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
6707     { &hf_dcm_pctx_id, { "Presentation Context ID", "dicom.pctx.id",
6708         FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
6709     { &hf_dcm_pctx_result, { "Presentation Context Result", "dicom.pctx.id",
6710         FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
6711     { &hf_dcm_pctx_abss_syntax, { "Abstract Syntax", "dicom.pctx.abss.syntax",
6712         FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
6713     { &hf_dcm_pctx_xfer_syntax, { "Transfer Syntax", "dicom.pctx.xfer.syntax",
6714         FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
6715     { &hf_dcm_info_uid, { "Implementation Class UID", "dicom.userinfo.uid",
6716         FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
6717     { &hf_dcm_info_version, { "Implementation Version", "dicom.userinfo.version",
6718         FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
6719     { &hf_dcm_pdu_maxlen, { "Max PDU Length", "dicom.max_pdu_len",
6720         FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
6721     { &hf_dcm_pdv_len, { "PDV Length", "dicom.pdv.len",
6722         FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
6723     { &hf_dcm_pdv_ctx, { "PDV Context", "dicom.pdv.ctx",
6724         FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
6725     { &hf_dcm_pdv_flags, { "PDV Flags", "dicom.pdv.flags",
6726         FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
6727     { &hf_dcm_data_tag, { "Tag", "dicom.data.tag",
6728         FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
6729
6730     { &hf_dcm_tag, { "Tag", "dicom.tag",
6731         FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
6732     { &hf_dcm_tag_vr, { "VR", "dicom.tag.vr",
6733         FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
6734     { &hf_dcm_tag_vl, { "Length", "dicom.tag.vl",
6735         FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
6736
6737     { &hf_dcm_tag_value_str, { "Value", "dicom.tag.value.str",
6738         FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
6739     { &hf_dcm_tag_value_16s, { "Value", "dicom.tag.value.16s",
6740         FT_INT16, BASE_DEC, NULL, 0, NULL, HFILL } },
6741     { &hf_dcm_tag_value_16u, { "Value", "dicom.tag.value.16u",
6742         FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
6743     { &hf_dcm_tag_value_32s, { "Value", "dicom.tag.value.32s",
6744         FT_INT32, BASE_DEC, NULL, 0, NULL, HFILL } },
6745     { &hf_dcm_tag_value_32u, { "Value", "dicom.tag.value.32u",
6746         FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
6747     { &hf_dcm_tag_value_byte, { "Value", "dicom.tag.value.byte",
6748         FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
6749
6750     /* Fragment entries */
6751     { &hf_dcm_pdv_fragments,
6752             { "Message fragments", "dicom.pdv.fragments",
6753             FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
6754     { &hf_dcm_pdv_fragment,
6755             { "Message fragment", "dicom.pdv.fragment",
6756             FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
6757     { &hf_dcm_pdv_fragment_overlap,
6758             { "Message fragment overlap", "dicom.pdv.fragment.overlap",
6759             FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
6760     { &hf_dcm_pdv_fragment_overlap_conflicts,
6761             { "Message fragment overlapping with conflicting data",
6762             "dicom.pdv.fragment.overlap.conflicts",
6763             FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
6764     { &hf_dcm_pdv_fragment_multiple_tails,
6765             { "Message has multiple tail fragments",
6766             "dicom.pdv.fragment.multiple_tails",
6767             FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
6768     { &hf_dcm_pdv_fragment_too_long_fragment,
6769             { "Message fragment too long", "dicom.pdv.fragment.too_long_fragment",
6770             FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
6771     { &hf_dcm_pdv_fragment_error,
6772             { "Message defragmentation error", "dicom.pdv.fragment.error",
6773             FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
6774     { &hf_dcm_pdv_fragment_count,
6775             { "Message fragment count", "dicom.pdv.fragment_count",
6776             FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
6777     { &hf_dcm_pdv_reassembled_in,
6778             { "Reassembled in", "dicom.pdv.reassembled.in",
6779             FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
6780     { &hf_dcm_pdv_reassembled_length,
6781             { "Reassembled PDV length", "dicom.pdv.reassembled.length",
6782             FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }
6783
6784 /*
6785     { &hf_dcm_FIELDABBREV, { "FIELDNAME", "dicom.FIELDABBREV",
6786         FIELDTYPE, FIELDBASE, FIELDCONVERT, BITMASK, "FIELDDESCR", HFILL } },
6787  */
6788     };
6789
6790 /* Setup protocol subtree array */
6791     static gint *ett[] = {
6792             &ett_dcm,
6793             &ett_assoc,
6794             &ett_assoc_header,
6795             &ett_assoc_actx,
6796             &ett_assoc_pctx,
6797             &ett_assoc_pctx_abss,
6798             &ett_assoc_pctx_xfer,
6799             &ett_assoc_info,
6800             &ett_assoc_info_uid,
6801             &ett_assoc_info_version,
6802             &ett_dcm_data,
6803             &ett_dcm_data_pdv,
6804             &ett_dcm_data_tag,
6805             &ett_dcm_data_seq,
6806             &ett_dcm_data_item,
6807             &ett_dcm_pdv,               /* used for fragments */
6808             &ett_dcm_pdv_fragment,
6809             &ett_dcm_pdv_fragments
6810     };
6811
6812     module_t *dcm_module;
6813
6814     /* Register the protocol name and description */
6815     proto_dcm = proto_register_protocol("DICOM", "DICOM", "dicom");
6816
6817     /* Required function calls to register the header fields and subtrees used */
6818     proto_register_field_array(proto_dcm, hf, array_length(hf));
6819     proto_register_subtree_array(ett, array_length(ett));
6820
6821     dcm_module = prefs_register_protocol(proto_dcm, dcm_apply_settings);
6822
6823     range_convert_str(&global_dcm_tcp_range, DICOM_DEFAULT_RANGE, 65535);
6824     global_dcm_tcp_range_backup = range_empty();
6825     prefs_register_range_preference(dcm_module, "tcp.port",
6826         "DICOM Ports", "DICOM Ports range", &global_dcm_tcp_range, 65535);
6827
6828     prefs_register_bool_preference(dcm_module, "heuristic",
6829             "Search on any TCP Port (heuristic mode)",
6830             "When enabled, the DICOM dissector will parse all TCP packets "
6831             "not handled by any other dissector and look for an association request. "
6832             "Disabled by default, to preserve resources for the non DICOM community.",
6833             &global_dcm_heuristic);
6834
6835     prefs_register_bool_preference(dcm_module, "export_header",
6836             "Create Meta Header on Export",
6837             "Create DICOM File Meta Header according to PS 3.10 on export for PDUs. "
6838             "If the captured PDV does not contain a SOP Class UID and SOP Instance UID "
6839             "(e.g. for command PDVs), wireshark specific ones will be created.",
6840             &global_dcm_export_header);
6841
6842     prefs_register_uint_preference(dcm_module, "export_minsize",
6843             "Min. item size in bytes to export",
6844             "Do not show items below this size in the export list. "
6845             "Set it to 0, to see DICOM commands and responses in the list. "
6846             "Set it higher, to just export DICOM IODs (i.e. CT Images, RT Structures).", 10,
6847             &global_dcm_export_minsize);
6848
6849     prefs_register_bool_preference(dcm_module, "seq_tree",
6850             "Create subtrees for Sequences and Items",
6851             "Create a node for sequences and items, and show children in a hierarchy. "
6852             "Deselect this option, if you prefer a flat display or e.g. "
6853             "when using TShark to create a text output.",
6854             &global_dcm_seq_subtree);
6855
6856     prefs_register_bool_preference(dcm_module, "tag_tree",
6857             "Create subtrees for DICOM Tags",
6858             "Create a node for a tag and show tag details as single elements. "
6859             "This can be useful to debug a tag and to allow display filters on these attributes. "
6860             "When using TShark to create a text output, it's better to have it disabled. ",
6861             &global_dcm_tag_subtree);
6862
6863     prefs_register_bool_preference(dcm_module, "cmd_details",
6864             "Show command details in header",
6865             "Show message ID and number of completed, remaining, warned or failed operations in header and info column.",
6866             &global_dcm_cmd_details);
6867
6868     prefs_register_bool_preference(dcm_module, "pdv_reassemble",
6869             "Merge fragmented PDVs",
6870             "Decode all DICOM tags in the last PDV. This will ensure the proper reassembly. "
6871             "When not set, the decoding may fail and the exports may become corrupt.",
6872             &global_dcm_reassemble);
6873
6874     dicom_eo_tap = register_tap("dicom_eo"); /* DICOM Export Object tap */
6875
6876     register_init_routine(&dcm_init);
6877 }
6878
6879
6880 /* If this dissector uses sub-dissector registration add a registration routine.
6881    This format is required because a script is used to find these routines and
6882    create the code that calls these routines.
6883 */
6884 void
6885 proto_reg_handoff_dcm(void)
6886 {
6887
6888     dcm_handle = new_create_dissector_handle(dissect_dcm_static, proto_dcm);
6889
6890     dcm_apply_settings();       /* Register static and heuristic ports */
6891
6892 }
6893
6894
6895 /*
6896
6897 PDU's
6898 01 ASSOC-RQ
6899  1    1 reserved
6900  2    4 length
6901  6    2 protocol version (0x0 0x1)
6902  8    2 reserved
6903 10   16 dest aetitle
6904 26   16 src  aetitle
6905 42   32 reserved
6906 74    - presentation data value items
6907
6908 02 A-ASSOC-AC
6909     1 reserved
6910     4 length
6911     2 protocol version (0x0 0x1)
6912     2 reserved
6913    16 dest aetitle (not checked)
6914    16 src  aetitle (not checked)
6915    32 reserved
6916     - presentation data value items
6917
6918 03 ASSOC-RJ
6919     1 reserved
6920     4 length (4)
6921     1 reserved
6922     1 result  (1 reject perm, 2 reject transient)
6923     1 source  (1 service user, 2 service provider, 3 service profider)
6924     1 reason
6925         1 == source
6926             1 no reason given
6927             2 application context name not supported
6928             3 calling aetitle not recognized
6929             7 called aetitle not recognized
6930         2 == source
6931             1 no reason given
6932             2 protocol version not supported
6933         3 == source
6934             1 temporary congestion
6935             2 local limit exceeded
6936
6937 04 P-DATA
6938  1  1 reserved
6939  2  4 length
6940     - (1+) presentation data value (PDV) items
6941  6      4 length
6942 10      1 Presentation Context ID (odd ints 1 - 255)
6943         - PDV
6944 11      1 header
6945             0x01 if set, contains Message Command info, else Message Data
6946             0x02 if set, contains last fragment
6947
6948 05 A-RELEASE-RQ
6949     1 reserved
6950     4 length (4)
6951     4 reserved
6952
6953 06 A-RELEASE-RP
6954     1 reserved
6955     4 length (4)
6956     4 reserved
6957
6958 07 A-ABORT
6959     1  reserved
6960     4  length (4)
6961     2  reserved
6962     1  source  (0 = user, 1 = provider)
6963     1  reason  if 1 == source (0 not spec, 1 unrecognized, 2 unexpected 4 unrecognized param, 5 unexpected param, 6 invalid param)
6964
6965
6966
6967 ITEM's
6968 10 Application Context
6969     1 reserved
6970     2 length
6971     - name
6972
6973 20 Presentation Context
6974     1 reserved
6975     2 length
6976     1 Presentation context id
6977     3 reserved
6978     - (1) abstract and (1+) transfer syntax sub-items
6979
6980 21 Presentation Context (Reply)
6981     1 reserved
6982     2 length
6983     1 ID (odd int's 1-255)
6984     1 reserved
6985     1 result (0 accept, 1 user-reject, 2 no-reason, 3 abstract not supported, 4- transfer syntax not supported)
6986     1 reserved
6987     - (1) type 40
6988
6989 30 Abstract syntax
6990     1 reserved
6991     2 length
6992     - name (<= 64)
6993
6994 40 Transfer syntax
6995     1 reserved
6996     2 length
6997     - name (<= 64)
6998
6999 50 user information
7000     1 reserved
7001     2 length
7002     - user data
7003
7004 51 max length
7005     1 reserved
7006     2 length (4)
7007     4 max PDU lengths
7008
7009 From 3.7 Annex D Association Negotiation
7010 ========================================
7011
7012 52 IMPLEMENTATION CLASS UID
7013     1 Item-type 52H
7014     1 Reserved
7015     2 Item-length
7016     n Implementation-class-uid
7017
7018 55 IMPLEMENTATION VERSION NAME
7019     1 Item-type 55H
7020     1 Reserved
7021     2 Item-length
7022     n Implementation-version-name
7023
7024 53 ASYNCHRONOUS OPERATIONS WINDOW
7025     1 Item-type 53H
7026     1 Reserved
7027     2 Item-length
7028     2 Maximum-number-operations-invoked
7029     2 Maximum-number-operations-performed
7030
7031 54 SCP/SCU ROLE SELECTION
7032     1 Item-type 54H
7033     1 Reserved
7034     2 Item-length (n)
7035     2 UID-length (m)
7036     m SOP-class-uid
7037     1 SCU-role
7038       0 - non support of the SCU role
7039       1 - support of the SCU role
7040     1 SCP-role
7041       0 - non support of the SCP role
7042       1 - support of the SCP role.
7043
7044 56 SOP CLASS EXTENDED NEGOTIATION
7045     1 Item-type 56H
7046     1 Reserved
7047     2 Item-Length (n)
7048     2 SOP-class-uid-length (m)
7049     m SOP-class-uid
7050     n-m Service-class-application-information
7051
7052 57 SOP CLASS COMMON EXTENDED NEGOTIATION
7053     1 Item-type 57H
7054     1 Sub-item-version
7055     2 Item-Length
7056     2 SOP-class-uid-length (m)
7057     7-x   SOP-class-uid The SOP Class identifier encoded as a UID as defined in PS 3.5.
7058     (x+1)-(x+2) Service-class-uid-length  The Service-class-uid-length shall be the number of bytes in the Service-class-uid field. It shall be encoded as an unsigned binary number.
7059     (x+3)-y Service-class-uid The Service Class identifier encoded as a UID as defined in PS 3.5.
7060     (y+1)-(y+2) Related-general-sop-class-identification-length The Related-general-sop-class-identification-length shall be the number of bytes in the Related-general-sop-class-identification field. Shall be zero if no Related General SOP Classes are identified.
7061     (y+3)-z Related-general-sop-class-identification  The Related-general-sop-class-identification is a sequence of pairs of length and UID sub-fields.  Each pair of sub-fields shall be formatted in accordance with Table D.3-13.
7062     (z+1)-k Reserved  Reserved for additional fields of the sub-item. Shall be zero-length for Version 0 of Sub-item definition.
7063
7064     Table D.3-13
7065     RELATED-GENERAL-SOP-CLASS-IDENTIFICATION SUB-FIELDS
7066     Bytes Sub-Field Name    Description of Sub-Field
7067     1-2 Related-general-sop-class-uid-length      The Related-general-sop-class-uid-length shall be the number of bytes in the Related-general-sop-class-uid sub-field. It shall be encoded as an unsigned binary number.
7068     3-n Related-general-sop-class-uid The Related General SOP Class identifier encoded as a UID as defined in PS 3.5.
7069
7070 58 User Identity Negotiation
7071     1 Item-type 58H
7072     1 Reserved
7073     2 Item-length
7074     1 User-Identity-Type  Field value shall be in the range 1 to 4 with the following meanings:
7075         1 - Username as a string in UTF-8
7076         2 - Username as a string in UTF-8 and passcode
7077         3 - Kerberos Service ticket
7078         4 - SAML Assertion
7079         Other values are reserved for future standardization.
7080     1 Positive-response-requested Field value:
7081         0 - no response requested
7082         1 - positive response requested
7083     2 Primary-field-length  The User-Identity-Length shall contain the length of the User-Identity value.
7084     9-n Primary-field   This field shall convey the user identity, either the username as a series of characters, or the Kerberos Service ticket encoded in accordance with RFC-1510.
7085     n+1-n+2 Secondary-field-length  This field shall be non-zero only if User-Identity-Type has the value 2.  It shall contain the length of the secondary-field.
7086     n+3-m Secondary-field   This field shall be present only if User-Identity-Type has the value 2.  It shall contain the Passcode value.
7087
7088 59 User Identity Negotiation Reply
7089     1 Item-type 59H
7090     1 Reserved
7091     2 Item-length
7092     5-6 Server-response-length  This field shall contain the number of bytes in the Server-response.  May be zero.
7093     7-n Server-response This field shall contain the Kerberos Server ticket, encoded in accordance with RFC-1510, if the User-Identity-Type value in the A-ASSOCIATE-RQ was 3. This field shall contain the SAML response if the User-Identity-Type value in the A-ASSOCIATE-RQ was 4. This field shall be zero length if the value of the User-Identity-Type in the A-ASSOCIATE-RQ was 1 or 2.
7094
7095  */