Skip to content

Commit 4182744

Browse files
committed
Added aliases for common DCMTK tools.
Added aliases for common tools in the 'dcmtk' app. Furthermore, tools that are know but not present in the same directory as dcmtk, are now denoted with an asterisk in the help output.
1 parent 418ee50 commit 4182744

2 files changed

Lines changed: 222 additions & 144 deletions

File tree

dcmapps/apps/dcmtk.cc

Lines changed: 150 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* Module: dcmtkapp
1515
*
16-
* Author: Tingyan Xu
16+
* Author: Tingyan Xu, Marco Eichelberg
1717
*
1818
* Purpose: dcmtk command line tool
1919
*
@@ -25,6 +25,7 @@
2525
#include "dcmtk/ofstd/ofconsol.h" /* for COUT/CERR */
2626
#include "dcmtk/ofstd/ofconapp.h" /* for OFConsoleApplication */
2727
#include "dcmtk/dcmdata/dcuid.h" /* for dcmtk version name */
28+
#include "dcmtk/ofstd/ofwhere.h" /* for OFgetExecutablePath() */
2829

2930
#define OFFIS_CONSOLE_APPLICATION "dcmtk"
3031
#define OFFIS_CONSOLE_DESCRIPTION "Execute dcmtk command line tool"
@@ -35,94 +36,144 @@ OFFIS_DCMTK_VERSION " " OFFIS_DCMTK_RELEASEDATE " $";
3536
// tool category for command line tools
3637
enum DcmAppType
3738
{
38-
AT_conversion,
39-
AT_compression,
40-
AT_network,
41-
AT_misc
39+
// internal type, only used for printTools()
40+
AT_anyType,
41+
// the following values denote specific categories
42+
AT_conversion,
43+
AT_compression,
44+
AT_network,
45+
AT_misc,
46+
AT_alias
4247
};
4348

4449
// struct for the list of tools
4550
struct DcmToolEntry
4651
{
47-
OFString name;
48-
OFString description;
49-
DcmAppType apptype;
52+
OFString name;
53+
OFString command;
54+
OFString description;
55+
DcmAppType apptype;
5056
};
5157

5258
// list of DCMTK command line tools in alphabetical order
5359
static DcmToolEntry tools[] =
5460
{
55-
{"dcm2img", "Convert DICOM image to standard image format", AT_conversion },
56-
{"dcm2json", "Convert DICOM file and data set to JSON", AT_conversion },
57-
{"dcm2xml", "Convert DICOM file and data set to XML", AT_conversion },
58-
{"dcmcjpeg", "Encode DICOM file to JPEG transfer syntax", AT_compression },
59-
{"dcmcjpls", "Encode DICOM file to JPEG-LS transfer syntax", AT_compression },
60-
{"dcmconv", "Convert DICOM file encoding", AT_conversion },
61-
{"dcmcrle", "Encode DICOM file to RLE transfer syntax", AT_compression },
62-
{"dcmdecap", "Extract file from DICOM encapsulated storage", AT_conversion },
63-
{"dcmdjpeg", "Decode JPEG-compressed DICOM file", AT_compression },
64-
{"dcmdjpls", "Decode JPEG-LS compressed DICOM file", AT_compression },
65-
{"dcmdrle", "Decode RLE-compressed DICOM file", AT_compression },
66-
{"dcmdspfn", "Export standard display curves to a text file", AT_misc },
67-
{"dcmdump", "Dump DICOM file and data set", AT_conversion },
68-
{"dcmencap", "Encapsulate document into DICOM format", AT_conversion },
69-
{"dcmftest", "Test if file uses DICOM part 10 format", AT_misc },
70-
{"dcmicmp", "Compare DICOM images and compute difference metrics", AT_misc },
71-
{"dcmmkcrv", "Add 2D curve data to image", AT_misc },
72-
{"dcmmkdir", "Create a DICOMDIR file", AT_misc },
73-
{"dcmmklut", "Create DICOM look-up tables", AT_misc },
74-
{"dcmodify", "Modify DICOM files", AT_conversion },
75-
{"dcmp2pgm", "Read DICOM image and presentation state and render bitmap", AT_conversion },
76-
{"dcmprscp", "DICOM basic grayscale print management SCP", AT_network },
77-
{"dcmprscu", "Print spooler for presentation state viewer", AT_network },
78-
{"dcmpschk", "Checking tool for presentation states", AT_misc },
79-
{"dcmpsmk", "Create DICOM grayscale softcopy presentation state", AT_misc },
80-
{"dcmpsprt", "Read DICOM images and presentation states and render print job", AT_misc },
81-
{"dcmpsrcv", "Network receive for presentation state viewer", AT_network },
82-
{"dcmpssnd", "Network send for presentation state viewer", AT_network },
83-
{"dcmqridx", "Register a DICOM image file in an image database index file", AT_misc },
84-
{"dcmqrscp", "DICOM image archive (central test node)", AT_network },
85-
{"dcmqrti", "Telnet Initiator", AT_misc },
86-
{"dcmquant", "Convert DICOM color images to palette color", AT_misc },
87-
{"dcmrecv", "Simple DICOM storage SCP (receiver)", AT_network },
88-
{"dcmscale", "Scale DICOM images", AT_misc },
89-
{"dcmsend", "Simple DICOM storage SCU (sender)", AT_network },
90-
{"dcmsign", "Sign and Verify DICOM Files", AT_misc },
91-
{"dcod2lum", "Convert hardcopy characteristic curve file to softcopy format", AT_misc },
92-
{"dconvlum", "Convert VeriLUM \"CCx_xx.dat\" files to DCMTK display files", AT_misc },
93-
{"drtdump", "Dump DICOM RT file and data set", AT_conversion },
94-
{"dsr2html", "Render DICOM SR file and data set to HTML/XHTML", AT_conversion },
95-
{"dsr2xml", "Convert DICOM SR file and data set to XML", AT_conversion },
96-
{"dsrdump", "Dump DICOM SR file and data set", AT_conversion },
97-
{"dump2dcm", "Convert ASCII dump to DICOM file", AT_conversion },
98-
{"echoscu", "DICOM verification (C-ECHO) SCU", AT_network },
99-
{"findscu", "DICOM query (C-FIND) SCU", AT_network },
100-
{"getscu", "DICOM retrieve (C-GET) SCU", AT_network },
101-
{"img2dcm", "Convert standard image formats into DICOM format", AT_conversion },
102-
{"json2dcm", "Convert JSON document to DICOM file or data set", AT_conversion },
103-
{"movescu", "DICOM retrieve (C-MOVE) SCU", AT_network },
104-
{"storescp", "DICOM storage (C-STORE) SCP", AT_network },
105-
{"storescu", "DICOM storage (C-STORE) SCU", AT_network },
106-
{"termscu", "DICOM termination SCU", AT_network },
107-
{"wlmscpfs", "DICOM Basic Worklist Management SCP (based on data files)", AT_network },
108-
{"xml2dcm", "Convert XML document to DICOM file or data set", AT_conversion },
109-
{"xml2dsr", "Convert XML document to DICOM SR file", AT_conversion }
61+
// the length of the first value ("name") should not exceed 8 characters
62+
{"dcm2img", "dcm2img", "Convert DICOM image to standard image format", AT_conversion },
63+
{"dcm2json", "dcm2json", "Convert DICOM file and data set to JSON", AT_conversion },
64+
{"dcm2xml", "dcm2xml", "Convert DICOM file and data set to XML", AT_conversion },
65+
{"dcmcjpeg", "dcmcjpeg", "Encode DICOM file to JPEG transfer syntax", AT_compression },
66+
{"dcmcjpls", "dcmcjpls", "Encode DICOM file to JPEG-LS transfer syntax", AT_compression },
67+
{"dcmconv", "dcmconv", "Convert DICOM file encoding", AT_conversion },
68+
{"dcmcrle", "dcmcrle", "Encode DICOM file to RLE transfer syntax", AT_compression },
69+
{"dcmdecap", "dcmdecap", "Extract file from DICOM encapsulated storage", AT_conversion },
70+
{"dcmdjpeg", "dcmdjpeg", "Decode JPEG-compressed DICOM file", AT_compression },
71+
{"dcmdjpls", "dcmdjpls", "Decode JPEG-LS compressed DICOM file", AT_compression },
72+
{"dcmdrle", "dcmdrle", "Decode RLE-compressed DICOM file", AT_compression },
73+
{"dcmdspfn", "dcmdspfn", "Export standard display curves to a text file", AT_misc },
74+
{"dcmdump", "dcmdump", "Dump DICOM file and data set", AT_conversion },
75+
{"dcmencap", "dcmencap", "Encapsulate document into DICOM format", AT_conversion },
76+
{"dcmftest", "dcmftest", "Test if file uses DICOM part 10 format", AT_misc },
77+
{"dcmicmp", "dcmicmp", "Compare DICOM images and compute difference metrics", AT_misc },
78+
{"dcmmkcrv", "dcmmkcrv", "Add 2D curve data to image", AT_misc },
79+
{"dcmmkdir", "dcmmkdir", "Create a DICOMDIR file", AT_misc },
80+
{"dcmmklut", "dcmmklut", "Create DICOM look-up tables", AT_misc },
81+
{"dcmodify", "dcmodify", "Modify DICOM files", AT_conversion },
82+
{"dcmp2pgm", "dcmp2pgm", "Read DICOM image and presentation state and render bitmap", AT_conversion },
83+
{"dcmprscp", "dcmprscp", "DICOM basic grayscale print management SCP", AT_network },
84+
{"dcmprscu", "dcmprscu", "Print spooler for presentation state viewer", AT_network },
85+
{"dcmpschk", "dcmpschk", "Checking tool for presentation states", AT_misc },
86+
{"dcmpsmk", "dcmpsmk", "Create DICOM grayscale softcopy presentation state", AT_misc },
87+
{"dcmpsprt", "dcmpsprt", "Read DICOM images and presentation states and render print job", AT_misc },
88+
{"dcmpsrcv", "dcmpsrcv", "Network receive for presentation state viewer", AT_network },
89+
{"dcmpssnd", "dcmpssnd", "Network send for presentation state viewer", AT_network },
90+
{"dcmqridx", "dcmqridx", "Register a DICOM image file in an image database index file", AT_misc },
91+
{"dcmqrscp", "dcmqrscp", "DICOM image archive (central test node)", AT_network },
92+
{"dcmqrti", "dcmqrti", "Telnet Initiator", AT_misc },
93+
{"dcmquant", "dcmquant", "Convert DICOM color images to palette color", AT_misc },
94+
{"dcmrecv", "dcmrecv", "Simple DICOM storage SCP (receiver)", AT_network },
95+
{"dcmscale", "dcmscale", "Scale DICOM images", AT_misc },
96+
{"dcmsend", "dcmsend", "Simple DICOM storage SCU (sender)", AT_network },
97+
{"dcmsign", "dcmsign", "Sign and Verify DICOM Files", AT_misc },
98+
{"dcod2lum", "dcod2lum", "Convert hardcopy characteristic curve file to softcopy format", AT_misc },
99+
{"dconvlum", "dconvlum", "Convert VeriLUM \"CCx_xx.dat\" files to DCMTK display files", AT_misc },
100+
{"drtdump", "drtdump", "Dump DICOM RT file and data set", AT_conversion },
101+
{"dsr2html", "dsr2html", "Render DICOM SR file and data set to HTML/XHTML", AT_conversion },
102+
{"dsr2xml", "dsr2xml", "Convert DICOM SR file and data set to XML", AT_conversion },
103+
{"dsrdump", "dsrdump", "Dump DICOM SR file and data set", AT_conversion },
104+
{"dump2dcm", "dump2dcm", "Convert ASCII dump to DICOM file", AT_conversion },
105+
{"echoscu", "echoscu", "DICOM verification (C-ECHO) SCU", AT_network },
106+
{"findscu", "findscu", "DICOM query (C-FIND) SCU", AT_network },
107+
{"getscu", "getscu", "DICOM retrieve (C-GET) SCU", AT_network },
108+
{"img2dcm", "img2dcm", "Convert standard image formats into DICOM format", AT_conversion },
109+
{"json2dcm", "json2dcm", "Convert JSON document to DICOM file or data set", AT_conversion },
110+
{"movescu", "movescu", "DICOM retrieve (C-MOVE) SCU", AT_network },
111+
{"storescp", "storescp", "DICOM storage (C-STORE) SCP", AT_network },
112+
{"storescu", "storescu", "DICOM storage (C-STORE) SCU", AT_network },
113+
{"termscu", "termscu", "DICOM termination SCU", AT_network },
114+
{"wlmscpfs", "wlmscpfs", "DICOM Basic Worklist Management SCP (based on data files)", AT_network },
115+
{"xml2dcm", "xml2dcm", "Convert XML document to DICOM file or data set", AT_conversion },
116+
{"xml2dsr", "xml2dsr", "Convert XML document to DICOM SR file", AT_conversion },
117+
118+
// aliases for common tools
119+
{"convert", "dcmconv", "Changes the encoding of a DICOM file (calls dcmconv)", AT_alias },
120+
{"dump", "dcmdump", "Dumps the contents of a DICOM file (calls dcmdump)", AT_alias },
121+
{"echo", "echoscu", "Checks whether a DICOM server is accessible (calls echoscu)", AT_alias },
122+
{"find", "findscu", "Queries a Q/R or Modality Worklist server (calls findscu)", AT_alias },
123+
{"get", "getscu", "Downloads from a Q/R server using C-GET (calls getscu)", AT_alias },
124+
{"mkdir", "dcmmkdir", "Creates a DICOMDIR file for storage media (calls dcmmkdir)", AT_alias },
125+
{"modify", "dcmodify", "Modifies the contents of a DICOM file (calls dcmodify)", AT_alias },
126+
{"move", "movescu", "Downloads from a Q/R server using C-MOVE (calls movescu)", AT_alias },
127+
{"send", "dcmsend", "Transfers DICOM instances to a Storage server (calls dcmsend)", AT_alias },
128+
{"sign", "dcmsign", "Creates and verifies digital signatures (calls dcmsign)", AT_alias },
129+
{"toimg", "dcm2img", "Renders a DICOM image to another image format (calls dcm2img)", AT_alias },
130+
{"tojson", "dcm2json", "Converts a DICOM file to JSON format (calls dcm2json)", AT_alias },
131+
{"toxml", "dcm2xml", "Converts a DICOM file to XML format (calls dcm2xml)", AT_alias }
132+
110133
};
111134

112135
static const size_t numTools = sizeof(tools) / sizeof(*tools);
113136

114-
static void printTools(DcmAppType toolType)
137+
static OFBool getExecutablePath(OFString& dirname)
138+
{
139+
// get real path in which the stub executable is located
140+
int dirname_length = 0;
141+
int length = OFgetExecutablePath(NULL, 0, &dirname_length);
142+
if (length == 0)
143+
{
144+
fprintf(stderr, "F: Cannot determine location of dcmtk executable\n");
145+
return OFFalse;
146+
}
147+
char *path = new char[length + 1];
148+
OFgetExecutablePath(path, length, &dirname_length);
149+
path[length] = '\0';
150+
path[dirname_length] = '\0';
151+
dirname = path;
152+
delete[] path;
153+
return OFTrue;
154+
}
155+
156+
static void printTools(DcmAppType toolType, OFString& dirname, OFBool& toolMissing)
115157
{
116-
size_t len = 0;
117-
for (size_t i = 0; i < numTools; ++i)
158+
OFString executable_name;
159+
for (size_t i = 0; i < numTools; ++i)
118160
{
119-
if (tools[i].apptype == toolType)
161+
if ((toolType == AT_anyType && tools[i].apptype != AT_alias) || (tools[i].apptype == toolType))
120162
{
121-
len = tools[i].name.size();
122-
COUT << " " << tools[i].name << ": ";
123-
for (size_t j = 1; j <= 8 - len; j++)
124-
COUT << " ";
125-
COUT << tools[i].description << OFendl;
163+
executable_name = dirname;
164+
executable_name += PATH_SEPARATOR;
165+
executable_name += tools[i].command;
166+
#ifdef _WIN32
167+
executable_name += ".exe";
168+
#endif
169+
const OFBool fileExists = OFStandard::fileExists(executable_name);
170+
COUT << " " << (toolType == AT_anyType ? "" : " ")
171+
<< tools[i].name << (fileExists ? " " : "*");
172+
// we assume that the maximum name length is 8 characters
173+
COUT << OFString(8 - tools[i].name.size(), ' ');
174+
COUT << " - " << tools[i].description << OFendl;
175+
if (!fileExists)
176+
toolMissing = OFTrue;
126177
}
127178
}
128179
}
@@ -142,30 +193,39 @@ static void printHelp(OFBool sorted)
142193
<< " -d --debug debug mode, print debug information\n" << OFendl;
143194

144195
COUT << "tools:" << OFendl;
196+
197+
OFBool toolMissing = OFFalse;
198+
OFString dirname;
199+
OFBool result = getExecutablePath(dirname);
200+
if (!result) return;
201+
145202
if (sorted)
146203
{
204+
// print tools sorted by category
147205
COUT << " conversion tools:" << OFendl;
148-
printTools(AT_conversion);
206+
printTools(AT_conversion, dirname, toolMissing);
149207

150208
COUT << OFendl << " compression tools:" << OFendl;
151-
printTools(AT_compression);
209+
printTools(AT_compression, dirname, toolMissing);
152210

153211
COUT << OFendl << " network tools:" << OFendl;
154-
printTools(AT_network);
212+
printTools(AT_network, dirname, toolMissing);
155213

156214
COUT << OFendl << " miscellaneous tools:" << OFendl;
157-
printTools(AT_misc);
215+
printTools(AT_misc, dirname, toolMissing);
216+
217+
COUT << OFendl << " aliases for common tools:" << OFendl;
218+
printTools(AT_alias, dirname, toolMissing);
158219
}
159220
else
160221
{
161-
size_t len;
162-
for (size_t i = 0; i < numTools; ++i) {
163-
len = tools[i].name.size();
164-
COUT << " " << tools[i].name << ": ";
165-
for (size_t j = 1; j <= 8 - len; j++)
166-
COUT << " ";
167-
COUT << tools[i].description << OFendl;
168-
}
222+
// print all tools as a flat list
223+
printTools(AT_anyType, dirname, toolMissing);
224+
}
225+
226+
if (toolMissing)
227+
{
228+
COUT << "\n * denotes tools that cannot be called because they are not present\n in the directory where the '" << OFFIS_CONSOLE_APPLICATION << "' tool is located." << OFendl;
169229
}
170230
}
171231

@@ -218,16 +278,17 @@ int main(int argc, char* argv[])
218278
}
219279

220280
// find corresponding applet and call.
221-
for (size_t i = 0; i < numTools; ++i) {
281+
for (size_t i = 0; i < numTools; ++i)
282+
{
222283
if (tool == tools[i].name)
223284
{
224-
return OFstub_main(argc - offset, argv + offset, tool.c_str(), tool.c_str(), OFFalse /* printWarning */, debug);
285+
return OFstub_main(argc - offset, argv + offset, tools[i].command.c_str(), tools[i].command.c_str(), OFFalse /* printWarning */, debug);
225286
}
226287
}
227288

228-
// If not in list, print error
289+
// if not in list, print error
229290
CERR << OFFIS_CONSOLE_APPLICATION << ": there is no DCMTK tool named \"" << tool
230-
<< "\".\nTo show the list of available tools, call \"" << OFFIS_CONSOLE_APPLICATION
231-
<< " --help\"." << OFendl;
291+
<< "\".\nTo show the list of available tools, call \"" << OFFIS_CONSOLE_APPLICATION
292+
<< " --help\"." << OFendl;
232293
return EXITCODE_COMMANDLINE_SYNTAX_ERROR;
233294
}

0 commit comments

Comments
 (0)