1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2008-2015 Imperial College London
5  * Copyright 2008-2013 Daniel Rueckert, Julia Schnabel
6  * Copyright 2013-2015 Andreas Schuh
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #include "mirtk/Common.h"
22 #include "mirtk/Options.h"
23 
24 #include "mirtk/IOConfig.h"
25 #include "mirtk/GenericImage.h"
26 
27 using namespace mirtk;
28 
29 
30 // =============================================================================
31 // Help
32 // =============================================================================
33 
34 // -----------------------------------------------------------------------------
PrintHelp(const char * name)35 void PrintHelp(const char *name)
36 {
37   cout << "\n";
38   cout << "Usage: convert <input> <output> [options]\n";
39   cout << "\n";
40   cout << "Description:\n";
41   cout << "  Converts an image from one voxel type to another.\n";
42   cout << "\n";
43   cout << "Optional arguments:\n";
44   cout << "  -char|uchar|short|ushort|float|double   Output voxel type.\n";
45   cout << "  -rescale <min> <max>                    Output minimum and maximum intensity.\n";
46   PrintStandardOptions(cout);
47   cout << "\n";
48 }
49 
50 // =============================================================================
51 // Main
52 // =============================================================================
53 
54 // -----------------------------------------------------------------------------
main(int argc,char * argv[])55 int main(int argc, char *argv[])
56 {
57   // Parse arguments
58   EXPECTS_POSARGS(2);
59 
60   const char *input_name  = POSARG(1);
61   const char *output_name = POSARG(2);
62 
63   int    voxel_type = MIRTK_VOXEL_UNKNOWN;
64   double min_value  = numeric_limits<double>::quiet_NaN();
65   double max_value  = numeric_limits<double>::quiet_NaN();
66 
67   for (ALL_OPTIONS) {
68     if      (OPTION("-char"))   voxel_type = MIRTK_VOXEL_CHAR;
69     else if (OPTION("-uchar"))  voxel_type = MIRTK_VOXEL_UNSIGNED_CHAR;
70     else if (OPTION("-short"))  voxel_type = MIRTK_VOXEL_SHORT;
71     else if (OPTION("-ushort")) voxel_type = MIRTK_VOXEL_UNSIGNED_SHORT;
72     else if (OPTION("-float"))  voxel_type = MIRTK_VOXEL_FLOAT;
73     else if (OPTION("-double")) voxel_type = MIRTK_VOXEL_DOUBLE;
74     else if (OPTION("-binary")) voxel_type = MIRTK_VOXEL_BINARY;
75     else if (OPTION("-byte"))   voxel_type = MIRTK_VOXEL_BYTE;
76     else if (OPTION("-grey"))   voxel_type = MIRTK_VOXEL_GREY;
77     else if (OPTION("-real"))   voxel_type = MIRTK_VOXEL_REAL;
78     else if (OPTION("-rescale")) {
79       PARSE_ARGUMENT(min_value);
80       PARSE_ARGUMENT(max_value);
81     }
82     else HANDLE_COMMON_OR_UNKNOWN_OPTION();
83   }
84 
85   // Read image
86   InitializeIOLibrary();
87   UniquePtr<BaseImage> input(BaseImage::New(input_name));
88   if (voxel_type == MIRTK_VOXEL_UNKNOWN) {
89     voxel_type = input->GetDataType();
90   }
91 
92   // Scale image
93   if (!IsNaN(min_value) || !IsNaN(max_value)) {
94     if (IsNaN(min_value) || IsNaN(max_value)) {
95       double vmin, vmax;
96       input->GetMinMaxAsDouble(vmin, vmax);
97       if (IsNaN(min_value)) min_value = vmin;
98       if (IsNaN(max_value)) max_value = vmax;
99     }
100     if (min_value >= max_value) swap(min_value, max_value);
101     if (voxel_type != MIRTK_VOXEL_FLOAT && voxel_type != MIRTK_VOXEL_DOUBLE) {
102       input.reset(new GenericImage<double>(*input));
103     }
104     input->PutMinMaxAsDouble(min_value, max_value);
105   }
106 
107   // Convert image
108   UniquePtr<BaseImage> output(BaseImage::New(voxel_type));
109   *output = *input;
110 
111   // Write image
112   output->Write(output_name);
113 
114   return 0;
115 }
116