Commit 2fc1d15ed551bc2e3302456b93fae6ad45ff142e
1 parent
df6709ee
Scaffolding in place for EBTS format
Showing
1 changed file
with
75 additions
and
20 deletions
openbr/plugins/format.cpp
| @@ -774,36 +774,91 @@ BR_REGISTER(Format, scoresFormat) | @@ -774,36 +774,91 @@ BR_REGISTER(Format, scoresFormat) | ||
| 774 | * \author Scott Klum \cite sklum | 774 | * \author Scott Klum \cite sklum |
| 775 | * | 775 | * |
| 776 | */ | 776 | */ |
| 777 | +#include <QTextStream> | ||
| 778 | +#include <QChar> | ||
| 777 | class ebtsFormat : public Format | 779 | class ebtsFormat : public Format |
| 778 | { | 780 | { |
| 779 | Q_OBJECT | 781 | Q_OBJECT |
| 782 | + | ||
| 783 | + QByteArray textFieldValue(const QByteArray &byteArray, const QString &fieldNumber, int from = 0) const | ||
| 784 | + { | ||
| 785 | + // Find the field, skip the number bytes, and account for the semicolon | ||
| 786 | + int fieldPosition = byteArray.indexOf(fieldNumber, from) + fieldNumber.size() + 1; | ||
| 787 | + int sepPosition = byteArray.indexOf(QChar(0x1D),fieldPosition); | ||
| 788 | + | ||
| 789 | + return byteArray.mid(fieldPosition,sepPosition-fieldPosition); | ||
| 790 | + } | ||
| 780 | ; | 791 | ; |
| 792 | +QString fieldValue(const QByteArray &byteArray, const QString &fieldNumber, int from = 0) const | ||
| 793 | +{ | ||
| 794 | + QString fullField = fieldNumber + ".001:"; | ||
| 781 | 795 | ||
| 782 | - struct Element | 796 | + // Find the field, skip the number bytes, and account for the semicolon |
| 797 | + int fieldPosition = byteArray.indexOf(fullField, from); | ||
| 798 | + | ||
| 799 | + int sepPosition = byteArray.indexOf(QChar(0x1C),fieldPosition); | ||
| 800 | + | ||
| 801 | + return byteArray.mid(fieldPosition,sepPosition-fieldPosition); | ||
| 802 | +} | ||
| 803 | + | ||
| 804 | + Template read() const | ||
| 783 | { | 805 | { |
| 784 | - // It is always best to cast integers to a Qt integer type, such as qint16 or quint32, when reading and writing. | ||
| 785 | - // This ensures that you always know exactly what size integers you are reading and writing, no matter what the | ||
| 786 | - // underlying platform and architecture the application happens to be running on. | ||
| 787 | - // http://qt-project.org/doc/qt-4.8/datastreamformat.html | ||
| 788 | - quint32 type, bytes; | ||
| 789 | - QByteArray data; | ||
| 790 | - Element() : type(0), bytes(0) {} | ||
| 791 | - Element(QDataStream &stream) | ||
| 792 | - : type(0), bytes(0) | 806 | + QByteArray byteArray; |
| 807 | + QtUtils::readFile(file, byteArray); | ||
| 808 | + | ||
| 809 | + Template t; | ||
| 810 | + | ||
| 811 | + Mat m; | ||
| 812 | + | ||
| 813 | + qDebug() << fieldValue(byteArray, "1"); | ||
| 814 | + qDebug() << fieldValue(byteArray, "2"); | ||
| 815 | + | ||
| 816 | + | ||
| 817 | + // Demographics | ||
| 793 | { | 818 | { |
| 794 | - // Read first 4 bytes into type (32 bit integer), | ||
| 795 | - // specifying the type of data used | ||
| 796 | - if (stream.readRawData((char*)&type, 120) != 120) | ||
| 797 | - qFatal("Unexpected end of file.") | 819 | + QString name = textFieldValue(byteArray, "2.018"); |
| 820 | + QStringList names = name.split(','); | ||
| 821 | + t.file.set("FIRSTNAME", names.at(1)); | ||
| 822 | + t.file.set("LASTNAME", names.at(0)); | ||
| 823 | + t.file.set("DOB", textFieldValue(byteArray, "2.022").toInt()); | ||
| 824 | + t.file.set("GENDER", textFieldValue(byteArray, "2.024")); | ||
| 825 | + t.file.set("RACE", textFieldValue(byteArray, "2.025")); | ||
| 798 | } | 826 | } |
| 799 | - }; | ||
| 800 | 827 | ||
| 801 | - Template read() const | ||
| 802 | - { | 828 | + // Mugshot (first in file used) |
| 829 | + // Todo: Check for face designation | ||
| 830 | + { | ||
| 831 | + const QString imageRecord = "10.001:"; | ||
| 832 | + const QString imageDataRecord = "10.999:"; | ||
| 833 | + | ||
| 834 | + int fieldPosition = byteArray.indexOf(imageRecord); | ||
| 835 | + | ||
| 836 | + if (fieldPosition != -1) { | ||
| 837 | + int sepPosition = byteArray.indexOf(QChar(0x1D),fieldPosition); | ||
| 838 | + int dataPosition = byteArray.indexOf(imageDataRecord,sepPosition); | ||
| 839 | + | ||
| 840 | + int recordBytes = byteArray.mid(fieldPosition,sepPosition-fieldPosition).toInt(); | ||
| 841 | + int headerBytes = byteArray.mid(fieldPosition,dataPosition-fieldPosition).size() + imageDataRecord.size(); | ||
| 842 | + | ||
| 843 | + QByteArray data = byteArray.mid(dataPosition+imageRecord.size(),recordBytes-headerBytes); | ||
| 803 | 844 | ||
| 804 | - QByteArray byteArray; | ||
| 805 | - QtUtils::readFile(file, byteArray); | ||
| 806 | - QDataStream f(byteArray); | 845 | + m = imdecode(Mat(3, data.size(), CV_8UC3, data.data()), CV_LOAD_IMAGE_COLOR); |
| 846 | + if (!m.data) qWarning("ebtsFormat::read failed to decode image data."); | ||
| 847 | + | ||
| 848 | + t.m() = m; | ||
| 849 | + } else qWarning("ebtsFormat::cannot find image data within file."); | ||
| 850 | + | ||
| 851 | + } | ||
| 852 | + | ||
| 853 | + if (t.file.contains("DOB")) { | ||
| 854 | + const QDate dob = QDate::fromString(t.file.get<QString>("DOB"), "yyyyMMdd"); | ||
| 855 | + const QDate current = QDate::currentDate(); | ||
| 856 | + int age = current.year() - dob.year(); | ||
| 857 | + if (current.month() < dob.month()) age--; | ||
| 858 | + t.file.set("Age", age); | ||
| 859 | + } | ||
| 860 | + | ||
| 861 | + return t; | ||
| 807 | } | 862 | } |
| 808 | 863 | ||
| 809 | void write(const Template &t) const | 864 | void write(const Template &t) const |