Commit dfef84ad authored by Erik Strand's avatar Erik Strand

Start writing C++ node board generator

parent 463bbced
cmake_minimum_required(VERSION 3.13) # 3.13 is required for target_link_options
project(NodeBoard CXX)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
include(cmake/shared_settings.cmake)
find_package(PNG REQUIRED)
add_executable(generate_node_board
main.cpp
png_writer.cpp
png_writer.h
)
target_include_directories(generate_node_board PUBLIC ${PNG_INCLUDE_DIR})
target_link_libraries(generate_node_board shared_settings ${PNG_LIBRARY})
target_compile_features(generate_node_board PUBLIC cxx_std_17)
# This file defines an interface library used to add common compile flags to all libraries and
# executables in FunkyCT.
add_library(shared_settings INTERFACE)
# Warning flags
target_compile_options(shared_settings INTERFACE
-Wall
-Wcast-align
-Wcast-qual
-Wextra
-Wundef
-Wuseless-cast
-Wzero-as-null-pointer-constant
-pedantic
)
# Speed flags
target_compile_options(shared_settings INTERFACE -march=native -ffast-math)
# Build type for profile generation
target_compile_options(shared_settings INTERFACE $<$<CONFIG:ProfileGenerate>:
-fprofile-generate
-O3
-DNDEBUG
>)
target_link_options(shared_settings INTERFACE $<$<CONFIG:ProfileGenerate>:-fprofile-generate>)
# Build type for profile use
target_compile_options(shared_settings INTERFACE $<$<CONFIG:ProfileUse>:
-fprofile-use
-O3
-DNDEBUG
>)
target_link_options(shared_settings INTERFACE $<$<CONFIG:ProfileUse>:-fprofile-use>)
#include "png_writer.h"
#include <iostream>
//--------------------------------------------------------------------------------------------------
int main() {
// All length measurements are in mm.
double width = 6;
double height = 14;
double ppmm = 50;
auto const to_px = [ppmm](double x) {
return static_cast<uint32_t>(ppmm * x);
};
uint32_t width_px = to_px(width);
uint32_t height_px = to_px(height);
PngWriter png_writer;
png_writer.allocate(width_px, height_px);
png_writer.set_all_pixels_black();
for (uint32_t y = 0; y < 10; ++y) {
for (uint32_t x = 0; x < 10; ++x) {
png_writer.set_pixel(x, y, 255);
}
}
png_writer.write("node_board_traces.png");
return 0;
}
#include "png_writer.h"
#include <stdlib.h>
#include <stdio.h>
#include <cstring>
#include <iostream>
//..................................................................................................
PngWriter::PngWriter(): width_(0), height_(0), row_pointers_(nullptr) {}
//..................................................................................................
PngWriter::~PngWriter() {
if (row_pointers_ != nullptr) {
free();
}
}
//..................................................................................................
void PngWriter::free() {
for (int32_t y = 0; y < height_; y++) {
std::free(row_pointers_[y]);
}
std::free(row_pointers_);
width_ = 0;
height_ = 0;
}
//..................................................................................................
void PngWriter::allocate(int32_t width, int32_t height) {
if (row_pointers_ != nullptr) {
free();
}
width_ = width;
height_ = height;
row_pointers_ = (png_bytep*)malloc(sizeof(png_bytep) * height_);
for (int y = 0; y < height_; y++) {
row_pointers_[y] = (png_bytep)malloc(row_size());
}
}
//..................................................................................................
void PngWriter::set_pixel(int32_t x, int32_t y, uint8_t value) {
png_bytep row = row_pointers_[y];
png_bytep px = &(row[x * 3]);
px[0] = value;
px[1] = value;
px[2] = value;
}
//..................................................................................................
void PngWriter::set_all_pixels_black() {
for (int y = 0; y < height_; y++) {
std::memset(row_pointers_[y], 0, row_size());
}
//for(int x = 0; x < width; x++) {
// png_bytep px = &(row[x * 3]);
// px[0] = 0;
// px[1] = 0;
// px[2] = 0;
//}
}
//..................................................................................................
void PngWriter::write(char const* filename) {
auto fp = fopen(filename, "wb");
if (!fp) {
std::cout << "Couldn't make file\n";
abort();
}
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (!png) {
std::cout << "Couldn't make png_structp\n";
abort();
}
png_infop info = png_create_info_struct(png);
if (!info) {
std::cout << "Couldn't make png_structp\n";
abort();
}
if (setjmp(png_jmpbuf(png))) {
std::cout << "Couldn't set jump\n";
abort();
}
png_init_io(png, fp);
// Output is 8bit depth, RGB 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);
if (png_get_rowbytes(png, info) != row_size()) {
std::cout << "Allocated bad amount of memory\n";
abort();
}
// To remove the alpha channel for PNG_COLOR_TYPE_RGB format,
// Use png_set_filler().
//png_set_filler(png_, 0, PNG_FILLER_AFTER);
png_write_image(png, row_pointers_);
png_write_end(png, NULL);
if (png && info) {
png_destroy_write_struct(&png, &info);
}
fclose(fp);
}
#include <png.h>
#include <cstdint>
//--------------------------------------------------------------------------------------------------
// This class is derived from code by Guillaume Cottenceau, copyright 2002-2010 and distributed
// under the X11 license. https://gist.github.com/niw/5963798
class PngWriter {
public:
PngWriter();
~PngWriter();
void free();
void allocate(int32_t width, int32_t height);
png_bytep* row_pointers() { return row_pointers_; }
void set_pixel(int32_t x, int32_t y, uint8_t value = 255);
void set_all_pixels_black();
void write(char const* filename);
private:
uint32_t row_size() { return 3 * width_; }
int32_t width_;
int32_t height_;
png_bytep* row_pointers_;
};
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