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 | 774 | * \author Scott Klum \cite sklum |
| 775 | 775 | * |
| 776 | 776 | */ |
| 777 | +#include <QTextStream> | |
| 778 | +#include <QChar> | |
| 777 | 779 | class ebtsFormat : public Format |
| 778 | 780 | { |
| 779 | 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 | 864 | void write(const Template &t) const | ... | ... |