File indexing completed on 2024-12-22 04:17:16

0001 /***************************************************************************
0002  *                                                                         *
0003  *   copyright : (C) 2007 The University of Toronto                        *
0004  *                   netterfield@astro.utoronto.ca                         *
0005  *                                                                         *
0006  *   This program is free software; you can redistribute it and/or modify  *
0007  *   it under the terms of the GNU General Public License as published by  *
0008  *   the Free Software Foundation; either version 2 of the License, or     *
0009  *   (at your option) any later version.                                   *
0010  *                                                                         *
0011  ***************************************************************************/
0012 
0013 #include "matlab.h"
0014 
0015 #include <QXmlStreamWriter>
0016 #include <QFileInfo>
0017 
0018 using namespace Kst;
0019 
0020 // Define enum to handle the various classes of variables with readable code
0021 // (taken from matio 1.3.4, file mat5.c static const char *class_type_desc at line 33
0022 // and turned into an enum). Some overlap with the data type, see below. I don't exactly
0023 // understand why...
0024 enum matio_class_type {UNDEFINED_CT,
0025                        CELL_ARRAY_CT,
0026                        STRUCTURE_CT,
0027                        OBJECT_CT,
0028                        CHARACTER_ARRAY_CT,
0029                        SPARSE_ARRAY_CT,
0030                        DOUBLE_PRECISION_ARRAY_CT,
0031                        SINGLE_PRECISION_ARRAY_CT,
0032                        EIGHT_BIT_SIGNED_INT_ARRAY_CT,
0033                        EIGHT_BIT_UNSIGNED_INT_ARRAY_CT,
0034                        SIXTEEN_BIT_SIGNED_INT_ARRAY_CT,
0035                        SIXTEEN_BIT_UNSIGNED_INT_ARRAY_CT,
0036                        THIRTYTWO_BIT_SIGNED_INT_ARRAY_CT,
0037                        THIRTYTWO_BIT_UNSIGNED_INT_ARRAY_CT,
0038                        MATLAB_ARRAY_CT,
0039                        COMPRESSED_DATA_CT};
0040 
0041 // Define enum to handle the various data types with readable code
0042 // (taken from matio 1.3.4, file mat5.c static const char *data_type_desc at line 39)
0043 enum matio_data_type {UNKNOWN_DT,
0044                       EIGHT_BIT_SIGNED_INT_DT,
0045                       EIGHT_BIT_UNSIGNED_INT_DT,
0046                       SIXTEEN_BIT_SIGNED_INT_DT,
0047                       SIXTEEN_BIT_UNSIGNED_INT_DT,
0048                       THIRTYTWO_BIT_SIGNED_INT_DT,
0049                       THIRTYTWO_BIT_UNSIGNED_INT_DT,
0050                       IEEE_754_SINGLE_PRECISION_DT,
0051                       RESERVED_1_DT,
0052                       IEEE_754_DOUBLE_PRECISION_DT,
0053                       RESERVED_2_DT,
0054                       RESERVED_3_DT,
0055                       SIXTYFOUR_BIT_SIGNED_INT_DT,
0056                       SIXTYFOUR_BIT_UNSIGNED_INT_DT,
0057                       MATLAB_ARRAY_DT,
0058                       COMPRESSED_DATA_DT,
0059                       UTF8_CHARACTER_DATA_DT,
0060                       UTF16_CHARACTER_DATA_DT,
0061                       UTF32_CHARACTER_DATA_DT,
0062                       STRING_DT,
0063                       CELL_ARRAY_DT,
0064                       STRUCTURE_DT};
0065 
0066 
0067 //
0068 // Scalar interface
0069 //
0070 
0071 class DataInterfaceMatlabScalar : public DataSource::DataInterface<DataScalar>
0072 {
0073 public:
0074   DataInterfaceMatlabScalar(MatlabSource& s) : matlab(s) {}
0075 
0076   // read one element
0077   int read(const QString&, DataScalar::ReadInfo&);
0078 
0079   // named elements
0080   QStringList list() const { return matlab._scalarList; }
0081   bool isListComplete() const { return true; }
0082   bool isValid(const QString&) const;
0083 
0084   // T specific
0085   const DataScalar::DataInfo dataInfo(const QString&, int frame=0) const { Q_UNUSED(frame) return DataScalar::DataInfo(); }
0086   void setDataInfo(const QString&, const DataScalar::DataInfo&) {}
0087 
0088   // meta data
0089   QMap<QString, double> metaScalars(const QString&) { return QMap<QString, double>(); }
0090   QMap<QString, QString> metaStrings(const QString&) { return QMap<QString, QString>(); }
0091 
0092 
0093 private:
0094   MatlabSource& matlab;
0095 };
0096 
0097 
0098 int DataInterfaceMatlabScalar::read(const QString& scalar, DataScalar::ReadInfo& p)
0099 {
0100   return matlab.readScalar(p.value, scalar);
0101 }
0102 
0103 
0104 bool DataInterfaceMatlabScalar::isValid(const QString& scalar) const
0105 {
0106   return  matlab._scalarList.contains( scalar );
0107 }
0108 
0109 
0110 //
0111 // String interface
0112 //
0113 
0114 class DataInterfaceMatlabString : public DataSource::DataInterface<DataString>
0115 {
0116 public:
0117   DataInterfaceMatlabString(MatlabSource& s) : matlab(s) {}
0118 
0119   // read one element
0120   int read(const QString&, DataString::ReadInfo&);
0121 
0122   // named elements
0123   QStringList list() const { return matlab._strings.keys(); }
0124   bool isListComplete() const { return true; }
0125   bool isValid(const QString&) const;
0126 
0127   // T specific
0128   const DataString::DataInfo dataInfo(const QString&, int frame=0) const { Q_UNUSED(frame) return DataString::DataInfo(); }
0129   void setDataInfo(const QString&, const DataString::DataInfo&) {}
0130 
0131   // meta data
0132   QMap<QString, double> metaScalars(const QString&) { return QMap<QString, double>(); }
0133   QMap<QString, QString> metaStrings(const QString&) { return QMap<QString, QString>(); }
0134 
0135 
0136 private:
0137   MatlabSource& matlab;
0138 };
0139 
0140 
0141 int DataInterfaceMatlabString::read(const QString& string, DataString::ReadInfo& p)
0142 {
0143   if (isValid(string) && p.value) {
0144     *p.value = matlab._strings[string];
0145     return 1;
0146   }
0147   return 0;
0148 }
0149 
0150 
0151 bool DataInterfaceMatlabString::isValid(const QString& string) const
0152 {
0153   return matlab._strings.contains( string );
0154 }
0155 
0156 
0157 
0158 
0159 /**********************
0160 Vector interface
0161 ***********************/
0162 
0163 class DataInterfaceMatlabVector : public DataSource::DataInterface<DataVector>
0164 {
0165 public:
0166   DataInterfaceMatlabVector(MatlabSource& s) : matlab(s) {}
0167 
0168   // read one element
0169   int read(const QString&, DataVector::ReadInfo&);
0170 
0171   // named elements
0172   QStringList list() const { return matlab._fieldList; }
0173   bool isListComplete() const { return true; }
0174   bool isValid(const QString&) const;
0175 
0176   // T specific
0177   const DataVector::DataInfo dataInfo(const QString&, int frame = 0) const;
0178   void setDataInfo(const QString&, const DataVector::DataInfo&) {}
0179 
0180   // meta data
0181   QMap<QString, double> metaScalars(const QString&);
0182   QMap<QString, QString> metaStrings(const QString&);
0183 
0184 
0185 private:
0186   MatlabSource& matlab;
0187 };
0188 
0189 
0190 const DataVector::DataInfo DataInterfaceMatlabVector::dataInfo(const QString &field, int) const
0191 {
0192   if (!matlab._fieldList.contains(field))
0193     return DataVector::DataInfo();
0194 
0195   return DataVector::DataInfo(matlab.frameCount(field), matlab.samplesPerFrame(field));
0196 }
0197 
0198 
0199 
0200 int DataInterfaceMatlabVector::read(const QString& field, DataVector::ReadInfo& p)
0201 {
0202   return matlab.readField(p.data, field, p.startingFrame, p.numberOfFrames);
0203 }
0204 
0205 
0206 bool DataInterfaceMatlabVector::isValid(const QString& field) const
0207 {
0208   return  matlab._fieldList.contains( field );
0209 }
0210 
0211 QMap<QString, double> DataInterfaceMatlabVector::metaScalars(const QString& field)
0212 {
0213   Q_UNUSED(field);
0214   QMap<QString, double> fieldScalars;
0215   return fieldScalars;
0216 }
0217 
0218 QMap<QString, QString> DataInterfaceMatlabVector::metaStrings(const QString& field)
0219 {
0220   QMap<QString, QString> fieldStrings;
0221   return fieldStrings;
0222 }
0223 
0224 
0225 
0226 //
0227 // Matrix interface
0228 //
0229 
0230 class DataInterfaceMatlabMatrix : public DataSource::DataInterface<DataMatrix>
0231 {
0232 public:
0233 
0234   DataInterfaceMatlabMatrix(MatlabSource& s) : matlab(s) {}
0235 
0236   // read one element
0237   int read(const QString&, DataMatrix::ReadInfo&);
0238 
0239   // named elements
0240   QStringList list() const { return matlab._matrixList; }
0241   bool isListComplete() const { return true; }
0242   bool isValid(const QString&) const;
0243 
0244   // T specific
0245   const DataMatrix::DataInfo dataInfo   (const QString&, int frame = 0) const;
0246   void setDataInfo(const QString&, const DataMatrix::DataInfo&) {}
0247 
0248   // meta data
0249   QMap<QString, double> metaScalars(const QString&) { return QMap<QString, double>(); }
0250   QMap<QString, QString> metaStrings(const QString&) { return QMap<QString, QString>(); }
0251 
0252 
0253 private:
0254   MatlabSource& matlab;
0255 };
0256 
0257 
0258 const DataMatrix::DataInfo DataInterfaceMatlabMatrix::dataInfo(const QString& matrix, int) const
0259 {
0260   if (!matlab._matrixList.contains( matrix ) ) {
0261     return DataMatrix::DataInfo();
0262   }
0263 
0264   QByteArray bytes = matrix.toLatin1();
0265   matvar_t *matvar = Mat_VarRead(matlab._matfile, bytes.data());
0266   if (!matvar) {
0267     return DataMatrix::DataInfo();
0268   }
0269 
0270   if (matvar->rank != 2) {
0271     return DataMatrix::DataInfo();
0272   }
0273 
0274   DataMatrix::DataInfo info;
0275   info.xSize = matvar->dims[0];
0276   info.ySize = matvar->dims[1];
0277 
0278   Mat_VarFree(matvar);
0279 
0280   return info;
0281 }
0282 
0283 
0284 int DataInterfaceMatlabMatrix::read(const QString& field, DataMatrix::ReadInfo& p)
0285 {
0286   int count = matlab.readMatrix(p.data->z, field);
0287 
0288   p.data->xMin = 0;
0289   p.data->yMin = 0;
0290   p.data->xStepSize = 1;
0291   p.data->yStepSize = 1;
0292 
0293   return count;
0294 }
0295 
0296 
0297 bool DataInterfaceMatlabMatrix::isValid(const QString& field) const {
0298   return matlab._matrixList.contains( field );
0299 }
0300 
0301 
0302 
0303 /**********************
0304 MatlabDatasourceSource - This class defines the main DataSource which derives from DataSource.
0305 The key functions that this class must provide is the ability to create the source, provide details about the source
0306 be able to process the data.
0307 
0308 ***********************/
0309 MatlabSource::MatlabSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e)
0310 : Kst::DataSource(store, cfg, filename, type),
0311   _matfile(0L),
0312   _config(0L),
0313   is(new DataInterfaceMatlabScalar(*this)),
0314   it(new DataInterfaceMatlabString(*this)),
0315   iv(new DataInterfaceMatlabVector(*this)),
0316   im(new DataInterfaceMatlabMatrix(*this))
0317   {
0318   setInterface(is);
0319   setInterface(it);
0320   setInterface(iv);
0321   setInterface(im);
0322 
0323   setUpdateType(None);
0324 
0325   if (!type.isEmpty() && type != "Matlab") {
0326     return;
0327   }
0328 
0329   _valid = false;
0330   _maxFrameCount = 0;
0331 
0332   _filename = filename;
0333 
0334   if (init()) {
0335     _valid = true;
0336   }
0337 
0338   registerChange();
0339 }
0340 
0341 
0342 
0343 MatlabSource::~MatlabSource() {
0344   Mat_Close(_matfile);
0345   _matfile = 0L;
0346 }
0347 
0348 
0349 void MatlabSource::reset() {
0350   Mat_Close(_matfile);
0351   _matfile = 0L;
0352   _maxFrameCount = 0;
0353   _valid = init();
0354 }
0355 
0356 
0357 // If the datasource has any predefined fields they should be populated here.
0358 bool MatlabSource::init() {
0359   // First, try to open the file
0360   _matfile = Mat_Open(_filename.toStdString().c_str(),MAT_ACC_RDONLY);
0361   if (!_matfile) {
0362     _valid = false;
0363     return false;
0364   }
0365 
0366   _scalarList.clear();
0367   _fieldList.clear();
0368   _matrixList.clear();
0369   _strings.clear();
0370 
0371   // Some standard stuff
0372   _fieldList += "INDEX";
0373   _strings = fileMetas();
0374 
0375   _maxFrameCount = 0;
0376 
0377   // Now iterate over the variables and keep the usable ones plus store some interesting data like number of samples
0378   matvar_t *matvar = Mat_VarReadNextInfo(_matfile);
0379   while (matvar) {
0380     switch (matvar->class_type) {
0381     // All array types = matrix, scalar or vector - check rank and sizes to determine which
0382     case DOUBLE_PRECISION_ARRAY_CT:
0383     case SINGLE_PRECISION_ARRAY_CT:
0384     case EIGHT_BIT_SIGNED_INT_ARRAY_CT:
0385     case EIGHT_BIT_UNSIGNED_INT_ARRAY_CT:
0386     case SIXTEEN_BIT_SIGNED_INT_ARRAY_CT:
0387     case SIXTEEN_BIT_UNSIGNED_INT_ARRAY_CT:
0388     case THIRTYTWO_BIT_SIGNED_INT_ARRAY_CT:
0389     case THIRTYTWO_BIT_UNSIGNED_INT_ARRAY_CT:
0390     case MATLAB_ARRAY_CT:
0391     case COMPRESSED_DATA_CT:
0392       // Scalar
0393       if ( (matvar->rank == 1 && matvar->dims[0] == 1) ||
0394            (matvar->rank == 2 && matvar->dims[0] == 1 && matvar->dims[1] == 1) ) {
0395         _scalarList << QString(matvar->name);
0396         // qDebug() << "Found a scalar: " << matvar->name;
0397       }
0398       // Vector
0399       if ( (matvar->rank == 1 && matvar->dims[0] > 1) ||
0400            (matvar->rank == 2 && matvar->dims[0] == 1 && matvar->dims[1] > 1) || // matrix with one "flat" dim and at least 2 samples in the other direction
0401            (matvar->rank == 2 && matvar->dims[1] == 1 && matvar->dims[0] > 1) ) { // symmetrical case to the previous one
0402         _fieldList << QString(matvar->name);
0403         int fc = (matvar->rank == 1) ? matvar->dims[0] : qMax(matvar->dims[0], matvar->dims[1]);
0404         _maxFrameCount = qMax(_maxFrameCount, fc);
0405         _frameCounts[matvar->name] = fc;
0406         // qDebug() << "Found a vector: " << matvar->name << ", size: [" << matvar->dims[0] << "x" << matvar->dims[1] << "]";
0407       }
0408       // Dimension 2 matrix
0409       if ( matvar->rank == 2 && matvar->dims[0] > 1 && matvar->dims[1] > 1 )  {
0410         _matrixList << QString(matvar->name);
0411         // qDebug() << "Found a matrix: " << matvar->name << ", size: [" << matvar->dims[0] << "x" << matvar->dims[1] << "]";
0412       }
0413       break;
0414 
0415     case CHARACTER_ARRAY_CT: { // String
0416       matvar_t *string = Mat_VarRead(_matfile, matvar->name);
0417       _strings[QString(matvar->name)] = QString((char*)string->data);
0418       Mat_VarFree(string);
0419       // qDebug() << "Found a string: " << matvar->name << ", size: [" << matvar->dims[0] << "x" << matvar->dims[1] << "]";
0420       break;
0421     }
0422 
0423     default:
0424       // qDebug() << "Variable " << matvar->name << ", type not supported (" << matvar->class_type << ")";
0425       break;
0426     }
0427 
0428 
0429     matvar = Mat_VarReadNextInfo(_matfile);
0430   }
0431   Mat_VarFree(matvar);
0432 
0433 
0434   registerChange();
0435   return true; // false if something went wrong
0436 }
0437 
0438 
0439 // Check if the data in the from the source has updated.
0440 // Considering how Matlab files are built up we can consider that they are always fixed
0441 Kst::Object::UpdateType MatlabSource::internalDataSourceUpdate() {
0442   return Kst::Object::NoChange;
0443 }
0444 
0445 
0446 int MatlabSource::readScalar(double *v, const QString& field)
0447 {
0448   matvar_t *matvar = Mat_VarRead(_matfile, field.toLatin1().data());
0449   if (matvar) { // TODO: add data type check. Or is the cast enough?
0450     *v = (double)*(double *)matvar->data;
0451     Mat_VarFree(matvar);
0452     return 1;
0453   }
0454   qDebug() << "Error reading scalar " << field;
0455   return 0;
0456 }
0457 
0458 int MatlabSource::readString(QString *stringValue, const QString& stringName)
0459 {
0460   // TODO more error handling? Especially data type
0461   matvar_t *matvar = Mat_VarRead(_matfile, stringName.toLatin1().data());
0462   if (matvar) {
0463     *stringValue = QString((const char*)matvar->data);
0464     Mat_VarFree(matvar);
0465     return 1;
0466   }
0467   return 0;
0468 }
0469 
0470 int MatlabSource::readField(double *v, const QString& field, int s, int n) {
0471 
0472   KST_DBG qDebug() << "Entering MatlabSource::readField with params: " << field << ", from " << s << " for " << n << " frames" << endl;
0473 
0474   /* For INDEX field */
0475   if (field.toLower() == "index") {
0476     if (n < 0) {
0477       v[0] = double(s);
0478       return 1;
0479     }
0480     for (int i = 0; i < n; ++i) {
0481       v[i] = double(s + i);
0482     }
0483     return n;
0484   }
0485 
0486   /* For a variable from the Matlab file */
0487   matio_data_type dataType;
0488   matvar_t *matvar = Mat_VarRead(_matfile, field.toLatin1().data());
0489   if (!matvar) {
0490     KST_DBG qDebug() << "MatlabSource: queried field " << field << " which can't be read" << endl;
0491     return -1;
0492   }
0493 
0494   if (s >= _frameCounts[field]) {
0495     return 0;
0496   }
0497 
0498   dataType = (matio_data_type) matvar->data_type;
0499   switch (dataType) { // We have to be careful with the dimension of data elements
0500   case EIGHT_BIT_SIGNED_INT_DT:
0501   {
0502     int8_t *dataPointer = (int8_t*)matvar->data;
0503     for (int i = 0; i < n; ++i) {
0504       v[i] = (double)dataPointer[i+s];
0505     }
0506   }
0507     break;
0508 
0509   case EIGHT_BIT_UNSIGNED_INT_DT:
0510   {
0511     uint8_t *dataPointer = (uint8_t*)matvar->data;
0512     for (int i = 0; i < n; ++i) {
0513       v[i] = (double)dataPointer[i+s];
0514     }
0515   }
0516     break;
0517 
0518   case SIXTEEN_BIT_SIGNED_INT_DT:
0519   {
0520     int16_t *dataPointer = (int16_t*)matvar->data;
0521     for (int i = 0; i < n; ++i) {
0522       v[i] = (double)dataPointer[i+s];
0523     }
0524   }
0525     break;
0526 
0527   case SIXTEEN_BIT_UNSIGNED_INT_DT:
0528   {
0529     uint16_t *dataPointer = (uint16_t*)matvar->data;
0530     for (int i = 0; i < n; ++i) {
0531       v[i] = (double)dataPointer[i+s];
0532     }
0533   }
0534     break;
0535 
0536   case THIRTYTWO_BIT_SIGNED_INT_DT:
0537   {
0538     int32_t *dataPointer = (int32_t*)matvar->data;
0539     for (int i = 0; i < n; ++i) {
0540       v[i] = (double)dataPointer[i+s];
0541     }
0542   }
0543     break;
0544 
0545   case THIRTYTWO_BIT_UNSIGNED_INT_DT:
0546   {
0547     uint32_t *dataPointer = (uint32_t*)matvar->data;
0548     for (int i = 0; i < n; ++i) {
0549       v[i] = (double)dataPointer[i+s];
0550     }
0551   }
0552     break;
0553 
0554   case IEEE_754_SINGLE_PRECISION_DT:
0555   {
0556     float *dataPointer = (float*)matvar->data;
0557     for (int i = 0; i < n; ++i) {
0558       v[i] = (double)dataPointer[i+s];
0559     }
0560   }
0561     break;
0562 
0563   case IEEE_754_DOUBLE_PRECISION_DT:
0564   {
0565     double *dataPointer = (double*)matvar->data;
0566     for (int i = 0; i < n; ++i) {
0567       v[i] = (double)dataPointer[i+s];
0568     }
0569   }
0570     break;
0571 
0572   case SIXTYFOUR_BIT_SIGNED_INT_DT:
0573   {
0574     int64_t *dataPointer = (int64_t*)matvar->data;
0575     for (int i = 0; i < n; ++i) {
0576       v[i] = (double)dataPointer[i+s];
0577     }
0578   }
0579     break;
0580 
0581   case SIXTYFOUR_BIT_UNSIGNED_INT_DT:
0582   {
0583     uint64_t *dataPointer = (uint64_t*)matvar->data;
0584     for (int i = 0; i < n; ++i) {
0585       v[i] = (double)dataPointer[i+s];
0586     }
0587   }
0588     break;
0589 
0590   default:
0591       KST_DBG qDebug() << "MatlabSource, field " << field << ": wrong datatype for kst, no values read" << endl;
0592       return -1;
0593       break;
0594   }
0595 
0596   KST_DBG qDebug() << "Finished reading " << field << endl;
0597   Mat_VarFree(matvar);
0598   return n;
0599 }
0600 
0601 
0602 int MatlabSource::readMatrix(double *v, const QString& field)
0603 {
0604   /* For a variable from the Matlab file */
0605   matvar_t *matvar = Mat_VarRead(_matfile, field.toLatin1().data());
0606   if (!matvar) {
0607     KST_DBG qDebug() << "MatlabSource: queried matrix " << field << " which can't be read" << endl;
0608     return -1;
0609   }
0610 
0611   // Matrices are always read from the beginning to the end
0612   // But we have to first store the data in a buffer of the right type, then copy it to v
0613   int n = matvar->dims[0] * matvar->dims[1];
0614 
0615   matio_data_type dataType = (matio_data_type) matvar->data_type;
0616   switch (dataType) {
0617   case EIGHT_BIT_SIGNED_INT_DT:
0618   {
0619     int8_t *dataPointer = (int8_t *) matvar->data;
0620     for (int i = 0; i < n; ++i) {
0621       v[i] = (double)dataPointer[i];
0622     }
0623   }
0624     break;
0625 
0626   case EIGHT_BIT_UNSIGNED_INT_DT:
0627   {
0628     uint8_t *dataPointer = (uint8_t *) matvar->data;
0629     for (int i = 0; i < n; ++i) {
0630       v[i] = (double)dataPointer[i];
0631     }
0632     free(dataPointer);
0633   }
0634     break;
0635 
0636   case SIXTEEN_BIT_SIGNED_INT_DT:
0637   {
0638     int16_t *dataPointer = (int16_t *) matvar->data;;
0639     for (int i = 0; i < n; ++i) {
0640       v[i] = (double)dataPointer[i];
0641     }
0642   }
0643     break;
0644 
0645   case SIXTEEN_BIT_UNSIGNED_INT_DT:
0646   {
0647     uint16_t *dataPointer = (uint16_t *) matvar->data;;
0648     for (int i = 0; i < n; ++i) {
0649       v[i] = (double)dataPointer[i];
0650     }
0651   }
0652     break;
0653 
0654   case THIRTYTWO_BIT_SIGNED_INT_DT:
0655   {
0656     int32_t *dataPointer = (int32_t *) matvar->data;
0657     for (int i = 0; i < n; ++i) {
0658       v[i] = (double)dataPointer[i];
0659     }
0660   }
0661     break;
0662 
0663   case THIRTYTWO_BIT_UNSIGNED_INT_DT:
0664   {
0665     uint32_t *dataPointer = (uint32_t *) matvar->data;
0666     for (int i = 0; i < n; ++i) {
0667       v[i] = (double)dataPointer[i];
0668     }
0669   }
0670     break;
0671 
0672   case IEEE_754_SINGLE_PRECISION_DT:
0673   {
0674     float *dataPointer = (float *) matvar->data;
0675     for (int i = 0; i < n; ++i) {
0676       v[i] = (double)dataPointer[i];
0677     }
0678   }
0679     break;
0680 
0681   case IEEE_754_DOUBLE_PRECISION_DT:
0682   {
0683     double *dataPointer = (double *) matvar->data;
0684     for (int i = 0; i < n; ++i) {
0685       v[i] = (double)dataPointer[i];
0686     }
0687   }
0688     break;
0689 
0690   case SIXTYFOUR_BIT_SIGNED_INT_DT:
0691   {
0692     int64_t *dataPointer = (int64_t *) matvar->data;
0693     for (int i = 0; i < n; ++i) {
0694       v[i] = (double)dataPointer[i];
0695     }
0696   }
0697     break;
0698 
0699   case SIXTYFOUR_BIT_UNSIGNED_INT_DT:
0700   {
0701     uint64_t *dataPointer = (uint64_t *) matvar->data;
0702     for (int i = 0; i < n; ++i) {
0703       v[i] = (double)dataPointer[i];
0704     }
0705   }
0706     break;
0707 
0708   default:
0709       KST_DBG qDebug() << "MatlabSource, field " << field << ": wrong datatype for kst, no values read" << endl;
0710       return -1;
0711       break;
0712   }
0713 
0714   Mat_VarFree(matvar);
0715 
0716   return n;
0717 }
0718 
0719 
0720 int MatlabSource::frameCount(const QString& field) const {
0721   if (field.isEmpty() || field.toLower() == "index") {
0722     return _maxFrameCount;
0723   } else {
0724     return _frameCounts[field];
0725   }
0726 }
0727 
0728 
0729 QString MatlabSource::fileType() const {
0730   return "Matlab Datasource";
0731 }
0732 
0733 
0734 void MatlabSource::save(QXmlStreamWriter &streamWriter) {
0735   Kst::DataSource::save(streamWriter);
0736 }
0737 
0738 int MatlabSource::samplesPerFrame(const QString& field) {
0739   return 1;
0740 }
0741 
0742 
0743 // Name used to identify the plugin.  Used when loading the plugin.
0744 QString MatlabSourcePlugin::pluginName() const { return tr("Matlab Datasource Reader"); }
0745 QString MatlabSourcePlugin::pluginDescription() const { return tr("Matlab's .mat Datasource Reader"); }
0746 
0747 /**********************
0748 MatlabDatasourcePlugin - This class defines the plugin interface to the DataSource defined by the plugin.
0749 The primary requirements of this class are to provide the necessary connections to create the object
0750 which includes providing access to the configuration widget.
0751 
0752 ***********************/
0753 
0754 Kst::DataSource *MatlabSourcePlugin::create(Kst::ObjectStore *store,
0755                                             QSettings *cfg,
0756                                             const QString &filename,
0757                                             const QString &type,
0758                                             const QDomElement &element) const {
0759 
0760   return new MatlabSource(store, cfg, filename, type, element);
0761 }
0762 
0763 
0764 // Provides the matrix list that this dataSource can provide from the provided filename.
0765 // This function should use understands to validate the file and then open and calculate the
0766 // list of matrices.
0767 QStringList MatlabSourcePlugin::matrixList(QSettings *cfg,
0768                                              const QString& filename,
0769                                              const QString& type,
0770                                              QString *typeSuggestion,
0771                                              bool *complete) const {
0772 
0773 
0774   if (typeSuggestion) {
0775     *typeSuggestion = "Matlab Datasource";
0776   }
0777   if ((!type.isEmpty() && !provides().contains(type)) ||
0778       0 == understands(cfg, filename)) {
0779     if (complete) {
0780       *complete = false;
0781     }
0782     return QStringList();
0783   }
0784   QStringList matrixList;
0785 
0786   return matrixList;
0787 
0788 }
0789 
0790 
0791 // Provides the scalar list that this dataSource can provide from the provided filename.
0792 // This function should use understands to validate the file and then open and calculate the
0793 // list of scalars if necessary.
0794 QStringList MatlabSourcePlugin::scalarList(QSettings *cfg,
0795                                             const QString& filename,
0796                                             const QString& type,
0797                                             QString *typeSuggestion,
0798                                             bool *complete) const {
0799 
0800   QStringList scalarList;
0801 
0802   if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) {
0803     if (complete) {
0804       *complete = false;
0805     }
0806     return QStringList();
0807   }
0808 
0809   if (typeSuggestion) {
0810     *typeSuggestion = "Matlab Datasource";
0811   }
0812 
0813   scalarList.append("FRAMES");
0814   return scalarList;
0815 
0816 }
0817 
0818 
0819 // Provides the string list that this dataSource can provide from the provided filename.
0820 // This function should use understands to validate the file and then open and calculate the
0821 // list of strings if necessary.
0822 QStringList MatlabSourcePlugin::stringList(QSettings *cfg,
0823                                       const QString& filename,
0824                                       const QString& type,
0825                                       QString *typeSuggestion,
0826                                       bool *complete) const {
0827 
0828   QStringList stringList;
0829 
0830   if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) {
0831     if (complete) {
0832       *complete = false;
0833     }
0834     return QStringList();
0835   }
0836 
0837   if (typeSuggestion) {
0838     *typeSuggestion = "Matlab Datasource";
0839   }
0840 
0841   stringList.append("FILENAME");
0842   return stringList;
0843 
0844 }
0845 
0846 
0847 // Provides the field list that this dataSource can provide from the provided filename.
0848 // This function should use understands to validate the file and then open and calculate the
0849 // list of fields if necessary.
0850 QStringList MatlabSourcePlugin::fieldList(QSettings *cfg,
0851                                             const QString& filename,
0852                                             const QString& type,
0853                                             QString *typeSuggestion,
0854                                             bool *complete) const {
0855   Q_UNUSED(cfg)
0856   Q_UNUSED(filename)
0857   Q_UNUSED(type)
0858 
0859   if (complete) {
0860     *complete = true;
0861   }
0862 
0863   if (typeSuggestion) {
0864     *typeSuggestion = "Matlab Datasource";
0865   }
0866 
0867   QStringList fieldList;
0868   return fieldList;
0869 }
0870 
0871 
0872 // The main function used to determine if this plugin knows how to process the provided file.
0873 // Each datasource plugin should check the file and return a number between 0 and 100 based
0874 // on the likelyhood of the file being this type.  100 should only be returned if there is no way
0875 // that the file could be any datasource other than this one.
0876 int MatlabSourcePlugin::understands(QSettings *cfg, const QString& filename) const {
0877   Q_UNUSED(cfg)
0878   QFileInfo fi(filename);
0879   if (fi.suffix() == "mat") {
0880     return 80;
0881   } else return 0;
0882 }
0883 
0884 
0885 
0886 bool MatlabSourcePlugin::supportsTime(QSettings *cfg, const QString& filename) const {
0887   //FIXME
0888   Q_UNUSED(cfg)
0889   Q_UNUSED(filename)
0890   return false;
0891 }
0892 
0893 
0894 QStringList MatlabSourcePlugin::provides() const {
0895   QStringList rc;
0896   rc += "Matlab Datasource";
0897   return rc;
0898 }
0899 
0900 
0901 // Request for this plugins configuration widget.
0902 Kst::DataSourceConfigWidget *MatlabSourcePlugin::configWidget(QSettings *cfg, const QString& filename) const {
0903   Q_UNUSED(cfg)
0904   Q_UNUSED(filename)
0905   return 0;;
0906 
0907 }
0908 
0909 
0910 #ifndef QT5
0911 Q_EXPORT_PLUGIN2(kstdata_matlab, MatlabSourcePlugin)
0912 #endif
0913 
0914 // vim: ts=2 sw=2 et