From a8a44bd9936c35881593a7636e8ededa08e49397 Mon Sep 17 00:00:00 2001 From: luna Date: Sun, 3 Aug 2025 18:43:02 +0200 Subject: [PATCH] made an image object and added a way to parse through them --- src/ascii.cpp | 45 +------------------------------------------ src/ascii.h | 2 +- src/lily_png.cpp | 13 +++++++------ src/lily_png.h | 2 +- src/utils.cpp | 50 ++++++++++++++++++------------------------------ src/utils.h | 32 ++++++++++++++++++++++++++++++- 6 files changed, 60 insertions(+), 84 deletions(-) diff --git a/src/ascii.cpp b/src/ascii.cpp index c91f991..36becbc 100644 --- a/src/ascii.cpp +++ b/src/ascii.cpp @@ -6,50 +6,7 @@ #include "convert.h" -void lily_png::convert_to_ascii(file_reader::buffer &src, file_reader::buffer &dest, metadata &meta) +void lily_png::convert_to_ascii(image &src, image &dest) { - auto pixel_size_ret = get_pixel_bit_size(meta); - if (!pixel_size_ret) - return ; - size_t pixel_size = pixel_size_ret.value(); - size_t pixel_size_bytes = (pixel_size + 7)/8; - float aspect_ratio = get_aspect_ratio(meta); - metadata new_meta = meta; - new_meta.width = 40; - new_meta.height = 40; - file_reader::buffer intermediate_resize{}; - auto resize_ret = resize_image(src, intermediate_resize, meta, new_meta); - if (!resize_ret) - return ; - size_t intermediate_size = resize_ret.value(); - size_t char_size = strlen("\033[38;2;255;255;255ma\033[0m "); - size_t width_char = char_size * new_meta.width; - size_t full_size = width_char * new_meta.height + new_meta.width; - dest.allocate(full_size); - size_t dest_index = 0; - size_t line_done = 0; - - for (int i = 0; i < intermediate_size; i += pixel_size_bytes) - { - color_rgb tmp_color{}; - tmp_color.r = intermediate_resize.data[i]; - tmp_color.g = intermediate_resize.data[i + 1]; - tmp_color.b = intermediate_resize.data[i + 2]; - std::string format = std::format("\033[38;2;{};{};{}ma\033[0m ", tmp_color.r, tmp_color.g, tmp_color.b); - memcpy(&dest.data[dest_index], format.c_str(), format.size()); - dest_index += format.size(); - line_done++; - if (line_done == new_meta.width) - { - dest.data[dest_index] = '\n'; - dest_index++; - line_done = 0; - } - if (dest_index >= full_size) - { - dest.data[dest_index] = '\0'; - break; - } - } } diff --git a/src/ascii.h b/src/ascii.h index 850a513..23a089c 100644 --- a/src/ascii.h +++ b/src/ascii.h @@ -7,5 +7,5 @@ namespace lily_png { - void convert_to_ascii(file_reader::buffer &src, file_reader::buffer &dest, metadata &meta); + void convert_to_ascii(image &src, image &dest); } diff --git a/src/lily_png.cpp b/src/lily_png.cpp index 3657b8d..10e364d 100644 --- a/src/lily_png.cpp +++ b/src/lily_png.cpp @@ -1,5 +1,7 @@ #include "lily_png.h" +#include + std::vector palette; bool palette_found = false; @@ -171,11 +173,10 @@ std::expected lily_png::apply_to_pixel(file_reader::b return true; } -std::expected lily_png::read_png(const std::string &file_path, file_reader::buffer &data) +std::expected lily_png::read_png(const std::string &file_path, image &data) { file_reader::buffer tmp_data{}; - metadata meta{0}; - auto ret = read_raw_data(file_path, tmp_data, meta); + auto ret = read_raw_data(file_path, tmp_data, data.meta); if (!ret) { return std::unexpected(ret.error()); @@ -183,13 +184,13 @@ std::expected lily_png::read_png(const if (palette_found == true) { file_reader::buffer dest_palette{}; - auto apply_ret = apply_palette(tmp_data, dest_palette, meta); + auto apply_ret = apply_palette(tmp_data, dest_palette, data.meta); if (!apply_ret) return std::unexpected(apply_ret.error()); tmp_data = dest_palette; } - auto res = filter(tmp_data, data, meta); + auto res = filter(tmp_data, data.buffer, data.meta); if (!res) return std::unexpected(res.error()); - return meta; + return true; } diff --git a/src/lily_png.h b/src/lily_png.h index 73515cd..b40bc30 100644 --- a/src/lily_png.h +++ b/src/lily_png.h @@ -14,7 +14,7 @@ namespace lily_png { std::expected apply_to_pixel(file_reader::buffer &src, metadata &meta, std::function func); - std::expected read_png(const std::string &file_path, file_reader::buffer &data); + std::expected read_png(const std::string &file_path, image &data); } template <> diff --git a/src/utils.cpp b/src/utils.cpp index bbc8ed7..9ecc236 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -63,37 +63,6 @@ std::expected lily_png::get_uncompressed_size(const return ret; } -std::expected lily_png::resize_image(file_reader::buffer &src, - file_reader::buffer &dest, metadata &meta, metadata &new_meta) -{ - auto pixel_size_ret = get_pixel_bit_size(meta); - if (!pixel_size_ret) - return std::unexpected(pixel_size_ret.error()); - size_t pixel_size = pixel_size_ret.value(); - size_t pixel_size_bytes = (pixel_size + 7)/8; - int compressed_pixels_width = meta.width / new_meta.width; - int compressed_pixels_height = meta.height / new_meta.height; - auto uncompress_ret = get_uncompressed_size(new_meta); - if (!uncompress_ret) - return std::unexpected(uncompress_ret.error()); - dest.allocate(uncompress_ret.value()); - - for (int y = 0; y < new_meta.height; y++) - { - for (int x = 0; x < new_meta.width; x++) - { - int src_x = static_cast(x * compressed_pixels_width); - int src_y = static_cast(y * compressed_pixels_height); - - // Calculate the linear index for the source and destination buffers - size_t dest_index = (static_cast(y) * new_meta.width + x) * pixel_size_bytes; - size_t src_index = (static_cast(src_y) * meta.width + src_x) * pixel_size_bytes; - memcpy(&dest.data[dest_index], &src.data[src_index], pixel_size_bytes); - } - } - return uncompress_ret.value(); -} - int lily_png::paeth_predict(const int a, const int b, const int c) { const int pred = a+b-c; @@ -118,3 +87,22 @@ float lily_png::get_aspect_ratio(const metadata &meta) return aspect_ratio; } + +std::expected lily_png::image::resize_image(image &dest) +{ + size_t new_size = (dest.meta.width * pixel_size_bytes) * dest.meta.height; + dest.buffer.allocate(new_size); + + //this implementation is bad but its only a test + int compressed_pixels_width = meta.width / dest.meta.width; + int compressed_pixels_height = meta.height / dest.meta.height; + + for (int y = 0; y < dest.meta.height; y++) + { + for (int x = 0; x < dest.meta.width; x++) + { + *(dest[y, x]) = *(operator[](y * compressed_pixels_height, x * compressed_pixels_width)); + } + } + return new_size; +} diff --git a/src/utils.h b/src/utils.h index 72abe27..e03331c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,6 +1,7 @@ #pragma once #include "metadata.h" #include +#include namespace lily_png { @@ -13,9 +14,38 @@ namespace lily_png invalid_bit_depth, invalid_color_type }; + std::expected get_pixel_bit_size(const metadata &meta); std::expected get_uncompressed_size(const metadata &meta); - std::expected resize_image(file_reader::buffer &src, file_reader::buffer &dest, metadata &meta, metadata &new_meta); int paeth_predict(const int a, const int b, const int c); float get_aspect_ratio(const metadata &meta); + + struct image + { + image() + { + auto pixel_size_ret = get_pixel_bit_size(meta).or_else([] (png_error error) + { + return std::expected(0); + }); + pixel_size = pixel_size_ret.value(); + pixel_size_bytes = (pixel_size + 7)/8; + } + file_reader::buffer buffer{}; + metadata meta{}; + + + constexpr unsigned char *operator[](std::size_t y, std::size_t x) const + { + if (x > meta.width || y > meta.height) + return nullptr; + const size_t calculate = (y * meta.width + x) * pixel_size_bytes; + return &buffer.data[calculate]; + } + std::expected resize_image(image &dest); + + private: + size_t pixel_size; + size_t pixel_size_bytes; + }; }