#include "httpservice.h" // qt #include // 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(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()} { 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 logTime = std::make_shared(nullptr, [t]() { // qDebug() << "HttpServer::GET_pixels: elapsed" << t.nsecsElapsed() / 1000 << "(us)"; // }); const std::shared_ptr 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(sharedCam.get()); auto cam = dynamic_cast(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 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}; }