From 7d8092aee663c0ad0aed0448ae69d7b3c541022c Mon Sep 17 00:00:00 2001 From: Michael Ochmann Date: Thu, 23 Feb 2023 10:14:21 +0100 Subject: [PATCH] added more pixel base renderers: * now supporting JPG * now supporting BMP --- main.cpp | 7 ++++++- src/QR.cpp | 6 ++++++ src/QR.hpp | 7 ++++++- src/renderers/BMPRenderer.hpp | 21 +++++++++++++++++++++ src/renderers/JPGRenderer.hpp | 21 +++++++++++++++++++++ 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 src/renderers/BMPRenderer.hpp create mode 100644 src/renderers/JPGRenderer.hpp diff --git a/main.cpp b/main.cpp index d729cf2..46e97cc 100644 --- a/main.cpp +++ b/main.cpp @@ -17,7 +17,7 @@ void printHelp() { Released under MIT license. Usage: - -f --format output file format. can be one of "cli, png, svg" + -f --format output file format. can be one of "cli, png, svg, jpg, bmp" -h --help show this help -i --input take data from this argument instead of stdin -o --output output file name without extension @@ -90,12 +90,17 @@ int main(int argc, char* argv[]) { } case 'f': { std::string value = optarg; + static_assert(massivedynamic::FormatLength == 5, "exhaustive formats: did you miss to add something here?"); if (value == "cli") format = massivedynamic::Format::CONSOLE; else if (value == "svg") format = massivedynamic::Format::SVG; else if (value == "png") format = massivedynamic::Format::PNG; + else if (value == "jpg") + format = massivedynamic::Format::JPG; + else if (value == "bmp") + format = massivedynamic::Format::BMP; else { printHelp(); return 1; diff --git a/src/QR.cpp b/src/QR.cpp index d41483d..8530e43 100644 --- a/src/QR.cpp +++ b/src/QR.cpp @@ -3,9 +3,12 @@ #include "QR.hpp" #include "qrcodegen.hpp" + #include "renderers/ConsoleRenderer.hpp" #include "renderers/PNGRenderer.hpp" #include "renderers/SVGRenderer.hpp" +#include "renderers/JPGRenderer.hpp" +#include "renderers/BMPRenderer.hpp" namespace massivedynamic { @@ -28,9 +31,12 @@ QR::QR(const std::string& data, std::string outputFile, size_t size, Type type, qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(data.c_str(), errorCorrectionLevel); + static_assert(FormatLength == 5, "exhaustive formats: did you miss to add something here?"); this->renderers.insert({Format::CONSOLE, std::make_unique(this->pixels, qr.getSize(), size)}); this->renderers.insert({Format::PNG, std::make_unique(this->pixels, qr.getSize(), size)}); this->renderers.insert({Format::SVG, std::make_unique(this->pixels, qr.getSize(), size)}); + this->renderers.insert({Format::JPG, std::make_unique(this->pixels, qr.getSize(), size)}); + this->renderers.insert({Format::BMP, std::make_unique(this->pixels, qr.getSize(), size)}); // this is inherently stupid, but "qrcodegen" does not give access to the // `segments` vector diff --git a/src/QR.hpp b/src/QR.hpp index ca8694a..ed9e0ac 100644 --- a/src/QR.hpp +++ b/src/QR.hpp @@ -20,9 +20,14 @@ namespace massivedynamic { enum class Format { CONSOLE, SVG, - PNG + PNG, + JPG, + BMP, + END }; + constexpr size_t FormatLength = static_cast(Format::END); + class QR { private: std::string outputFile; diff --git a/src/renderers/BMPRenderer.hpp b/src/renderers/BMPRenderer.hpp new file mode 100644 index 0000000..ecf3348 --- /dev/null +++ b/src/renderers/BMPRenderer.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +#include "PixelRenderer.hpp" + +namespace massivedynamic { + +class BMPRenderer : public PixelRenderer { + public: + BMPRenderer(const std::vector& pixels, size_t sourceSize, size_t targetSize) : PixelRenderer(pixels, sourceSize, targetSize) {} + + virtual void render(const std::string& filename) override { + this->generateBuffer(); + + stbi_write_bmp((filename + ".bmp").c_str(), targetSize, targetSize, 4, this->bitmap.data()); + } + +}; + +} \ No newline at end of file diff --git a/src/renderers/JPGRenderer.hpp b/src/renderers/JPGRenderer.hpp new file mode 100644 index 0000000..abfc8f4 --- /dev/null +++ b/src/renderers/JPGRenderer.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +#include "PixelRenderer.hpp" + +namespace massivedynamic { + +class JPGRenderer : public PixelRenderer { + public: + JPGRenderer(const std::vector& pixels, size_t sourceSize, size_t targetSize) : PixelRenderer(pixels, sourceSize, targetSize) {} + + virtual void render(const std::string& filename) override { + this->generateBuffer(); + + stbi_write_jpg((filename + ".jpg").c_str(), targetSize, targetSize, 4, this->bitmap.data(), sizeof(Color) * targetSize); + } + +}; + +} \ No newline at end of file