mhdimagereader.cpp 4.55 KB
Newer Older
schultezub's avatar
schultezub committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "mhdimagereader.h"

#include <fstream>

#include "tgt/filesystem.h"
#include "core/datastructures/imagedatadisk.h"
#include "core/tools/textfileparser.h"

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

namespace TUMVis {
    const std::string AbstractProcessor::loggerCat_ = "TUMVis.modules.io.MhdImageReader";

    MhdImageReader::MhdImageReader() 
        : AbstractProcessor()
18
        , _url("url", "Image URL", "")
schultezub's avatar
schultezub committed
19
    {
20
        _properties.addProperty(&_url);
schultezub's avatar
schultezub committed
21
22
23
24
25
26
27
    }

    MhdImageReader::~MhdImageReader() {

    }

    void MhdImageReader::process() {
28
        TextFileParser tfp(_url.getValue(), true, "=");
schultezub's avatar
schultezub committed
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
        tfp.parse<TextFileParser::ItemSeparatorLines>();

        std::string url;
        size_t dimensionality;
        tgt::svec3 size;
        WeaklyTypedPointer::PointerType pt;
        size_t offset = 0;
        EndianHelper::Endianness e = EndianHelper::LITTLE_ENDIAN;

        // start parsing
        try {
            // image type
            if (tfp.getString("ObjectType") != "Image") {
                LERROR("Error while parsing MHD header: ObjectType = Image expected");
                return;
            }

            // 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")
                pt = WeaklyTypedPointer::UCHAR;
            else if (et == "MET_CHAR")
                pt = WeaklyTypedPointer::CHAR;
            else if (et == "MET_USHORT")
                pt = WeaklyTypedPointer::USHORT;
            else if (et == "MET_SHORT")
                pt = WeaklyTypedPointer::SHORT;
            else if (et == "MET_UINT")
                pt = WeaklyTypedPointer::UINT;
            else if (et == "MET_INT")
                pt = WeaklyTypedPointer::INT;
            else if (et == "MET_FLOAT")
                pt = WeaklyTypedPointer::FLOAT;
            else if (et == "MET_DOUBLE")
                pt = WeaklyTypedPointer::DOUBLE;
            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:
            url = tfp.getString("ElementDataFile");
            if (url == "LOCAL") {
96
                url = _url.getValue();
schultezub's avatar
schultezub committed
97
                // find beginning of local data:
98
                tgt::File* file = FileSys.open(_url.getValue());
schultezub's avatar
schultezub committed
99
                if (!file || !file->isOpen())
100
                    throw tgt::FileException("Could not open file " + _url.getValue() + " for reading.", _url.getValue());
schultezub's avatar
schultezub committed
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

                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;
            }


            // all parsing done - lets create the image:
            ImageDataDisk* image = new ImageDataDisk(url, dimensionality, size, pt, offset, e);
119
            _dataContainer.addData("output.image.read", image);
schultezub's avatar
schultezub committed
120
121
122
123
124
125
126
127
128
129
130
131
        }
        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;
        }

    }
}