-----------------------------------------------------------------------------
DICOM DATA DICTIONARY IN DCMTK
-----------------------------------------------------------------------------

In DICOM, the Data Dictionary (part 6 of the DICOM standard) stores for all
tags their respective VR, VM, attribute name and other information.  This
information must also be made available in DCMTK.  This is accomplished
through a global data dictionary class.

The global data dictionary is loaded within a C++ constructor into the global
DcmDataDictionary class instance called dcmDataDict once it is accessed for
the first time from the code.  The dictionary content is populated by three
different approaches:  Either the content (tags, VR, ...) can be compiled
into the dictionary code, or the dictionary is filled by loading a text file
on startup from a pre-defined file path (also called an "external" data
dictionary).  Lastly, DCMTK will load one or more additional external
dictionaries from the path set in the environment variable DCMDICTPATH, if set.

The built-in approach offers the advantage that a binary will not have to
load any information from a separate file, which may get lost or used in an
outdated version.  Loading the dictionary content from a separate file,
however, has the advantage that application programs need not be recompiled
if additions or corrections are made to the data dictionary.

By default, DCMTK uses an external data dictionary on Posix systems (Linux,
Mac OS X, etc.) while a built-in dictionary is used on Windows systems.  How
these defaults can be changed or how both approaches can even be combined is
further explained below.

-----------------------------------------------------------------------------
DICTIONARY DEFAULT: AUTOCONF ON POSIX SYSTEMS
-----------------------------------------------------------------------------

By default on a Posix system the global data dictionary will attempt to load
the data dictionary from an external file.  The location is pre-configured
to $DCMTK_DAT_DIR/dicom.dic where $DCMTK_DAT_DIR is DCMTK's data installation
directory chosen using configure's --datadir option (default value: /dcmtk).
See also --datarootdir and --prefix options.  The resulting path is stored as
DCM_DICT_DEFAULT_PATH in the file config/include/dcmtk/config/osconfig.h,
which is created by Autoconf during the execution of the configure script and
thus is available to the dictionary code that includes osconfig.h.

-----------------------------------------------------------------------------
DICTIONARY DEFAULT: CMAKE ON WINDOWS AND POSIX SYSTEMS
-----------------------------------------------------------------------------

On Windows, the default behavior is to compile a fully-populated DICOM
dictionary as global data dictionary into the dcmdata library.  Thus, it is
not required to load an external data dictionary from a file.  However,
usage of external dictionaries is still possible on Windows by setting the
environment variable DCMDICTPATH accordingly (see further details below).

On Posix systems, the default setting is to load the data dictionary from an
external file (as described in the above section on Autoconf).

-----------------------------------------------------------------------------
CHANGING DICTIONARY DEFAULTS
-----------------------------------------------------------------------------

Autoconf as well as CMake provide options to change their default dictionary
behavior.  For Autoconf, configure offers the options:

  --enable-external-dict    enable loading of external dictionary (default)
  --disable-external-dict   don't load external dictionary
  --enable-builtin-dict     enable loading of built-in dictionary (default)
  --disable-builtin-dict    don't load built-in dictionary

They can be used to toggle both dictionaries on and off: If the external
dictionary is turned off, it is not tried to load it from any default
location.

When building with CMake, the related options are called

  - DCMTK_ENABLE_EXTERNAL_DICTIONARY
  - DCMTK_ENABLE_BUILTIN_DICTIONARY

-----------------------------------------------------------------------------
DICTIONARY LOAD ORDER AND USING MULTIPLE DICTIONARIES
-----------------------------------------------------------------------------

The built-in dictionary, if enabled, is always loaded first on startup,
followed by any external dictionary.  Data dictionary entries loaded later in
the load sequence override entries loaded earlier.

Note that most of the time (no matter whether using Autoconf or CMake) it
makes sense to enable only the built-in dictionary or only the external
dictionary.  If both external and built-in version are enabled, the global
data dictionary is populated first with the compiled-in data, and afterwards
the external dictionary is loaded.  If the latter is the one shipped with
DCMTK (dicom.dic) then the external dictionary provides no extra information
since it contains exactly the same data as the built-in one but only takes
time for loading.  Thus it only makes sense to enable both options if the
external dictionary is modified to include (only) additional information not
available in the built-in dictionary.

If the user disables both options, no dictionary will be loaded by default
on startup.  However, a dictionary can be defined using the DCMDICTPATH
environment variable (see below).  If DCMDICTPATH is used, the default
external dictionary will not be loaded at all.

Application programs should check that a data dictionary has been loaded
before using the functionality of the dcmdata library.  The absence of
a data dictionary is likely to cause unexpected behavior (e.g. unknown
attributes will be encoded using VR=UN).

-----------------------------------------------------------------------------
CUSTOM EXTERNAL DICTIONARIES THROUGH ENVIRONMENT VARIABLE "DCMDICTPATH"
-----------------------------------------------------------------------------

Sometimes it makes sense to change the dictionary that should be loaded
without recompiling the source code.  This can be done either by modifying
the dicom.dic that is already loaded, or, by specifying a different location
in an environment variable that is evaluated on DCMTK startup.  That
environment variable is called "DCMDICTPATH" and is considered on Windows
and Posix platforms.  If DCMDICTPATH is not set, the behavior described in
the sections above takes place (built-in and/or external dictionary from
default path is loaded).

Otherwise, the file provided in the environment variable DCMDICTPATH is loaded
and any default external dictionary is ignored (!).  However, note that the
built-in dictionary (if configured) will be always loaded.

In order to set DCMDICTPATH on Unix, the csh shell command

  setenv DCMDICTPATH $HOME/dicom.dic

would cause all applications using the dcmdata library to load the data
dictionary dicom.dic from the users home directory.

For Windows, the call

  set DCMDICTPATH=c:\dicom.dic

will cause all applications using the dcmdata library to load the data
dictionary dicom.dic from the main directory on drive C.

-----------------------------------------------------------------------------
USING MORE THAN ONE EXTERNAL DICTIONARY
-----------------------------------------------------------------------------

The DCMDICTPATH environment variable can even refer to several data
dictionaries separated by colons (":") on Unix systems, or semicolons (";")
on Windows systems.  Thus the Unix csh command:

  setenv DCMDICTPATH /usr/local/share/dcmtk/dicom.dic:$HOME/dicom.dic

would cause all applications using the dcmdata library to first load the
default data dictionary and subsequently load the data dictionary dicom.dic
from the user's home directory.  On Windows systems, an example would be:

  set DCMDICTPATH=c:\dcmtk-install\share\dcmtk\dicom.dic;c:\dicom.dic

Also here, data dictionary entries loaded later in the load sequence override
entries loaded earlier.

-----------------------------------------------------------------------------
DATA DICTIONARIES INCLUDED IN DCMTK (DICOM.DIC, PRIVATE.DIC AND BUILT-IN)
-----------------------------------------------------------------------------

An example DICOM data dictionary can be found in dcmdata/data/dicom.dic,
which is also installed (using Autoconf or CMake) and used as the default
external dictionary (if external default dictionary is enabled).

The example data dictionary is is meant to be complete and includes all
standard and retired tags from part 6 of the DICOM standard (see the header of
the file where the implemented version of the standard plus all supplements
and CPs are listed).  Also contained, since they are included in part 6, are
the official DICONDE (Digital Imaging and Communication in Nondestructive
Evaluation) and DICOS (Digital Imaging and Communications in Security) tags.

Another example dictionary included is the dcmdata/data/private.dic, which
includes all private tag information known to DCMTK developers and partly
taken over from other DICOM toolkits and various other sources like DICOM
Conformance Statements.  There is no guarantee that the tag information
contained is valid or even complete.  By default, this dictionary is not
taken into account.  It can be enabled to load on startup as an extra
external dictionary using Autoconf's configure option "--enable-private-tags"
and in CMake using the option "DCMTK_ENABLE_PRIVATE_TAGS".  Enabling will
result in private.dic being added to the DCM_DICT_DEFAULT_PATH, which lists
those external dictionaries to be loaded on startup (see above).  Note that
the private tag option is only considered for external dictionaries if
external dictionaries are not turned off.

DCMTK also includes two predefined built-in dictionaries, one fully populated
containing the information from DCMTK's dicom.dic file, and one that is empty.
Both are defined in dcdictbi.cc and the one to be used is selected by the
built-in dictionary build options (see above).

The code for a useful built-in data dictionary can be regenerated at any time
by the mkdictbi program (dcmdata/libsrc/mkdictbi).  The dcmdata library
Makefiles (for Autoconf dcmdata/libsrc/Makefile.in, and for CMake
dcmdata/libsrc/CMakeLists.txt) include a target (updatebuiltindict) for this
purpose.  After regenerating dcdictbi.cc, rebuilding the libdcmdata.a library
and relinking all your applications will ensure that the built-in data
dictionary is used.

-----------------------------------------------------------------------------
TAG NAME CONSTANTS FOR USE IN APPLICATIONS
-----------------------------------------------------------------------------

The include file dcmdata/include/dcmtk/dcmdata/dcdeftag.h can be generated
from a data dictionary by the program mkdeftag.  The include file defines tag
names for use in application programs.  The names are generated from the names
specified in the data dictionary.  Duplicate names in the data dictionary will
result in compiler warnings due to duplicate #define's when compiling code
that includes the dcdeftag.h header file.  Thus, when adding new entries to
the data dictionary, care should be taken to ensure that attribute names are
not duplicated for distinct tags.

The dcmdata library Makefiles (for Autoconf dcmdata/libsrc/Makefile.in and for
CMake dcmdata/libsrc/CMakeLists.txt) include a target (updatedeftag) that
builds the mkdeftag tool and uses it to generate the
dcmdata/include/dcmtk/dcmdata/dcdeftag.h header file.  The header file should
be regenerated whenever additions or name modifications are made to the data
dictionary.  Care should be taken before modifying any tag names since
existing application programs may already use the old name and might
subsequently fail to compile.

------------

DCMTK Development Team, Oldenburg, Germany

Last revised: 2018-09-04 (Onken).
