diff --git a/node_board/CMakeLists.txt b/node_board/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b7ba219bf484f39eafc33f74f30b63b8a774c56d --- /dev/null +++ b/node_board/CMakeLists.txt @@ -0,0 +1,19 @@ +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) diff --git a/node_board/cmake/shared_settings.cmake b/node_board/cmake/shared_settings.cmake new file mode 100644 index 0000000000000000000000000000000000000000..19340ff1d74c3dd81346bb03ef2e0fa300b32068 --- /dev/null +++ b/node_board/cmake/shared_settings.cmake @@ -0,0 +1,35 @@ +# 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>) diff --git a/node_board/main.cpp b/node_board/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7d6a7409a56897d7f493d5f5bc2d0f183b13efb5 --- /dev/null +++ b/node_board/main.cpp @@ -0,0 +1,31 @@ +#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; +} diff --git a/node_board/png_writer.cpp b/node_board/png_writer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c7da4af677a2caea77098a86d83402c144dd24eb --- /dev/null +++ b/node_board/png_writer.cpp @@ -0,0 +1,119 @@ +#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); +} diff --git a/node_board/png_writer.h b/node_board/png_writer.h new file mode 100644 index 0000000000000000000000000000000000000000..7bedff046d37d6cfa27d003612b6bb9a6356cb36 --- /dev/null +++ b/node_board/png_writer.h @@ -0,0 +1,25 @@ +#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_; +};