// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #include <extensionChecker.hpp> #include "bmpInput.hpp" #include "bmpr.hpp" #include <iostream> #include <cassert> namespace VideoStitch { namespace Input { BmpReader* BmpReader::create(const std::string& fileNameTemplate, const Plugin::VSReaderPlugin::Config& runtime) { BmpReader* lReturn = 0; const ProbeResult& probeResult = MultiFileReader::probe(fileNameTemplate); if (checkProbeResult(probeResult, runtime)) { lReturn = new BmpReader(runtime.id, fileNameTemplate, probeResult, runtime.width, runtime.height); } return lReturn; } ProbeResult BmpReader::probe(const std::string& filename) { const ProbeResult& probeResult = MultiFileReader::probe(filename); if (!probeResult.valid) { return ProbeResult({false, false, -1, -1, -1, -1}); } const std::string& firstFile = probeResult.filenameIsTemplate ? filenameFromTemplate(filename, (int)probeResult.firstFrame) : filename; std::ostringstream error; BMPReader bmpReader(firstFile.c_str(), &error); if (!error.str().empty()) { Logger::get(Logger::Error) << error.str(); } if (!bmpReader.ok()) { return ProbeResult({false, false, -1, -1, -1, -1}); } return ProbeResult({true, probeResult.filenameIsTemplate, probeResult.firstFrame, probeResult.lastFrame, bmpReader.getWidth(), bmpReader.getHeight()}); } BmpReader::BmpReader(int rid, const std::string& fileNameTemplate, const ProbeResult& probeResult, int64_t width, int64_t height) : Reader(rid), MultiFileReader(fileNameTemplate, probeResult, width, height, 3 * width * height, PixelFormat::BGR), lineBuffer(new unsigned char[(size_t)(3 * width)]) {} BmpReader::~BmpReader() { delete[] lineBuffer; } bool BmpReader::handles(VideoStitch::Ptv::Value const* config) { // bool lReturn = false; std::string const* filename = hasStringContent(config); if (!filename) { return false; } return (hasExtension(*filename, ".bmp") || hasExtension(*filename, ".BMP")); } ReadStatus BmpReader::readFrameInternal(unsigned char* data) { const std::string& fn = filenameFromTemplate(curFrame); std::ostringstream error; BMPReader bmpReader(fn.c_str(), &error); // FIXME: recycle if (!error.str().empty()) { Logger::get(Logger::Error) << error.str(); } if (!bmpReader.ok()) { std::stringstream msg; msg << "Image '" << fn << "': failed to setup reader."; return ReadStatus({Origin::Input, ErrType::SetupFailure, msg.str()}); } int64_t jWidth = bmpReader.getWidth(); int64_t jHeight = bmpReader.getHeight(); if (getWidth() != jWidth || getHeight() != jHeight) { std::stringstream msg; msg << "Image '" << fn << "' does not have the right size. Expected " << getWidth() << "x" << getHeight() << ", got " << jWidth << "x" << jHeight; return ReadStatus({Origin::Input, ErrType::SetupFailure, msg.str()}); } unsigned char* curRow = data; for (int64_t row = 0; row < getHeight(); ++row) { bmpReader.getNextRow(curRow); curRow += 3 * getWidth(); } return Status::OK(); } void BmpReader::resetDisplayName() { getSpec().setDisplayName(fileNameTemplate.c_str()); } } // namespace Input } // namespace VideoStitch