summaryrefslogtreecommitdiff
path: root/src/httpservice.cpp
diff options
context:
space:
mode:
authorNikita Kostovsky <nikita@kostovsky.me>2025-11-13 12:12:07 +0100
committerNikita Kostovsky <nikita@kostovsky.me>2025-11-13 12:12:07 +0100
commit3396ea3e7cf5a0def0ea720bcb863b374fd1cd0e (patch)
tree55082bf91ff2dabd2957f0cf11150a7d39ababc3 /src/httpservice.cpp
parentc33006b2a8468f48cfbace39fe7c534f910fce0d (diff)
implement GET_pixels in http server
Diffstat (limited to 'src/httpservice.cpp')
-rw-r--r--src/httpservice.cpp110
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};
+}