Added to ascii conversion (very very experimental)

This commit is contained in:
Luna 2025-07-27 22:48:12 +02:00
parent 92a5143df8
commit 9e0f25dd82
7 changed files with 134 additions and 1 deletions

View file

@ -15,6 +15,8 @@ add_library(lily_png STATIC src/lily_png.cpp
src/filter.cpp src/filter.cpp
src/filter.h src/filter.h
src/convert.cpp src/convert.cpp
src/convert.h) src/convert.h
src/ascii.cpp
src/ascii.h)
target_link_libraries(lily_png PRIVATE file_read ZLIB::ZLIB) target_link_libraries(lily_png PRIVATE file_read ZLIB::ZLIB)

55
src/ascii.cpp Normal file
View file

@ -0,0 +1,55 @@
//
// Created by Luna on 27/7/25.
//
#include "ascii.h"
#include "convert.h"
void lily_png::convert_to_ascii(file_reader::buffer<unsigned char> &src, file_reader::buffer<char> &dest, metadata &meta)
{
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<unsigned char> 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;
}
}
}

11
src/ascii.h Normal file
View file

@ -0,0 +1,11 @@
#pragma once
#include "../file_reader/src/buffer.h"
#include "utils.h"
#include "metadata.h"
#include <format>
namespace lily_png
{
void convert_to_ascii(file_reader::buffer<unsigned char> &src, file_reader::buffer<char> &dest, metadata &meta);
}

View file

@ -154,6 +154,23 @@ static std::expected<bool, lily_png::png_error> apply_palette(file_reader::buffe
return true; return true;
} }
std::expected<bool, lily_png::png_error> lily_png::apply_to_pixel(file_reader::buffer<unsigned char> &src, metadata &meta, std::function<void(unsigned char *, int, size_t)> func)
{
auto uncompress_ret = get_uncompressed_size(meta);
if (!uncompress_ret)
return std::unexpected(png_error::invalid_bit_depth);
size_t size = uncompress_ret.value();
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();
for (int i = 0; i < size; i += pixel_size)
{
func(&src.data[i], i, pixel_size);
}
return true;
}
std::expected<lily_png::metadata, lily_png::png_error> lily_png::read_png(const std::string &file_path, file_reader::buffer<unsigned char> &data) std::expected<lily_png::metadata, lily_png::png_error> lily_png::read_png(const std::string &file_path, file_reader::buffer<unsigned char> &data)
{ {
file_reader::buffer<unsigned char> tmp_data{}; file_reader::buffer<unsigned char> tmp_data{};

View file

@ -4,13 +4,16 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <format> #include <format>
#include <functional>
#include "utils.h" #include "utils.h"
#include "filter.h" #include "filter.h"
#include "ascii.h"
#include "convert.h" #include "convert.h"
#include <zlib.h> #include <zlib.h>
namespace lily_png namespace lily_png
{ {
std::expected<bool, png_error> apply_to_pixel(file_reader::buffer<unsigned char> &src, metadata &meta, std::function<void(unsigned char *, int, size_t)> func);
std::expected<metadata, png_error> read_png(const std::string &file_path, file_reader::buffer<unsigned char> &data); std::expected<metadata, png_error> read_png(const std::string &file_path, file_reader::buffer<unsigned char> &data);
} }

View file

@ -63,6 +63,37 @@ std::expected<size_t, lily_png::png_error> lily_png::get_uncompressed_size(const
return ret; return ret;
} }
std::expected<size_t, lily_png::png_error> lily_png::resize_image(file_reader::buffer<unsigned char> &src,
file_reader::buffer<unsigned char> &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<int>(x * compressed_pixels_width);
int src_y = static_cast<int>(y * compressed_pixels_height);
// Calculate the linear index for the source and destination buffers
size_t dest_index = (static_cast<size_t>(y) * new_meta.width + x) * pixel_size_bytes;
size_t src_index = (static_cast<size_t>(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) int lily_png::paeth_predict(const int a, const int b, const int c)
{ {
const int pred = a+b-c; const int pred = a+b-c;
@ -75,3 +106,15 @@ int lily_png::paeth_predict(const int a, const int b, const int c)
return b; return b;
return c; return c;
} }
float lily_png::get_aspect_ratio(const metadata &meta)
{
float aspect_ratio = 0.0f;
if (meta.width > meta.height)
aspect_ratio = (float)meta.width / (float)meta.height;
else
aspect_ratio = (float)meta.height / (float)meta.width;
return aspect_ratio;
}

View file

@ -15,5 +15,7 @@ namespace lily_png
}; };
std::expected<size_t, png_error> get_pixel_bit_size(const metadata &meta); std::expected<size_t, png_error> get_pixel_bit_size(const metadata &meta);
std::expected<size_t, png_error> get_uncompressed_size(const metadata &meta); std::expected<size_t, png_error> get_uncompressed_size(const metadata &meta);
std::expected<size_t, png_error> resize_image(file_reader::buffer<unsigned char> &src, file_reader::buffer<unsigned char> &dest, metadata &meta, metadata &new_meta);
int paeth_predict(const int a, const int b, const int c); int paeth_predict(const int a, const int b, const int c);
float get_aspect_ratio(const metadata &meta);
} }