diff --git a/src/fart/ImageWriter.cpp b/src/fart/ImageWriter.cpp index 8848125..9ec70f3 100644 --- a/src/fart/ImageWriter.cpp +++ b/src/fart/ImageWriter.cpp @@ -1,51 +1,15 @@ #include -#include -#include +#include #include -#include -#include #include -#include -static uint8_t to_byte(double v) -{ - return (uint8_t)std::lround(std::clamp(v, 0.0, 1.0) * 255.0); -} - -static bool write_png(const Image & image, const std::string & fname) -{ - std::vector buffer(image.width * image.height * 4u); - for (size_t i = 0u; i < image.pixels.size(); i++) - { - const Color & c = image.pixels[i]; - buffer[i * 4u + 0u] = to_byte(c.r); - buffer[i * 4u + 1u] = to_byte(c.g); - buffer[i * 4u + 2u] = to_byte(c.b); - buffer[i * 4u + 3u] = to_byte(c.a); - } - - png_image png = {}; - png.version = PNG_IMAGE_VERSION; - png.width = image.width; - png.height = image.height; - png.format = PNG_FORMAT_RGBA; - - if (!png_image_write_to_file(&png, fname.c_str(), 0, buffer.data(), 0, nullptr)) - { - fprintf(stderr, "Error writing PNG file '%s': %s\n", fname.c_str(), png.message); - png_image_free(&png); - return false; - } - return true; -} - -bool ImageWriter::write(const Image & image, const std::string & fname) +ImageWriter * ImageWriter::build(const std::string & fname) { std::string ext = std::filesystem::path(fname).extension().string(); if (ext == ".png") { - return write_png(image, fname); + return new PngImageWriter(fname); } fprintf(stderr, "Unsupported output image format: '%s'\n", fname.c_str()); - return false; + return nullptr; } diff --git a/src/fart/ImageWriter.h b/src/fart/ImageWriter.h index 50387c8..ba246d1 100644 --- a/src/fart/ImageWriter.h +++ b/src/fart/ImageWriter.h @@ -6,5 +6,11 @@ class ImageWriter { public: - static bool write(const Image & image, const std::string & fname); + static ImageWriter * build(const std::string & fname); + virtual ~ImageWriter() = default; + virtual bool write(const Image & image) = 0; + +protected: + ImageWriter(const std::string & fname) : fname(fname) {} + std::string fname; }; diff --git a/src/fart/PngImageWriter.cpp b/src/fart/PngImageWriter.cpp new file mode 100644 index 0000000..b6429e3 --- /dev/null +++ b/src/fart/PngImageWriter.cpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include +#include + +static uint8_t to_byte(double v) +{ + return (uint8_t)std::lround(std::clamp(v, 0.0, 1.0) * 255.0); +} + +bool PngImageWriter::write(const Image & image) +{ + std::vector buffer(image.width * image.height * 4u); + for (size_t i = 0u; i < image.pixels.size(); i++) + { + const Color & c = image.pixels[i]; + buffer[i * 4u + 0u] = to_byte(c.r); + buffer[i * 4u + 1u] = to_byte(c.g); + buffer[i * 4u + 2u] = to_byte(c.b); + buffer[i * 4u + 3u] = to_byte(c.a); + } + + png_image png = {}; + png.version = PNG_IMAGE_VERSION; + png.width = image.width; + png.height = image.height; + png.format = PNG_FORMAT_RGBA; + + if (!png_image_write_to_file(&png, fname.c_str(), 0, buffer.data(), 0, nullptr)) + { + fprintf(stderr, "Error writing PNG file '%s': %s\n", fname.c_str(), png.message); + png_image_free(&png); + return false; + } + return true; +} diff --git a/src/fart/PngImageWriter.h b/src/fart/PngImageWriter.h new file mode 100644 index 0000000..a60364b --- /dev/null +++ b/src/fart/PngImageWriter.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +class PngImageWriter : public ImageWriter +{ +public: + PngImageWriter(const std::string & fname) : ImageWriter(fname) {} + bool write(const Image & image) override; +};