1 /*
2  *
3  *  Copyright (C) 2018-2019, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module:  dcmdata
15  *
16  *  Author:  Pedro Arizpe
17  *
18  *  Purpose: Encapsulate STL file into a DICOM file
19  *
20  */
21 
22 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first*/
23 #include "dcmtk/dcmdata/dctk.h"
24 #include "dcmtk/dcmdata/dcencdoc.h"
25 #include "dcmtk/ofstd/ofconapp.h"
26 
27 #ifdef WITH_ZLIB
28 #include <zlib.h>        /* for zlibVersion() */
29 #endif
30 
31 #define OFFIS_CONSOLE_APPLICATION "stl2dcm"
32 
33 static OFLogger stl2dcmLogger = OFLog::getLogger("dcmtk.apps." OFFIS_CONSOLE_APPLICATION);
34 
35 static char rcsid[] = "$dcmtk: " OFFIS_CONSOLE_APPLICATION " v"
36 OFFIS_DCMTK_VERSION " " OFFIS_DCMTK_RELEASEDATE " $";
37 
main(int argc,char * argv[])38 int main(int argc, char *argv[])
39 {
40   OFConsoleApplication app(OFFIS_CONSOLE_APPLICATION, "Encapsulate STL file into DICOM format", rcsid);
41   OFCommandLine cmd;
42   int errorCode = EXITCODE_NO_ERROR;
43   OFCondition result = EC_Normal;
44   DcmFileFormat fileformat;
45   DcmEncapsulatedDocument encapsulator;
46 
47   OFLOG_TRACE(stl2dcmLogger, "Including necessary options");
48   encapsulator.addSTLCommandlineOptions(cmd);
49   OFLOG_TRACE(stl2dcmLogger, "Evaluating command line");
50   prepareCmdLineArgs(argc, argv, OFFIS_CONSOLE_APPLICATION);
51 
52   if (app.parseCommandLine(cmd, argc, argv)) {
53     OFLOG_TRACE(stl2dcmLogger, "Checking exclusive options first");
54     if (cmd.hasExclusiveOption())
55     {
56       if (cmd.findOption("--version"))
57       {
58         app.printHeader(OFTrue /*print host identifier*/);
59         COUT << OFendl << "External libraries used: ";
60 #ifdef WITH_ZLIB
61         COUT << OFendl << "- ZLIB, Version " << zlibVersion() << OFendl;
62 #else
63         COUT << " none" << OFendl;
64 #endif
65         return EXITCODE_NO_ERROR;
66       }
67     }
68     encapsulator.parseArguments(app, cmd);
69   }
70   //print resource identifier
71   OFLOG_DEBUG(stl2dcmLogger, rcsid << OFendl);
72 
73   OFLOG_DEBUG(stl2dcmLogger, "making sure data dictionary is loaded");
74   if (!dcmDataDict.isDictionaryLoaded())
75   {
76     OFLOG_WARN(stl2dcmLogger, "no data dictionary loaded, check environment variable: "
77       << DCM_DICT_ENVIRONMENT_VARIABLE);
78   }
79   OFLOG_DEBUG(stl2dcmLogger, "Creating identifiers (and reading series data)");
80   result = encapsulator.createIdentifiers(stl2dcmLogger);
81   if (result.bad())
82   {
83     OFLOG_FATAL(stl2dcmLogger, "There was an error while reading the series data");
84     return EXITCODE_INVALID_INPUT_FILE;
85   }
86   OFLOG_INFO(stl2dcmLogger, "creating encapsulated STL object");
87   errorCode = encapsulator.insertEncapsulatedDocument(fileformat.getDataset(), stl2dcmLogger);
88   if (errorCode != EXITCODE_NO_ERROR)
89   {
90     OFLOG_ERROR(stl2dcmLogger, "unable to create STL encapsulation to DICOM format");
91     return errorCode;
92   }
93   OFLOG_INFO(stl2dcmLogger, "Generating an instance number that is guaranteed to be unique within a series.");
94   result = encapsulator.createHeader(fileformat.getDataset(), stl2dcmLogger);
95   if (result.bad())
96   {
97     OFLOG_ERROR(stl2dcmLogger, "unable to create DICOM header: " << result.text());
98     return EXITCODE_CANNOT_WRITE_OUTPUT_FILE;
99   }
100   OFLOG_INFO(stl2dcmLogger, "writing encapsulated STL object as file " << encapsulator.getOutputFileName());
101 
102   OFLOG_INFO(stl2dcmLogger, "Check if new output transfer syntax is possible");
103 
104   DcmXfer opt_oxferSyn(encapsulator.getTransferSyntax());
105 
106   fileformat.getDataset()->chooseRepresentation(encapsulator.getTransferSyntax(), NULL);
107   if (fileformat.getDataset()->canWriteXfer(encapsulator.getTransferSyntax()))
108   {
109     OFLOG_INFO(stl2dcmLogger, "Output transfer syntax " << opt_oxferSyn.getXferName() << " can be written");
110   }
111   else {
112     OFLOG_ERROR(stl2dcmLogger, "No conversion to transfer syntax " << opt_oxferSyn.getXferName() << " possible!");
113     return EXITCODE_COMMANDLINE_SYNTAX_ERROR;
114   }
115   OFLOG_INFO(stl2dcmLogger, "Checking for DICOM key overriding");
116   result = encapsulator.applyOverrideKeys(fileformat.getDataset());
117   if (result.bad())
118   {
119     OFLOG_ERROR(stl2dcmLogger, "There was a problem while overriding a key:" << OFendl
120       << result.text());
121     return EXITCODE_CANNOT_WRITE_OUTPUT_FILE;
122   }
123   OFLOG_INFO(stl2dcmLogger, "write converted DICOM file with metaheader");
124   result = encapsulator.saveFile(fileformat);
125   if (result.bad())
126   {
127     OFLOG_ERROR(stl2dcmLogger, result.text() << ": writing file: " << encapsulator.getOutputFileName());
128     return EXITCODE_CANNOT_WRITE_OUTPUT_FILE;
129   }
130 
131   OFLOG_INFO(stl2dcmLogger, "STL encapsulation successful");
132 
133   return EXITCODE_NO_ERROR;
134 }
135