From a233b746c2a0725f0291e131189576cdd09cda36 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 28 Oct 2026 21:28:28 -0400 Subject: [PATCH] Add ImageWriter --- src/fart/ImageWriter.cpp | 51 ++++++++++++++++++++++++++++++++++++++++ src/fart/ImageWriter.h | 10 ++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/fart/ImageWriter.cpp create mode 100644 src/fart/ImageWriter.h diff --git a/src/fart/ImageWriter.cpp b/src/fart/ImageWriter.cpp new file mode 100644 index 0000000..8848125 --- /dev/null +++ b/src/fart/ImageWriter.cpp @@ -0,0 +1,51 @@ +#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) +{ + std::string ext = std::filesystem::path(fname).extension().string(); + if (ext == ".png") + { + return write_png(image, fname); + } + fprintf(stderr, "Unsupported output image format: '%s'\n", fname.c_str()); + return false; +} diff --git a/src/fart/ImageWriter.h b/src/fart/ImageWriter.h new file mode 100644 index 0000000..50387c8 --- /dev/null +++ b/src/fart/ImageWriter.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include + +class ImageWriter +{ +public: + static bool write(const Image & image, const std::string & fname); +};