From 7ca79b731d63baa8bf7574b520f4010a2d51ce34 Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 5 Jul 2025 05:31:16 +0200 Subject: [PATCH] initial commit --- .gitmodules | 3 +++ CMakeLists.txt | 10 +++++++++ file_reader | 1 + library.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ library.h | 17 +++++++++++++++ 5 files changed, 89 insertions(+) create mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 160000 file_reader create mode 100644 library.cpp create mode 100644 library.h diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..4d61f74 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "file_reader"] + path = file_reader + url = https://forgejo.luna4.xyz/Luna/file_reader diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b9b7a5c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.31) +project(lily_png) + +set(CMAKE_CXX_STANDARD 23) + +add_subdirectory(file_reader) + +add_library(lily_png STATIC library.cpp) + +target_link_libraries(lily_png file_read) diff --git a/file_reader b/file_reader new file mode 160000 index 0000000..1b00548 --- /dev/null +++ b/file_reader @@ -0,0 +1 @@ +Subproject commit 1b005488a2932156a5a5165820e93c04c39f6e55 diff --git a/library.cpp b/library.cpp new file mode 100644 index 0000000..6f4a909 --- /dev/null +++ b/library.cpp @@ -0,0 +1,58 @@ +#include "library.h" + +#include + +static metadata parse_metadata(buffer &data) +{ + std::tuple meta; + constexpr std::size_t size = std::tuple_size_v; + parsing_buffer par_buf(data); + par_buf.point = par_buf.buf.data; + par_buf.consumed_size = 0; + read_comp(size, par_buf, meta); + std::println("Width {} height {}", std::get<0>(meta), std::get<1>(meta)); + metadata m{0}; + m.width = std::get<0>(meta); + m.height = std::get<1>(meta); + m.bit_depth = std::get<2>(meta); + m.color_type = std::get<3>(meta); + m.compression = std::get<4>(meta); + m.filter = std::get<5>(meta); + m.interface = std::get<6>(meta); + std::println("metadata{{ width: {}, height: {}, bit_depth: {}, color_type: {}, compression: {}, filter: {}, interface: {} }}", m.width, m.height, (int)m.bit_depth, (int)m.color_type, (int)m.compression, (int)m.filter, (int)m.interface); + return m; +} + +char * read_png(const std::string &file_path) +{ + unsigned char magic[9] = {137, 80, 78, 71, 13, 10, 26, 10}; + file_reader reader(file_path); + buffer head = {0}; + head.size = 8; + auto head_tup = std::make_tuple(head); + auto re = reader.read_from_tuple(head_tup); + if (re.second == READ_INCOMPLETE || re.second == READ_FILE_ENDED) + throw std::runtime_error("Not enough size to read header"); + if (memcmp(magic, std::get<0>(head_tup).data, 8) != 0) + throw std::runtime_error("File is not a png"); + metadata meta{0}; + while (true) + { + buffer chunk_type{0}; + chunk_type.size = 4; + auto chunk_head = std::make_tuple((unsigned int)0, chunk_type); + auto ret = reader.read_from_tuple(chunk_head); + if (ret.second == READ_INCOMPLETE || ret.second == READ_FILE_ENDED) + throw std::runtime_error("Incomplete chunk"); + std::println("Header stats size {} type {}", std::get<0>(chunk_head), std::get<1>(chunk_head).data); + buffer data_body{0}; + data_body.size = std::get<0>(chunk_head); + auto data = std::make_tuple(data_body, chunk_type); + ret = reader.read_from_tuple(data); + if (ret.second == READ_INCOMPLETE || ret.second == READ_FILE_ENDED) + throw std::runtime_error("Incomplete chunk"); + if (strcmp("IHDR", std::get<1>(chunk_head).data) == 0) + meta = parse_metadata(std::get<0>(data)); + break; + } +} diff --git a/library.h b/library.h new file mode 100644 index 0000000..cdd2e8e --- /dev/null +++ b/library.h @@ -0,0 +1,17 @@ +#pragma once + +#include "file_reader/src/file_read.h" +#include + +struct metadata +{ + unsigned int width; + unsigned int height; + char bit_depth; + char color_type; + char compression; + char filter; + char interface; +}; + +char *read_png(const std::string &file_path); \ No newline at end of file