Commit f896b0fb authored by Lars Kuehne's avatar Lars Kuehne

adapted to lower versions of libpng

parent b604ddd8
#include "picture.hpp"
#include <cmath>
#include <csetjmp>
#include <cstdio>
#include <iostream>
#include <stdexcept>
#include <vector>
#include <png.h>
......@@ -9,6 +14,25 @@
// all functions for picture transformation and output:
class FileWrapper {
FILE *file_;
public:
FileWrapper(const std::string &filename, const char *open_mode)
: file_(std::fopen(filename.c_str(), open_mode)) {
if (!file_) throw std::runtime_error("error opening file " + filename);
}
~FileWrapper() {
if (file_) {
fclose(file_);
file_ = nullptr;
}
}
operator FILE *() { return file_; }
};
// function: map result to color vector
bool write_png(const char *filename, const float *result, float threshold,
int width, int height) {
......@@ -22,42 +46,44 @@ bool write_png(const char *filename, const float *result, float threshold,
colors_rgb[3 * i + 1] = 255;
colors_rgb[3 * i + 2] = 255;
} else {
colors_gray[i] = floor(254 * result[i] / threshold);
colors_gray[i] = std::floor(254 * result[i] / threshold);
// RGB color gradient: viridis from matplotlib
int idx = floor(255 * result[i] / threshold);
int idx = std::floor(255 * result[i] / threshold);
unsigned char r = floor(255 * viridis[idx][0]);
unsigned char g = floor(255 * viridis[idx][1]);
unsigned char b = floor(255 * viridis[idx][2]);
unsigned char r = std::floor(255 * viridis[idx][0]);
unsigned char g = std::floor(255 * viridis[idx][1]);
unsigned char b = std::floor(255 * viridis[idx][2]);
colors_rgb[3 * i] = r; // red
colors_rgb[3 * i + 1] = g; // green
colors_rgb[3 * i + 2] = b; // blue
}
}
png_bytep buffer = colors_rgb.data();
png_image img;
memset(&img, 0, sizeof(img));
img.version = PNG_IMAGE_VERSION;
img.opaque = NULL;
img.width = width;
img.height = height;
img.format = PNG_FORMAT_RGB;
img.flags = 0;
img.colormap_entries = 0;
// set to negative for bottom-up image
FileWrapper file(filename, "wb");
png_structp png =
png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) return false;
png_infop info = png_create_info_struct(png);
if (!info) return false;
if (std::setjmp(png_jmpbuf(png))) return false;
png_init_io(png, file);
// Output is 8bit depth, RGBA format.
png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_write_info(png, info);
std::vector<png_bytep> row_pointers(height);
const int row_stride = width * 3;
for (int i = 0; i < row_pointers.size(); ++i)
row_pointers[i] = colors_rgb.data() + i * row_stride;
png_image_write_to_file(&img, filename, false, buffer, row_stride, NULL);
if (PNG_IMAGE_FAILED(img)) {
std::cerr << img.message << std::endl;
return false;
} else {
if (img.warning_or_error != 0) {
std::cerr << img.message << std::endl;
}
png_write_image(png, row_pointers.data());
png_write_end(png, NULL);
return true;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment