mhdimagereader.cpp 4.98 KB
Newer Older
schultezub's avatar
schultezub committed
1
2
3
4
5
6
#include "mhdimagereader.h"

#include <fstream>

#include "tgt/filesystem.h"
#include "core/datastructures/imagedatadisk.h"
schultezub's avatar
schultezub committed
7
#include "core/datastructures/imagedataram.h"
schultezub's avatar
schultezub committed
8
9
10
11
12
13
14
15
16
17
18
#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()
19
        , _url("url", "Image URL", "")
20
        , _targetImageID("targetImageName", "Target Image ID", "MhdImageReader.output")
schultezub's avatar
schultezub committed
21
    {
22
        _properties.addProperty(&_url);
23
        _properties.addProperty(&_targetImageID);
schultezub's avatar
schultezub committed
24

25
26
        // just testing some type traits...
        //ImageDataRAMTraits<float, 2>::ImageType* img = new ImageDataRAMTraits<float, 2>::ImageType(2, tgt::svec3(2, 2, 1), 0);
schultezub's avatar
schultezub committed
27
28
29
30
31
32
    }

    MhdImageReader::~MhdImageReader() {

    }

33
    void MhdImageReader::process(DataContainer& data) {
34
        TextFileParser tfp(_url.getValue(), true, "=");
schultezub's avatar
schultezub committed
35
36
        tfp.parse<TextFileParser::ItemSeparatorLines>();

37
        // init optional parameters with sane default values
schultezub's avatar
schultezub committed
38
39
40
        std::string url;
        size_t dimensionality;
        tgt::svec3 size;
41
        WeaklyTypedPointer::BaseType pt;
schultezub's avatar
schultezub committed
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
        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")
schultezub's avatar
schultezub committed
67
                pt = WeaklyTypedPointer::UINT8;
schultezub's avatar
schultezub committed
68
            else if (et == "MET_CHAR")
schultezub's avatar
schultezub committed
69
                pt = WeaklyTypedPointer::INT8;
schultezub's avatar
schultezub committed
70
            else if (et == "MET_USHORT")
schultezub's avatar
schultezub committed
71
                pt = WeaklyTypedPointer::UINT16;
schultezub's avatar
schultezub committed
72
            else if (et == "MET_SHORT")
schultezub's avatar
schultezub committed
73
                pt = WeaklyTypedPointer::INT16;
schultezub's avatar
schultezub committed
74
            else if (et == "MET_UINT")
schultezub's avatar
schultezub committed
75
                pt = WeaklyTypedPointer::UINT32;
schultezub's avatar
schultezub committed
76
            else if (et == "MET_INT")
schultezub's avatar
schultezub committed
77
                pt = WeaklyTypedPointer::INT32;
schultezub's avatar
schultezub committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
            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") {
103
                url = _url.getValue();
schultezub's avatar
schultezub committed
104
                // find beginning of local data:
105
                tgt::File* file = FileSys.open(_url.getValue());
schultezub's avatar
schultezub committed
106
                if (!file || !file->isOpen())
107
                    throw tgt::FileException("Could not open file " + _url.getValue() + " for reading.", _url.getValue());
schultezub's avatar
schultezub committed
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

                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);
126
            data.addData(_targetImageID.getValue(), image);
schultezub's avatar
schultezub committed
127
128
129
130
131
132
133
134
135
136
137
138
        }
        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;
        }

    }
}