diff options
| author | Nikita Kostovsky <nikita@kostovsky.me> | 2025-11-13 12:12:07 +0100 |
|---|---|---|
| committer | Nikita Kostovsky <nikita@kostovsky.me> | 2025-11-13 12:12:07 +0100 |
| commit | 3396ea3e7cf5a0def0ea720bcb863b374fd1cd0e (patch) | |
| tree | 55082bf91ff2dabd2957f0cf11150a7d39ababc3 /src/httpservice.cpp | |
| parent | c33006b2a8468f48cfbace39fe7c534f910fce0d (diff) | |
implement GET_pixels in http server
Diffstat (limited to 'src/httpservice.cpp')
| -rw-r--r-- | src/httpservice.cpp | 110 |
1 files changed, 108 insertions, 2 deletions
diff --git a/src/httpservice.cpp b/src/httpservice.cpp index 7b89e23..14cf60d 100644 --- a/src/httpservice.cpp +++ b/src/httpservice.cpp @@ -1,16 +1,122 @@ #include "httpservice.h" +// qt +#include <QHttpServer> + +// orpheus +#include "camera/veyeimx287m.h" #include "constants.h" +#include "image.h" +#include "imagealgos.h" #include "macro.h" +// rapidjson +#include "rapidjson/document.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/writer.h" + extern uint8_t pgm_image[64 + img_width * img_height * sizeof(uint8_t)]; extern size_t pgm_image_size; extern std::mutex pgm_image_mtx; -HttpServer::HttpServer(const std::shared_ptr<ICamera> &camera, +HttpServer::HttpServer(ICamera *camera, + // QObject *parent, const QHostAddress &address, const uint16_t port) + // : QObject{parent} : INIT_FIELD(camera) , INIT_FIELD(address) , INIT_FIELD(port) -{} + , m_server{std::make_shared<QHttpServer>()} +{ + const auto apiPrefix = QStringLiteral("/v1"); + const auto pixelsPath = apiPrefix + "/pixels"; + qDebug().noquote() << Q_FUNC_INFO << ": pixelsPath: " << pixelsPath; + m_server->route(pixelsPath, [this]() { return GET_pixels(); }); + + qDebug().noquote() << Q_FUNC_INFO << ": listen: " << m_server->listen(m_address, m_port); +} + +QHttpServerResponse HttpServer::GET_pixels() +{ + QElapsedTimer t; + t.start(); + // std::shared_ptr<std::nullptr_t> logTime = std::make_shared<std::nullptr_t>(nullptr, [t]() { + // qDebug() << "HttpServer::GET_pixels: elapsed" << t.nsecsElapsed() / 1000 << "(us)"; + // }); + const std::shared_ptr<std::nullptr_t> logTime{nullptr, [t](auto unused_ptr) { + qDebug() << "HttpServer::GET_pixels: elapsed" + << t.nsecsElapsed() / 1000 << "(us)"; + }}; + + Image img; + { + // const auto sharedCam = m_camera.lock(); + // FIME: don't cast anything, use interface + // auto cam = dynamic_cast<VeyeIMX287m *>(sharedCam.get()); + auto cam = dynamic_cast<VeyeIMX287m *>(m_camera); + + if (!cam) { + qWarning() << "NO CAM"; + return QHttpServerResponse::StatusCode::ServiceUnavailable; + } + + // yeaah + // ::img = &img; + if (!cam->getImage(img)) { + qWarning() << "cannot get image"; + return QHttpServerResponse::StatusCode::ServiceUnavailable; + } + + // ::pixels = std::move(img.pixels()); + ++cam->processedCounter; + } + + // FIXME: not thread-safe, don't use this static shared_ptr at all + const auto pixels = img.sharedPixels(); + // const auto lines = pixelsToLines(::pixels); + const auto lines = pixelsToLines(*pixels); + + // qt json does not allow to limit double precision, so using rapidjson + rapidjson::Document jd; + jd.SetObject(); + auto &al = jd.GetAllocator(); + + const auto nan2zero = [](const auto &value) { return qIsNaN(value) ? 0 : value; }; + + rapidjson::Value rjPixels{rapidjson::kArrayType}; + + for (size_t i = 0; i < img_width; ++i) { + rjPixels.PushBack(nan2zero(pixels->pixels[i]), al); + } + + rapidjson::Value rjLines{rapidjson::kArrayType}; + + for (const auto &l : lines) { + rapidjson::Value rjLineP1{rapidjson::kArrayType}; + rjLineP1.PushBack(nan2zero(l.p1().x()), al).PushBack(nan2zero(l.p1().y()), al); + rapidjson::Value rjLineP2{rapidjson::kArrayType}; + rjLineP2.PushBack(nan2zero(l.p2().x()), al).PushBack(nan2zero(l.p2().y()), al); + rapidjson::Value rjLinePoints{rapidjson::kArrayType}; + rjLinePoints.PushBack(rjLineP1, al).PushBack(rjLineP2, al); + + rjLines.PushBack(rjLinePoints, al); + } + + // jd.AddMember("encoderPosition", qint64{encoder.position()}); + // FIXME: get prom pixels struct + jd.AddMember("measurementCounter", img.counters.measurementCounter, al); + jd.AddMember("timestampUs", img.counters.timestampUs, al); + jd.AddMember("pixels", rjPixels.Move(), al); + jd.AddMember("lines", rjLines.Move(), al); + + rapidjson::StringBuffer buffer; + rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); + writer.SetMaxDecimalPlaces(2); + jd.Accept(writer); + const QString res{(const char *) buffer.GetString()}; + // qDebug() << "size:" << res.size(); + // qDebug().noquote() << "ret pix"; + + return QHttpServerResponse{res}; +} |
