My old project for strange attractors
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 

107 lines
2.3 KiB

//
// ImageFormatPNG.hpp
// AwesomeAttractorND
//
// Created by Joshua Moerman on 11/12/11.
// Copyright 2011 Vadovas. All rights reserved.
//
#ifndef AwesomeAttractorND_ImageFormatPNG_hpp
#define AwesomeAttractorND_ImageFormatPNG_hpp
#include <stdio.h>
#include <stdexcept>
#include <png.h>
namespace ImageFormats {
namespace png{
struct pixelRGB {
pixelRGB()
: red(0)
, green(0)
, blue(0)
{}
pixelRGB(double red, double green, double blue)
: red(clamp(255*red))
, green(clamp(255*green))
, blue(clamp(255*blue))
{}
pixelRGB(int red, int green, int blue)
: red(clamp(red))
, green(clamp(green))
, blue(clamp(blue))
{}
private:
uint8_t clamp(int n){
return std::min(255, std::max(0, n));
}
uint8_t red;
uint8_t green;
uint8_t blue;
};
struct png_stream{
typedef pixelRGB pixel;
png_stream() = delete;
png_stream(png_stream const &) = delete;
png_stream & operator=(png_stream const &) = delete;
png_stream(uint32_t width, uint32_t height, std::string filename)
: fp(0)
, png_ptr(0)
, info_ptr(0)
, row(width)
, x(0)
{
fp = fopen(filename.c_str(), "wb");
if(!fp) throw std::runtime_error("Could not open file");
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if(!png_ptr) throw std::runtime_error("PNG structure could not be allocated");
info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr) throw std::runtime_error("PNG information structure could not be allocated");
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_set_compression_level(png_ptr, 9);
png_write_info(png_ptr, info_ptr);
}
~png_stream(){
png_write_end(png_ptr, info_ptr);
png_destroy_info_struct(png_ptr, &info_ptr);
fclose(fp);
}
png_stream& operator<<(pixel const & p){
row[x] = p;
++x;
if(x >= row.size()){
png_write_row(png_ptr, reinterpret_cast<unsigned char const*>(row.data()));
x = 0;
}
return *this;
}
private:
FILE* fp;
png_structp png_ptr;
png_infop info_ptr;
std::vector<pixel> row;
uint32_t x;
};
}
}
#endif