Commit 2db5366cbb6102e9f6db7c82601d115154c240d3
1 parent
b5f587dd
implemented matFormat::read
Showing
2 changed files
with
113 additions
and
0 deletions
sdk/core/qtutils.h
sdk/plugins/format.cpp
| ... | ... | @@ -185,6 +185,118 @@ BR_REGISTER(Format, maskFormat) |
| 185 | 185 | |
| 186 | 186 | /*! |
| 187 | 187 | * \ingroup formats |
| 188 | + * \brief MATLAB <tt>.mat</tt> format. | |
| 189 | + * \author Josh Klontz \cite jklontz | |
| 190 | + * http://www.mathworks.com/help/pdf_doc/matlab/matfile_format.pdf | |
| 191 | + */ | |
| 192 | +class matFormat : public Format | |
| 193 | +{ | |
| 194 | + Q_OBJECT | |
| 195 | + | |
| 196 | + struct Element | |
| 197 | + { | |
| 198 | + quint32 type, bytes; | |
| 199 | + QByteArray data; | |
| 200 | + Element() : type(0), bytes(0) {} | |
| 201 | + Element(QDataStream &stream) | |
| 202 | + : type(0), bytes(0) | |
| 203 | + { | |
| 204 | + bool error = false; | |
| 205 | + error |= (stream.readRawData((char*)&type, 4) != 4); | |
| 206 | + | |
| 207 | + if (type >= 1 << 16) { | |
| 208 | + // Small data format | |
| 209 | + bytes = type; | |
| 210 | + type = type & 0x0000FFFF; | |
| 211 | + bytes = bytes >> 16; | |
| 212 | + } else { | |
| 213 | + // Regular format | |
| 214 | + error |= (stream.readRawData((char*)&bytes, 4) != 4); | |
| 215 | + } | |
| 216 | + | |
| 217 | + data.resize(bytes); | |
| 218 | + error |= (int(bytes) != stream.readRawData(data.data(), bytes)); | |
| 219 | + | |
| 220 | + // Alignment | |
| 221 | + int skipBytes = (bytes < 4) ? (4 - bytes) : 0; | |
| 222 | + if (skipBytes != 0) error |= (skipBytes != stream.skipRawData(skipBytes)); | |
| 223 | + | |
| 224 | + if (error) qFatal("matFormat::Element Unexpected end of file."); | |
| 225 | + } | |
| 226 | + | |
| 227 | + void print() const | |
| 228 | + { | |
| 229 | + qDebug() << "matFormat::Element" << type << bytes << data.size(); | |
| 230 | + } | |
| 231 | + }; | |
| 232 | + | |
| 233 | + Template read() const | |
| 234 | + { | |
| 235 | + QByteArray byteArray; | |
| 236 | + QtUtils::readFile(file, byteArray); | |
| 237 | + QDataStream f(byteArray); | |
| 238 | + | |
| 239 | + { // Check header | |
| 240 | + QByteArray header(128, 0); | |
| 241 | + f.readRawData(header.data(), 128); | |
| 242 | + if (!header.startsWith("MATLAB 5.0 MAT-file")) | |
| 243 | + qFatal("matFormat::read Invalid MAT header."); | |
| 244 | + } | |
| 245 | + | |
| 246 | + Template t(file); | |
| 247 | + | |
| 248 | + while (!f.atEnd()) { | |
| 249 | + Element element(f); | |
| 250 | + | |
| 251 | + // miCOMPRESS | |
| 252 | + if (element.type == 15) { | |
| 253 | + element.data.prepend((char*)&element.bytes, 4); // Qt zlib wrapper requires this to preallocate the buffer | |
| 254 | + QDataStream uncompressed(qUncompress(element.data)); | |
| 255 | + element = Element(uncompressed); | |
| 256 | + } | |
| 257 | + | |
| 258 | + // miMATRIX | |
| 259 | + if (element.type == 14) { | |
| 260 | + QDataStream matrix(element.data); | |
| 261 | + qint32 rows = 0, columns = 0; | |
| 262 | + int matrixType = 0; | |
| 263 | + QByteArray matrixData; | |
| 264 | + while (!matrix.atEnd()) { | |
| 265 | + Element subelement(matrix); | |
| 266 | + if (subelement.type == 5) { // Dimensions array | |
| 267 | + if (subelement.bytes == 8) { | |
| 268 | + rows = ((qint32*)subelement.data.data())[0]; | |
| 269 | + columns = ((qint32*)subelement.data.data())[1]; | |
| 270 | + } else { | |
| 271 | + qWarning("matFormat::read can only handle 2D arrays."); | |
| 272 | + } | |
| 273 | + } else if (subelement.type == 7) { //miSINGLE | |
| 274 | + matrixType = CV_32FC1; | |
| 275 | + matrixData = subelement.data; | |
| 276 | + } else if (subelement.type == 9) { //miDOUBLE | |
| 277 | + matrixType = CV_64FC1; | |
| 278 | + matrixData = subelement.data; | |
| 279 | + } | |
| 280 | + } | |
| 281 | + | |
| 282 | + if ((rows > 0) && (columns > 0) && (matrixType != 0) && !matrixData.isEmpty()) | |
| 283 | + t.append(Mat(rows, columns, matrixType, matrixData.data()).clone()); | |
| 284 | + } | |
| 285 | + } | |
| 286 | + | |
| 287 | + return t; | |
| 288 | + } | |
| 289 | + | |
| 290 | + void write(const Template &t) const | |
| 291 | + { | |
| 292 | + | |
| 293 | + } | |
| 294 | +}; | |
| 295 | + | |
| 296 | +BR_REGISTER(Format, matFormat) | |
| 297 | + | |
| 298 | +/*! | |
| 299 | + * \ingroup formats | |
| 188 | 300 | * \brief Retrieves an image from a webcam. |
| 189 | 301 | * \author Josh Klontz \cite jklontz |
| 190 | 302 | */ | ... | ... |