mhdimagereader.cpp 7 KB
Newer Older
1
2
// ================================================================================================
// 
schultezub's avatar
schultezub committed
3
// This file is part of the CAMPVis Software Framework.
4
5
// 
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7
8
9
//      Chair for Computer Aided Medical Procedures
//      Technische Universitt Mnchen
//      Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
schultezub's avatar
schultezub committed
10
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
// 
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// 
// ================================================================================================

schultezub's avatar
schultezub committed
30
31
32
33
34
35
#include "mhdimagereader.h"

#include <fstream>

#include "tgt/filesystem.h"
#include "core/datastructures/imagedatadisk.h"
36
#include "core/datastructures/genericimagedatalocal.h"
schultezub's avatar
schultezub committed
37
38
39
40
41
42
#include "core/tools/textfileparser.h"

/*
 * Full format specification at http://www.itk.org/Wiki/MetaIO/Documentation
 */

schultezub's avatar
schultezub committed
43
44
namespace campvis {
    const std::string MhdImageReader::loggerCat_ = "CAMPVis.modules.io.MhdImageReader";
schultezub's avatar
schultezub committed
45
46
47

    MhdImageReader::MhdImageReader() 
        : AbstractProcessor()
48
49
        , p_url("url", "Image URL", "")
        , p_targetImageID("targetImageName", "Target Image ID", "MhdImageReader.output", DataNameProperty::WRITE)
schultezub's avatar
schultezub committed
50
    {
51
52
        addProperty(&p_url);
        addProperty(&p_targetImageID);
schultezub's avatar
schultezub committed
53
54
55
56
57
58
    }

    MhdImageReader::~MhdImageReader() {

    }

59
    void MhdImageReader::process(DataContainer& data) {
schultezub's avatar
schultezub committed
60
        try {
schultezub's avatar
schultezub committed
61
            // start parsing
62
            TextFileParser tfp(p_url.getValue(), true, "=");
schultezub's avatar
schultezub committed
63
64
65
66
67
68
69
70
71
72
            tfp.parse<TextFileParser::ItemSeparatorLines>();

            // init optional parameters with sane default values
            std::string url;
            size_t dimensionality;
            tgt::svec3 size;
            WeaklyTypedPointer::BaseType pt;
            size_t offset = 0;
            EndianHelper::Endianness e = EndianHelper::LITTLE_ENDIAN;

schultezub's avatar
schultezub committed
73
            // image type
74
75
76
77
78
79
80
81
            if (tfp.hasKey("ObjectType")) {
                if (tfp.getString("ObjectType") != "Image") {
                    LERROR("Error while parsing MHD header: ObjectType = Image expected");
                    return;
                }
            }
            else {
                LWARNING("No Key 'ObjectType' found - assuming Image.");
schultezub's avatar
schultezub committed
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
            }

            // dimensionality and size
            dimensionality = tfp.getSizeT("NDims");
            if (dimensionality == 2)
                size = tgt::svec3(tfp.getSvec2("DimSize"), 0);
            else if (dimensionality == 3)
                size = tfp.getSvec3("DimSize");
            else {
                LERROR("Error while parsing MHD header: Unsupported dimensionality: " << dimensionality);
                return;
            }

            // element type
            std::string et = tfp.getString("ElementType");
            if (et == "MET_UCHAR")
schultezub's avatar
schultezub committed
98
                pt = WeaklyTypedPointer::UINT8;
schultezub's avatar
schultezub committed
99
            else if (et == "MET_CHAR")
schultezub's avatar
schultezub committed
100
                pt = WeaklyTypedPointer::INT8;
schultezub's avatar
schultezub committed
101
            else if (et == "MET_USHORT")
schultezub's avatar
schultezub committed
102
                pt = WeaklyTypedPointer::UINT16;
schultezub's avatar
schultezub committed
103
            else if (et == "MET_SHORT")
schultezub's avatar
schultezub committed
104
                pt = WeaklyTypedPointer::INT16;
schultezub's avatar
schultezub committed
105
            else if (et == "MET_UINT")
schultezub's avatar
schultezub committed
106
                pt = WeaklyTypedPointer::UINT32;
schultezub's avatar
schultezub committed
107
            else if (et == "MET_INT")
schultezub's avatar
schultezub committed
108
                pt = WeaklyTypedPointer::INT32;
schultezub's avatar
schultezub committed
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
            else if (et == "MET_FLOAT")
                pt = WeaklyTypedPointer::FLOAT;
            else {
                LERROR("Error while parsing MHD header: Unsupported element type: " << et);
                return;
            }

            // further optional parameters:
            if (tfp.hasKey("HeaderSize")) {
                // header size can be -1...
                int tmp = tfp.getInt("HeaderSize");
                if (tmp >= 0)
                    offset = static_cast<int>(tmp);
            }
            if (tfp.hasKey("ElementByteOrderMSB"))
                e = (tfp.getBool("ElementByteOrderMSB") ? EndianHelper::BIG_ENDIAN : EndianHelper::LITTLE_ENDIAN);
            
            // TODO: spacing, element size, etc.


            // get raw image location:
schultezub's avatar
schultezub committed
130
            url = StringUtils::trim(tfp.getString("ElementDataFile"));
schultezub's avatar
schultezub committed
131
            if (url == "LOCAL") {
132
                url = p_url.getValue();
schultezub's avatar
schultezub committed
133
                // find beginning of local data:
134
                tgt::File* file = FileSys.open(p_url.getValue());
schultezub's avatar
schultezub committed
135
                if (!file || !file->isOpen())
136
                    throw tgt::FileException("Could not open file " + p_url.getValue() + " for reading.", p_url.getValue());
schultezub's avatar
schultezub committed
137
138
139
140
141
142
143
144
145
146
147
148
149
150

                while (!file->eof()) {
                    std::string line = StringUtils::trim(file->getLine());
                    if (line.find("ElementDataFile") == 0) {
                        offset = file->tell();
                    }
                file->close();
                delete file;
                }
            }
            else if (url == "LIST") {
                LERROR("Error while loading MHD file: Image list currently not supported.");
                return;
            }
schultezub's avatar
schultezub committed
151
            else {
152
                url = tgt::FileSystem::cleanupPath(tgt::FileSystem::dirName(p_url.getValue()) + "/" + url);
schultezub's avatar
schultezub committed
153
154
            } 

schultezub's avatar
schultezub committed
155
156
157


            // all parsing done - lets create the image:
schultezub's avatar
schultezub committed
158
            ImageDataDisk* image = new ImageDataDisk(url, dimensionality, size, pt, 1, offset, e);
159
160
            data.addData(p_targetImageID.getValue(), image);
            p_targetImageID.issueWrite();
schultezub's avatar
schultezub committed
161
162
163
164
165
166
167
168
169
170
        }
        catch (tgt::Exception& e) {
            LERROR("Error while parsing MHD header: " << e.what());
            return;
        }
        catch (std::exception& e) {
            LERROR("Error while parsing MHD header: " << e.what());
            return;
        }

171
        _invalidationLevel.setValid();
schultezub's avatar
schultezub committed
172
173
    }
}