Mercurial > hg > orthanc-wsi
comparison Applications/DicomToTiff.cpp @ 128:788dd04b87f5
cleaning up options in DicomToTiff
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 02 Feb 2018 17:56:48 +0100 |
parents | 7a3f4d580625 |
children | a0f9a3df1110 |
comparison
equal
deleted
inserted
replaced
127:2cb9fabb529e | 128:788dd04b87f5 |
---|---|
30 #include "../Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h" | 30 #include "../Resources/Orthanc/Plugins/Samples/Common/OrthancHttpConnection.h" |
31 | 31 |
32 #include "ApplicationToolbox.h" | 32 #include "ApplicationToolbox.h" |
33 | 33 |
34 | 34 |
35 static const char* OPTION_COLOR = "color"; | |
36 static const char* OPTION_HELP = "help"; | |
37 static const char* OPTION_INPUT = "input"; | |
38 static const char* OPTION_JPEG_QUALITY = "jpeg-quality"; | |
39 static const char* OPTION_OUTPUT = "output"; | |
40 static const char* OPTION_REENCODE = "reencode"; | |
41 static const char* OPTION_VERBOSE = "verbose"; | |
42 static const char* OPTION_VERSION = "version"; | |
43 | |
35 static bool ParseParameters(int& exitStatus, | 44 static bool ParseParameters(int& exitStatus, |
36 boost::program_options::variables_map& options, | 45 boost::program_options::variables_map& options, |
37 int argc, | 46 int argc, |
38 char* argv[]) | 47 char* argv[]) |
39 { | 48 { |
40 // Declare the supported parameters | 49 // Declare the supported parameters |
41 boost::program_options::options_description generic("Generic options"); | 50 boost::program_options::options_description generic("Generic options"); |
42 generic.add_options() | 51 generic.add_options() |
43 ("help", "Display this help and exit") | 52 (OPTION_HELP, "Display this help and exit") |
44 ("version", "Output version information and exit") | 53 (OPTION_VERSION, "Output version information and exit") |
45 ("verbose", "Be verbose in logs") | 54 (OPTION_VERBOSE, "Be verbose in logs") |
46 ; | 55 ; |
47 | 56 |
48 boost::program_options::options_description source("Options for the source DICOM image"); | 57 boost::program_options::options_description source("Options for the source DICOM image"); |
49 source.add_options() | 58 source.add_options() |
50 ("orthanc", boost::program_options::value<std::string>()->default_value("http://localhost:8042/"), | 59 ("orthanc", boost::program_options::value<std::string>()->default_value("http://localhost:8042/"), |
52 ; | 61 ; |
53 OrthancWSI::ApplicationToolbox::AddRestApiOptions(source); | 62 OrthancWSI::ApplicationToolbox::AddRestApiOptions(source); |
54 | 63 |
55 boost::program_options::options_description target("Options for the target TIFF image"); | 64 boost::program_options::options_description target("Options for the target TIFF image"); |
56 target.add_options() | 65 target.add_options() |
57 ("color", boost::program_options::value<std::string>(), "Color of the background for missing tiles (e.g. \"255,0,0\")") | 66 (OPTION_COLOR, boost::program_options::value<std::string>(), |
58 ("reencode", boost::program_options::value<bool>(), | 67 "Color of the background for missing tiles (e.g. \"255,0,0\")") |
68 (OPTION_REENCODE, boost::program_options::value<bool>(), | |
59 "Whether to re-encode each tile in JPEG (no transcoding, much slower) (Boolean)") | 69 "Whether to re-encode each tile in JPEG (no transcoding, much slower) (Boolean)") |
60 ("jpeg-quality", boost::program_options::value<int>(), "Set quality level for JPEG (0..100)") | 70 (OPTION_JPEG_QUALITY, boost::program_options::value<int>(), |
71 "Set quality level for JPEG (0..100)") | |
61 ; | 72 ; |
62 | 73 |
63 boost::program_options::options_description hidden; | 74 boost::program_options::options_description hidden; |
64 hidden.add_options() | 75 hidden.add_options() |
65 ("input", boost::program_options::value<std::string>(), "Orthanc identifier of the input series of interest") | 76 (OPTION_INPUT, boost::program_options::value<std::string>(), |
66 ("output", boost::program_options::value<std::string>(), "Output TIFF file"); | 77 "Orthanc identifier of the input series of interest") |
67 ; | 78 (OPTION_OUTPUT, boost::program_options::value<std::string>(), |
79 "Output TIFF file"); | |
68 | 80 |
69 boost::program_options::options_description allWithoutHidden; | 81 boost::program_options::options_description allWithoutHidden; |
70 allWithoutHidden.add(generic).add(source).add(target); | 82 allWithoutHidden.add(generic).add(source).add(target); |
71 | 83 |
72 boost::program_options::options_description all = allWithoutHidden; | 84 boost::program_options::options_description all = allWithoutHidden; |
73 all.add(hidden); | 85 all.add(hidden); |
74 | 86 |
75 boost::program_options::positional_options_description positional; | 87 boost::program_options::positional_options_description positional; |
76 positional.add("input", 1); | 88 positional.add(OPTION_INPUT, 1); |
77 positional.add("output", 1); | 89 positional.add(OPTION_OUTPUT, 1); |
78 | 90 |
79 bool error = false; | 91 bool error = false; |
80 | 92 |
81 try | 93 try |
82 { | 94 { |
89 LOG(ERROR) << "Error while parsing the command-line arguments: " << e.what(); | 101 LOG(ERROR) << "Error while parsing the command-line arguments: " << e.what(); |
90 error = true; | 102 error = true; |
91 } | 103 } |
92 | 104 |
93 if (!error && | 105 if (!error && |
94 options.count("help") == 0 && | 106 options.count(OPTION_HELP) == 0 && |
95 options.count("version") == 0) | 107 options.count(OPTION_VERSION) == 0) |
96 { | 108 { |
97 if (options.count("input") != 1) | 109 if (options.count(OPTION_INPUT) != 1) |
98 { | 110 { |
99 LOG(ERROR) << "No input series was specified"; | 111 LOG(ERROR) << "No input series was specified"; |
100 error = true; | 112 error = true; |
101 } | 113 } |
102 | 114 |
103 if (options.count("output") != 1) | 115 if (options.count(OPTION_OUTPUT) != 1) |
104 { | 116 { |
105 LOG(ERROR) << "No output file was specified"; | 117 LOG(ERROR) << "No output file was specified"; |
106 error = true; | 118 error = true; |
107 } | 119 } |
108 } | 120 } |
109 | 121 |
110 if (error || options.count("help")) | 122 if (error || options.count(OPTION_HELP)) |
111 { | 123 { |
112 std::cout << std::endl | 124 std::cout << std::endl |
113 << "Usage: " << argv[0] << " [OPTION]... [INPUT] [OUTPUT]" | 125 << "Usage: " << argv[0] << " [OPTION]... [INPUT] [OUTPUT]" |
114 << std::endl | 126 << std::endl |
115 << "Orthanc, lightweight, RESTful DICOM server for healthcare and medical research." | 127 << "Orthanc, lightweight, RESTful DICOM server for healthcare and medical research." |
126 } | 138 } |
127 | 139 |
128 return false; | 140 return false; |
129 } | 141 } |
130 | 142 |
131 if (options.count("version")) | 143 if (options.count(OPTION_VERSION)) |
132 { | 144 { |
133 OrthancWSI::ApplicationToolbox::PrintVersion(argv[0]); | 145 OrthancWSI::ApplicationToolbox::PrintVersion(argv[0]); |
134 return false; | 146 return false; |
135 } | 147 } |
136 | 148 |
137 if (options.count("verbose")) | 149 if (options.count(OPTION_VERBOSE)) |
138 { | 150 { |
139 Orthanc::Logging::EnableInfoLevel(true); | 151 Orthanc::Logging::EnableInfoLevel(true); |
140 } | 152 } |
141 | 153 |
142 return true; | 154 return true; |
154 | 166 |
155 uint8_t red = 255; | 167 uint8_t red = 255; |
156 uint8_t green = 255; | 168 uint8_t green = 255; |
157 uint8_t blue = 255; | 169 uint8_t blue = 255; |
158 | 170 |
159 if (options.count("color")) | 171 if (options.count(OPTION_COLOR)) |
160 { | 172 { |
161 OrthancWSI::ApplicationToolbox::ParseColor(red, green, blue, options["color"].as<std::string>()); | 173 OrthancWSI::ApplicationToolbox::ParseColor(red, green, blue, options[OPTION_COLOR].as<std::string>()); |
162 } | 174 } |
163 | 175 |
164 OrthancWSI::ImageToolbox::Set(*tile, red, green, blue); | 176 OrthancWSI::ImageToolbox::Set(*tile, red, green, blue); |
165 | 177 |
166 return tile.release(); | 178 return tile.release(); |
169 | 181 |
170 | 182 |
171 static void Run(OrthancWSI::ITiledPyramid& source, | 183 static void Run(OrthancWSI::ITiledPyramid& source, |
172 const boost::program_options::variables_map& options) | 184 const boost::program_options::variables_map& options) |
173 { | 185 { |
174 OrthancWSI::HierarchicalTiffWriter target(options["output"].as<std::string>(), | 186 OrthancWSI::HierarchicalTiffWriter target(options[OPTION_OUTPUT].as<std::string>(), |
175 source.GetPixelFormat(), | 187 source.GetPixelFormat(), |
176 OrthancWSI::ImageCompression_Jpeg, | 188 OrthancWSI::ImageCompression_Jpeg, |
177 source.GetTileWidth(), | 189 source.GetTileWidth(), |
178 source.GetTileHeight()); | 190 source.GetTileHeight()); |
179 | 191 |
180 bool reencode = (options.count("reencode") && | 192 bool reencode = (options.count(OPTION_REENCODE) && |
181 options["reencode"].as<bool>()); | 193 options[OPTION_REENCODE].as<bool>()); |
182 | 194 |
183 if (options.count("jpeg-quality")) | 195 if (options.count(OPTION_JPEG_QUALITY)) |
184 { | 196 { |
185 target.SetJpegQuality(options["jpeg-quality"].as<int>()); | 197 target.SetJpegQuality(options[OPTION_JPEG_QUALITY].as<int>()); |
186 } | 198 } |
187 | 199 |
188 std::auto_ptr<Orthanc::ImageAccessor> empty(CreateEmptyTile(target, options)); | 200 std::auto_ptr<Orthanc::ImageAccessor> empty(CreateEmptyTile(target, options)); |
189 | 201 |
190 for (unsigned int level = 0; level < source.GetLevelCount(); level++) | 202 for (unsigned int level = 0; level < source.GetLevelCount(); level++) |
194 target.AddLevel(source.GetLevelWidth(level), source.GetLevelHeight(level)); | 206 target.AddLevel(source.GetLevelWidth(level), source.GetLevelHeight(level)); |
195 } | 207 } |
196 | 208 |
197 for (unsigned int level = 0; level < source.GetLevelCount(); level++) | 209 for (unsigned int level = 0; level < source.GetLevelCount(); level++) |
198 { | 210 { |
199 LOG(WARNING) << std::string(reencode ? "Reencoding" : "Transcoding") << " level " << level; | 211 LOG(WARNING) << std::string(reencode ? "Reencoding" : "Transcoding") |
200 | 212 << " level " << level; |
201 unsigned int countX = OrthancWSI::CeilingDivision(source.GetLevelWidth(level), source.GetTileWidth()); | 213 |
202 unsigned int countY = OrthancWSI::CeilingDivision(source.GetLevelHeight(level), source.GetTileHeight()); | 214 unsigned int countX = OrthancWSI::CeilingDivision |
215 (source.GetLevelWidth(level), source.GetTileWidth()); | |
216 | |
217 unsigned int countY = OrthancWSI::CeilingDivision | |
218 (source.GetLevelHeight(level), source.GetTileHeight()); | |
203 | 219 |
204 for (unsigned int tileY = 0; tileY < countY; tileY++) | 220 for (unsigned int tileY = 0; tileY < countY; tileY++) |
205 { | 221 { |
206 for (unsigned int tileX = 0; tileX < countX; tileX++) | 222 for (unsigned int tileX = 0; tileX < countX; tileX++) |
207 { | 223 { |
248 | 264 |
249 if (!success) | 265 if (!success) |
250 { | 266 { |
251 LOG(WARNING) << "Cannot transcode a DICOM image that is not encoded using JPEG (it is " | 267 LOG(WARNING) << "Cannot transcode a DICOM image that is not encoded using JPEG (it is " |
252 << OrthancWSI::EnumerationToString(compression) | 268 << OrthancWSI::EnumerationToString(compression) |
253 << "), please use the --reencode=1 option"; | 269 << "), please use the --" << OPTION_REENCODE << "=1 option"; |
254 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); | 270 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); |
255 } | 271 } |
256 | 272 |
257 if (missing) | 273 if (missing) |
258 { | 274 { |
284 Orthanc::WebServiceParameters params; | 300 Orthanc::WebServiceParameters params; |
285 | 301 |
286 OrthancWSI::ApplicationToolbox::SetupRestApi(params, options); | 302 OrthancWSI::ApplicationToolbox::SetupRestApi(params, options); |
287 | 303 |
288 OrthancPlugins::OrthancHttpConnection orthanc(params); | 304 OrthancPlugins::OrthancHttpConnection orthanc(params); |
289 OrthancWSI::DicomPyramid source(orthanc, options["input"].as<std::string>(), | 305 OrthancWSI::DicomPyramid source(orthanc, options[OPTION_INPUT].as<std::string>(), |
290 false /* don't use cached metadata */); | 306 false /* don't use cached metadata */); |
291 | 307 |
292 OrthancWSI::TiledPyramidStatistics stats(source); | 308 OrthancWSI::TiledPyramidStatistics stats(source); |
293 Run(stats, options); | 309 Run(stats, options); |
294 } | 310 } |
295 } | 311 } |
296 catch (Orthanc::OrthancException& e) | 312 catch (Orthanc::OrthancException& e) |
297 { | 313 { |
298 LOG(ERROR) << "Terminating on exception: " << e.What(); | 314 LOG(ERROR) << "Terminating on exception: " << e.What(); |
299 | 315 |
300 if (options.count("reencode") == 0) | 316 if (options.count(OPTION_REENCODE) == 0) |
301 { | 317 { |
302 LOG(ERROR) << "Consider using option \"--reencode\""; | 318 LOG(ERROR) << "Consider using option \"--" << OPTION_REENCODE << "\""; |
303 } | 319 } |
304 | 320 |
305 exitStatus = -1; | 321 exitStatus = -1; |
306 } | 322 } |
307 | 323 |