Mercurial > hg > orthanc-wsi
annotate Applications/DicomToTiff.cpp @ 125:7a3f4d580625
SSL is enabled by default for HTTPS transfers
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 02 Feb 2018 17:34:35 +0100 |
parents | a51dee6a1515 |
children | 788dd04b87f5 |
rev | line source |
---|---|
0 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
115
a51dee6a1515
upgrade to year 2018
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
98
diff
changeset
|
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium |
0 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "../Framework/DicomToolbox.h" | |
23 #include "../Framework/ImageToolbox.h" | |
24 #include "../Framework/Inputs/DicomPyramid.h" | |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
25 #include "../Framework/Inputs/TiledPyramidStatistics.h" |
0 | 26 #include "../Framework/Outputs/HierarchicalTiffWriter.h" |
27 | |
59
7a3853d51c45
Move "Framework/Orthanc/" as "Resources/Orthanc/"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
57
diff
changeset
|
28 #include "../Resources/Orthanc/Core/Logging.h" |
7a3853d51c45
Move "Framework/Orthanc/" as "Resources/Orthanc/"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
57
diff
changeset
|
29 #include "../Resources/Orthanc/Core/OrthancException.h" |
61
147bd6dc28db
refactoring using new items in the plugin toolbox of Orthanc
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
59
diff
changeset
|
30 #include "../Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h" |
59
7a3853d51c45
Move "Framework/Orthanc/" as "Resources/Orthanc/"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
57
diff
changeset
|
31 |
0 | 32 #include "ApplicationToolbox.h" |
33 | |
34 | |
35 static bool ParseParameters(int& exitStatus, | |
36 boost::program_options::variables_map& options, | |
37 int argc, | |
38 char* argv[]) | |
39 { | |
40 // Declare the supported parameters | |
41 boost::program_options::options_description generic("Generic options"); | |
42 generic.add_options() | |
43 ("help", "Display this help and exit") | |
8
62adabb8c122
Provide "--version" in command-line tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
44 ("version", "Output version information and exit") |
0 | 45 ("verbose", "Be verbose in logs") |
46 ; | |
47 | |
48 boost::program_options::options_description source("Options for the source DICOM image"); | |
49 source.add_options() | |
50 ("orthanc", boost::program_options::value<std::string>()->default_value("http://localhost:8042/"), | |
51 "URL to the REST API of the target Orthanc server") | |
52 ; | |
125
7a3f4d580625
SSL is enabled by default for HTTPS transfers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
115
diff
changeset
|
53 OrthancWSI::ApplicationToolbox::AddRestApiOptions(source); |
0 | 54 |
55 boost::program_options::options_description target("Options for the target TIFF image"); | |
56 target.add_options() | |
57 ("color", boost::program_options::value<std::string>(), "Color of the background for missing tiles (e.g. \"255,0,0\")") | |
58 ("reencode", boost::program_options::value<bool>(), | |
31 | 59 "Whether to re-encode each tile in JPEG (no transcoding, much slower) (Boolean)") |
0 | 60 ("jpeg-quality", boost::program_options::value<int>(), "Set quality level for JPEG (0..100)") |
61 ; | |
62 | |
63 boost::program_options::options_description hidden; | |
64 hidden.add_options() | |
65 ("input", boost::program_options::value<std::string>(), "Orthanc identifier of the input series of interest") | |
66 ("output", boost::program_options::value<std::string>(), "Output TIFF file"); | |
67 ; | |
68 | |
69 boost::program_options::options_description allWithoutHidden; | |
70 allWithoutHidden.add(generic).add(source).add(target); | |
71 | |
72 boost::program_options::options_description all = allWithoutHidden; | |
73 all.add(hidden); | |
74 | |
75 boost::program_options::positional_options_description positional; | |
76 positional.add("input", 1); | |
77 positional.add("output", 1); | |
78 | |
79 bool error = false; | |
80 | |
81 try | |
82 { | |
83 boost::program_options::store(boost::program_options::command_line_parser(argc, argv). | |
84 options(all).positional(positional).run(), options); | |
85 boost::program_options::notify(options); | |
86 } | |
87 catch (boost::program_options::error& e) | |
88 { | |
89 LOG(ERROR) << "Error while parsing the command-line arguments: " << e.what(); | |
90 error = true; | |
91 } | |
92 | |
93 if (!error && | |
8
62adabb8c122
Provide "--version" in command-line tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
94 options.count("help") == 0 && |
62adabb8c122
Provide "--version" in command-line tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
95 options.count("version") == 0) |
0 | 96 { |
97 if (options.count("input") != 1) | |
98 { | |
99 LOG(ERROR) << "No input series was specified"; | |
100 error = true; | |
101 } | |
102 | |
103 if (options.count("output") != 1) | |
104 { | |
105 LOG(ERROR) << "No output file was specified"; | |
106 error = true; | |
107 } | |
108 } | |
109 | |
110 if (error || options.count("help")) | |
111 { | |
112 std::cout << std::endl | |
113 << "Usage: " << argv[0] << " [OPTION]... [INPUT] [OUTPUT]" | |
114 << std::endl | |
115 << "Orthanc, lightweight, RESTful DICOM server for healthcare and medical research." | |
116 << std::endl << std::endl | |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
117 << "Convert a DICOM image for digital pathology stored in some Orthanc server as a" << std::endl |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
118 << "standard hierarchical TIFF (whose tiles are all encoded using JPEG)." |
0 | 119 << std::endl; |
120 | |
121 std::cout << allWithoutHidden << "\n"; | |
122 | |
123 if (error) | |
124 { | |
125 exitStatus = -1; | |
126 } | |
127 | |
128 return false; | |
129 } | |
130 | |
8
62adabb8c122
Provide "--version" in command-line tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
131 if (options.count("version")) |
62adabb8c122
Provide "--version" in command-line tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
132 { |
62adabb8c122
Provide "--version" in command-line tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
133 OrthancWSI::ApplicationToolbox::PrintVersion(argv[0]); |
62adabb8c122
Provide "--version" in command-line tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
134 return false; |
62adabb8c122
Provide "--version" in command-line tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
135 } |
62adabb8c122
Provide "--version" in command-line tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
136 |
0 | 137 if (options.count("verbose")) |
138 { | |
139 Orthanc::Logging::EnableInfoLevel(true); | |
140 } | |
141 | |
142 return true; | |
143 } | |
144 | |
145 | |
146 | |
147 static Orthanc::ImageAccessor* CreateEmptyTile(const OrthancWSI::IPyramidWriter& writer, | |
148 const boost::program_options::variables_map& options) | |
149 { | |
150 std::auto_ptr<Orthanc::ImageAccessor> tile | |
151 (OrthancWSI::ImageToolbox::Allocate(writer.GetPixelFormat(), | |
152 writer.GetTileWidth(), | |
153 writer.GetTileHeight())); | |
154 | |
155 uint8_t red = 255; | |
156 uint8_t green = 255; | |
157 uint8_t blue = 255; | |
158 | |
159 if (options.count("color")) | |
160 { | |
161 OrthancWSI::ApplicationToolbox::ParseColor(red, green, blue, options["color"].as<std::string>()); | |
162 } | |
163 | |
164 OrthancWSI::ImageToolbox::Set(*tile, red, green, blue); | |
165 | |
166 return tile.release(); | |
167 } | |
168 | |
169 | |
170 | |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
171 static void Run(OrthancWSI::ITiledPyramid& source, |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
172 const boost::program_options::variables_map& options) |
0 | 173 { |
174 OrthancWSI::HierarchicalTiffWriter target(options["output"].as<std::string>(), | |
175 source.GetPixelFormat(), | |
176 OrthancWSI::ImageCompression_Jpeg, | |
177 source.GetTileWidth(), | |
178 source.GetTileHeight()); | |
179 | |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
180 bool reencode = (options.count("reencode") && |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
181 options["reencode"].as<bool>()); |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
182 |
0 | 183 if (options.count("jpeg-quality")) |
184 { | |
185 target.SetJpegQuality(options["jpeg-quality"].as<int>()); | |
186 } | |
187 | |
188 std::auto_ptr<Orthanc::ImageAccessor> empty(CreateEmptyTile(target, options)); | |
189 | |
190 for (unsigned int level = 0; level < source.GetLevelCount(); level++) | |
191 { | |
192 LOG(WARNING) << "Creating level " << level << " of size " | |
193 << source.GetLevelWidth(level) << "x" << source.GetLevelHeight(level); | |
194 target.AddLevel(source.GetLevelWidth(level), source.GetLevelHeight(level)); | |
195 } | |
196 | |
197 for (unsigned int level = 0; level < source.GetLevelCount(); level++) | |
198 { | |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
199 LOG(WARNING) << std::string(reencode ? "Reencoding" : "Transcoding") << " level " << level; |
0 | 200 |
201 unsigned int countX = OrthancWSI::CeilingDivision(source.GetLevelWidth(level), source.GetTileWidth()); | |
202 unsigned int countY = OrthancWSI::CeilingDivision(source.GetLevelHeight(level), source.GetTileHeight()); | |
203 | |
204 for (unsigned int tileY = 0; tileY < countY; tileY++) | |
205 { | |
206 for (unsigned int tileX = 0; tileX < countX; tileX++) | |
207 { | |
208 LOG(INFO) << "Dealing with tile (" << tileX << "," << tileY << ") at level " << level; | |
209 | |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
210 bool missing = false; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
211 bool success = true; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
212 |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
213 // Give a first try to get the raw tile |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
214 std::string tile; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
215 OrthancWSI::ImageCompression compression; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
216 if (source.ReadRawTile(tile, compression, level, tileX, tileY)) |
0 | 217 { |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
218 if (reencode || |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
219 compression == OrthancWSI::ImageCompression_Jpeg) |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
220 { |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
221 target.WriteRawTile(tile, compression, level, tileX, tileY); |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
222 } |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
223 else |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
224 { |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
225 success = false; // Re-encoding is mandatory |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
226 } |
0 | 227 } |
228 else | |
229 { | |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
230 // Give a second try to get the decoded tile |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
231 compression = OrthancWSI::ImageCompression_Unknown; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
232 |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
233 std::auto_ptr<Orthanc::ImageAccessor> tile(source.DecodeTile(level, tileX, tileY)); |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
234 if (tile.get() == NULL) |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
235 { |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
236 // Unable to read the raw tile or to decode it: The tile is missing (sparse tiling) |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
237 missing = true; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
238 } |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
239 else if (reencode) |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
240 { |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
241 target.EncodeTile(*empty, level, tileX, tileY); |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
242 } |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
243 else |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
244 { |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
245 success = false; // Re-encoding is mandatory |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
246 } |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
247 } |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
248 |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
249 if (!success) |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
250 { |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
251 LOG(WARNING) << "Cannot transcode a DICOM image that is not encoded using JPEG (it is " |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
252 << OrthancWSI::EnumerationToString(compression) |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
253 << "), please use the --reencode=1 option"; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
254 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
255 } |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
256 |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
257 if (missing) |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
258 { |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
259 LOG(WARNING) << "Sparse tiling: Using an empty image for missing tile (" |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
260 << tileX << "," << tileY << ") at level " << level; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
261 target.EncodeTile(*empty, level, tileX, tileY); |
0 | 262 } |
263 } | |
264 } | |
265 | |
266 target.Flush(); | |
267 } | |
268 } | |
269 | |
270 | |
271 | |
272 int main(int argc, char* argv[]) | |
273 { | |
274 OrthancWSI::ApplicationToolbox::GlobalInitialize(); | |
93
14146ecd1688
Display version of the framework in the logs
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
275 OrthancWSI::ApplicationToolbox::ShowVersionInLog(argv[0]); |
0 | 276 |
277 int exitStatus = 0; | |
278 boost::program_options::variables_map options; | |
279 | |
280 try | |
281 { | |
282 if (ParseParameters(exitStatus, options, argc, argv)) | |
283 { | |
284 Orthanc::WebServiceParameters params; | |
285 | |
125
7a3f4d580625
SSL is enabled by default for HTTPS transfers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
115
diff
changeset
|
286 OrthancWSI::ApplicationToolbox::SetupRestApi(params, options); |
0 | 287 |
61
147bd6dc28db
refactoring using new items in the plugin toolbox of Orthanc
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
59
diff
changeset
|
288 OrthancPlugins::OrthancHttpConnection orthanc(params); |
69
d529d9ce3c7e
cache for DicomPyramidInstance
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
61
diff
changeset
|
289 OrthancWSI::DicomPyramid source(orthanc, options["input"].as<std::string>(), |
d529d9ce3c7e
cache for DicomPyramidInstance
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
61
diff
changeset
|
290 false /* don't use cached metadata */); |
0 | 291 |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
292 OrthancWSI::TiledPyramidStatistics stats(source); |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
31
diff
changeset
|
293 Run(stats, options); |
0 | 294 } |
295 } | |
296 catch (Orthanc::OrthancException& e) | |
297 { | |
298 LOG(ERROR) << "Terminating on exception: " << e.What(); | |
299 | |
300 if (options.count("reencode") == 0) | |
301 { | |
302 LOG(ERROR) << "Consider using option \"--reencode\""; | |
303 } | |
304 | |
305 exitStatus = -1; | |
306 } | |
307 | |
308 OrthancWSI::ApplicationToolbox::GlobalFinalize(); | |
309 | |
310 return exitStatus; | |
311 } |