Commit 2db5366cbb6102e9f6db7c82601d115154c240d3

Authored by Josh Klontz
1 parent b5f587dd

implemented matFormat::read

sdk/core/qtutils.h
... ... @@ -18,6 +18,7 @@
18 18 #define __QTUTILS_H
19 19  
20 20 #include <QByteArray>
  21 +#include <QDataStream>
21 22 #include <QDir>
22 23 #include <QFile>
23 24 #include <QFileInfo>
... ...
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 */
... ...