diff --git a/openbr/core/core.cpp b/openbr/core/core.cpp index cb37038..50988a2 100644 --- a/openbr/core/core.cpp +++ b/openbr/core/core.cpp @@ -111,64 +111,68 @@ struct AlgorithmCore if (gallery.isNull()) gallery = getMemoryGallery(input); QScopedPointer g(Gallery::make(gallery)); - if (g.isNull()) return FileList(); - - if (gallery.contains("read") || gallery.contains("cache")) { - fileList = g->files(); - } - if (!fileList.isEmpty() && gallery.contains("cache")) - return fileList; - - const TemplateList i(TemplateList::fromGallery(input)); - if (i.isEmpty()) return fileList; // Nothing to enroll - - if (transform.isNull()) qFatal("Null transform."); - const int blocks = Globals->blocks(i.size()); - Globals->currentStep = 0; - Globals->totalSteps = i.size(); - Globals->startTime.start(); - - const bool noDuplicates = gallery.contains("noDuplicates"); - QStringList fileNames = noDuplicates ? fileList.names() : QStringList(); - const int subBlockSize = 4*std::max(1, Globals->parallelism); - const int numSubBlocks = ceil(1.0*Globals->blockSize/subBlockSize); - int totalCount = 0, failureCount = 0; - double totalBytes = 0; - for (int block=0; blockblockSize + subBlock*subBlockSize, subBlockSize); - if (data.isEmpty()) break; - if (noDuplicates) - for (int i=data.size()-1; i>=0; i--) - if (fileNames.contains(data[i].file.name)) - data.removeAt(i); - const int numFiles = data.size(); - - if (Globals->backProject) { - TemplateList backProjectedData; - transform->backProject(data, backProjectedData); - data = backProjectedData; - } else { - data >> *transform; + if (g.isNull()) qFatal("Null gallery!"); + + do { + fileList.clear(); + + if (gallery.contains("read") || gallery.contains("cache")) + fileList = g->files(); + + if (!fileList.isEmpty() && gallery.contains("cache")) + return fileList; + + const TemplateList i(TemplateList::fromGallery(input)); + if (i.isEmpty()) return fileList; // Nothing to enroll + + if (transform.isNull()) qFatal("Null transform."); + const int blocks = Globals->blocks(i.size()); + Globals->currentStep = 0; + Globals->totalSteps = i.size(); + Globals->startTime.start(); + + const bool noDuplicates = gallery.contains("noDuplicates"); + QStringList fileNames = noDuplicates ? fileList.names() : QStringList(); + const int subBlockSize = 4*std::max(1, Globals->parallelism); + const int numSubBlocks = ceil(1.0*Globals->blockSize/subBlockSize); + int totalCount = 0, failureCount = 0; + double totalBytes = 0; + for (int block=0; blockblockSize + subBlock*subBlockSize, subBlockSize); + if (data.isEmpty()) break; + if (noDuplicates) + for (int i=data.size()-1; i>=0; i--) + if (fileNames.contains(data[i].file.name)) + data.removeAt(i); + const int numFiles = data.size(); + + if (Globals->backProject) { + TemplateList backProjectedData; + transform->backProject(data, backProjectedData); + data = backProjectedData; + } else { + data >> *transform; + } + + g->writeBlock(data); + const FileList newFiles = data.files(); + fileList.append(newFiles); + + totalCount += newFiles.size(); + failureCount += newFiles.failures(); + totalBytes += data.bytes(); + Globals->currentStep += numFiles; + Globals->printStatus(); } - - g->writeBlock(data); - const FileList newFiles = data.files(); - fileList.append(newFiles); - - totalCount += newFiles.size(); - failureCount += newFiles.failures(); - totalBytes += data.bytes(); - Globals->currentStep += numFiles; - Globals->printStatus(); } - } - const float speed = 1000 * Globals->totalSteps / Globals->startTime.elapsed() / std::max(1, abs(Globals->parallelism)); - if (!Globals->quiet && (Globals->totalSteps > 1)) - fprintf(stderr, "\rSPEED=%.1e SIZE=%.4g FAILURES=%d/%d \n", - speed, totalBytes/totalCount, failureCount, totalCount); - Globals->totalSteps = 0; + const float speed = 1000 * Globals->totalSteps / Globals->startTime.elapsed() / std::max(1, abs(Globals->parallelism)); + if (!Globals->quiet && (Globals->totalSteps > 1)) + fprintf(stderr, "\rSPEED=%.1e SIZE=%.4g FAILURES=%d/%d \n", + speed, totalBytes/totalCount, failureCount, totalCount); + Globals->totalSteps = 0; + } while (input.getBool("infinite")); return fileList; } diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index aaab682..839ef51 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -131,7 +131,7 @@ void File::set(const QString &key, const QVariant &value) const QString valueString = value.toString(); /* We assume that if the value starts with '0' - then it was probably intended to to be a string UID + then it was probably intended to be a string UID and that it's numerical value is not relevant. */ if (value.canConvert(QVariant::Double) && (!valueString.startsWith('0') || (valueString == "0"))) diff --git a/openbr/plugins/format.cpp b/openbr/plugins/format.cpp index e94ec4a..348683b 100644 --- a/openbr/plugins/format.cpp +++ b/openbr/plugins/format.cpp @@ -492,6 +492,28 @@ BR_REGISTER(Format, matFormat) /*! * \ingroup formats + * \brief Returns an empty matrix. + * \author Josh Klontz \cite jklontz + */ +class nullFormat : public Format +{ + Q_OBJECT + + Template read() const + { + return Template(file, Mat()); + } + + void write(const Template &t) const + { + (void)t; + } +}; + +BR_REGISTER(Format, nullFormat) + +/*! + * \ingroup formats * \brief RAW format * * http://www.nist.gov/srd/nistsd27.cfm diff --git a/openbr/plugins/qtnetwork.cpp b/openbr/plugins/qtnetwork.cpp index b25a6c0..e29d81c 100644 --- a/openbr/plugins/qtnetwork.cpp +++ b/openbr/plugins/qtnetwork.cpp @@ -50,55 +50,119 @@ class urlFormat : public Format BR_REGISTER(Format, urlFormat) -class WebServices : public QTcpServer +/*! + * \ingroup galleries + * \brief Handle POST requests + * \author Josh Klontz \cite jklontz + */ +class postGallery : public Gallery { Q_OBJECT + class TcpServer : public QTcpServer + { + QList socketDescriptors; + QMutex socketDescriptorsLock; + + public: + QList availableSocketDescriptors() + { + QMutexLocker locker(&socketDescriptorsLock); + QList result(socketDescriptors); + socketDescriptors.clear(); + return result; + } + + void addPendingConnection(QTcpSocket *socket) + { + QTcpServer::addPendingConnection(socket); + } + + private: + void incomingConnection(qintptr socketDescriptor) + { + QMutexLocker locker(&socketDescriptorsLock); + socketDescriptors.append(socketDescriptor); + } + }; + public: - WebServices() + static QScopedPointer server; + + postGallery() { - connect(this, SIGNAL(newConnection()), this, SLOT(handleNewConnection())); + if (server.isNull()) { + server.reset(new TcpServer()); + server->listen(QHostAddress::Any, 8080); + server->moveToThread(QCoreApplication::instance()->thread()); + qDebug("Listening on %s:%d", qPrintable(server->serverAddress().toString()), server->serverPort()); + } } - void listen() +private: + TemplateList readBlock(bool *done) { - QTcpServer::listen(QHostAddress::Any, 8080); + *done = true; + TemplateList templates; + foreach (qintptr socketDescriptor, server->availableSocketDescriptors()) { + File f(".post"); + f.set("socketDescriptor", socketDescriptor); + templates.append(f); + } + if (templates.isEmpty()) + templates.append(File(".null")); + return templates; } -private slots: - void handleNewConnection() + void write(const Template &t) { - while (hasPendingConnections()) { - QTcpSocket *socket = QTcpServer::nextPendingConnection(); - connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); - connect(socket, SIGNAL(readyRead()), this, SLOT(read())); -// socket->write("HTTP/1.1 200 OK\r\n" -// "Content-Type: text/html; charset=UTF-8\r\n\r\n" -// "Hello World!\r\n"); -// socket->disconnectFromHost(); - } + (void) t; + qFatal("Not supported!"); } +}; + +QScopedPointer postGallery::server; + +BR_REGISTER(Gallery, postGallery) - void read() +/*! + * \ingroup formats + * \brief Handle POST requests + * \author Josh Klontz \cite jklontz + */ +class postFormat : public Format +{ + Q_OBJECT + + Template read() const { - QTcpSocket *socket = dynamic_cast(QObject::sender()); - if (socket == NULL) return; + Template t(file); + qDebug() << t.file.flat(); + QTcpSocket *socket = new QTcpSocket(); + socket->setSocketDescriptor(file.get("socketDescriptor")); + + socket->write("HTTP/1.1 200 OK\r\n" + "Content-Type: text/html; charset=UTF-8\r\n\r\n" + "Hello World!\r\n"); + socket->waitForBytesWritten(); + + socket->waitForReadyRead(); QByteArray data = socket->readAll(); - qDebug() << data; + t.append(imdecode(Mat(1, data.size(), CV_8UC1, data.data()), 1)); + + socket->close(); + delete socket; + return t; + } + + void write(const Template &t) const + { + (void) t; + qFatal("Not supported!"); } }; -//static void web() -//{ -// static WebServices webServices; -// if (webServices.isListening()) -// return; - -// webServices.listen(); -// qDebug("Listening on %s:%d", qPrintable(webServices.serverAddress().toString()), webServices.serverPort()); -// while (true) -// QCoreApplication::processEvents(); -//} +BR_REGISTER(Format, postFormat) } // namespace br