Impl png output of image

This commit is contained in:
Stephen Seo 2021-08-25 14:32:19 +09:00
parent 507c699ac0
commit d61aa164c0
3 changed files with 71 additions and 3 deletions

View file

@ -133,7 +133,10 @@ int main(int argc, char **argv) {
auto pixels =
Ex02::RT::renderColorsWithSpheres(outputWidth, outputHeight, threadCount);
auto outFilename = pixels.writeToFile(outputFile);
// auto outFilename = pixels.writeToFile(outputFile);
// std::cout << "Rendered image saved to " << outFilename << std::endl;
auto outFilename = pixels.writeToPNG(outputFile);
std::cout << "Rendered image saved to " << outFilename << std::endl;
return 0;

View file

@ -2,8 +2,10 @@
#include <array>
#include <cmath>
#include <csetjmp>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <thread>
#include <glm/ext/matrix_transform.hpp>
@ -46,6 +48,66 @@ std::string Ex02::RT::Image::writeToFile(const std::string &filename) const {
return outfilename;
}
std::string Ex02::RT::Image::writeToPNG(const std::string &filename) const {
std::string outfilename = filename + ".png";
FILE *outfile = fopen(outfilename.c_str(), "wb");
if (outfile == nullptr) {
return "ERROR";
}
const static auto pngErrorLFn = [](png_structp psp, png_const_charp message) {
std::cerr << "WARNING [libpng]: " << message << std::endl;
};
const static auto pngWarnLFn = [](png_structp psp, png_const_charp message) {
std::cerr << "ERROR [libpng]: " << message << std::endl;
};
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr,
pngErrorLFn, pngWarnLFn);
if (png_ptr == nullptr) {
fclose(outfile);
return "ERROR";
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == nullptr) {
png_destroy_write_struct(&png_ptr, nullptr);
fclose(outfile);
return "ERROR";
}
if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(outfile);
return "ERROR";
}
png_init_io(png_ptr, outfile);
png_set_IHDR(png_ptr, info_ptr, this->width, this->data.size() / this->width,
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
for (unsigned int j = 0; j < this->data.size() / this->width; ++j) {
unsigned char *dataPtr =
reinterpret_cast<unsigned char *>(&this->data.at(j * this->width));
png_write_rows(png_ptr, &dataPtr, 1);
}
png_write_end(png_ptr, nullptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(outfile);
return outfilename;
}
/*
glm::mat4x4 Ex02::RT::Internal::defaultMVP() {
glm::mat4x4 mvp = glm::perspective(

View file

@ -18,7 +18,7 @@ constexpr float EX02_RAY_TRACER_GRAY_SPHERE_RADIUS = 1.5F;
namespace Ex02::RT {
struct Pixel {
struct alignas(4) Pixel {
Pixel();
unsigned char r, g, b;
@ -34,9 +34,12 @@ public:
// returns actual output filename (it appends the file extension)
std::string writeToFile(const std::string &filename) const;
// returns actual output filename (it appends the file extension)
std::string writeToPNG(const std::string &filename) const;
private:
unsigned int width;
std::vector<Pixel> data;
mutable std::vector<Pixel> data;
};
namespace Internal {