mhdimagereader.cpp 4.73 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", "")
schultezub's avatar
schultezub committed
20
    {
21
        _properties.addProperty(&_url);
schultezub's avatar
schultezub committed
22
23

        ImageDataRAMTraits<float, 2>::ImageType* img = new ImageDataRAMTraits<float, 2>::ImageType(2, tgt::svec3(2, 2, 1), 0);
schultezub's avatar
schultezub committed
24
25
26
27
28
29
30
    }

    MhdImageReader::~MhdImageReader() {

    }

    void MhdImageReader::process() {
31
        TextFileParser tfp(_url.getValue(), true, "=");
schultezub's avatar
schultezub committed
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
        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")
schultezub's avatar
schultezub committed
63
                pt = WeaklyTypedPointer::UINT8;
schultezub's avatar
schultezub committed
64
            else if (et == "MET_CHAR")
schultezub's avatar
schultezub committed
65
                pt = WeaklyTypedPointer::INT8;
schultezub's avatar
schultezub committed
66
            else if (et == "MET_USHORT")
schultezub's avatar
schultezub committed
67
                pt = WeaklyTypedPointer::UINT16;
schultezub's avatar
schultezub committed
68
            else if (et == "MET_SHORT")
schultezub's avatar
schultezub committed
69
                pt = WeaklyTypedPointer::INT16;
schultezub's avatar
schultezub committed
70
            else if (et == "MET_UINT")
schultezub's avatar
schultezub committed
71
                pt = WeaklyTypedPointer::UINT32;
schultezub's avatar
schultezub committed
72
            else if (et == "MET_INT")
schultezub's avatar
schultezub committed
73
                pt = WeaklyTypedPointer::INT32;
schultezub's avatar
schultezub committed
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
            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") {
99
                url = _url.getValue();
schultezub's avatar
schultezub committed
100
                // find beginning of local data:
101
                tgt::File* file = FileSys.open(_url.getValue());
schultezub's avatar
schultezub committed
102
                if (!file || !file->isOpen())
103
                    throw tgt::FileException("Could not open file " + _url.getValue() + " for reading.", _url.getValue());
schultezub's avatar
schultezub committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

                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);
122
            _dataContainer.addData("output.image.read", image);
schultezub's avatar
schultezub committed
123
124
125
126
127
128
129
130
131
132
133
134
        }
        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;
        }

    }
}