rewrote ascii conversion

This commit is contained in:
Luna 2025-08-03 20:21:02 +02:00
parent a8a44bd993
commit 3419fa359e
6 changed files with 90 additions and 26 deletions

View file

@ -6,7 +6,43 @@
#include "convert.h"
void lily_png::convert_to_ascii(image &src, image &dest)
void lily_png::convert_to_ascii(image &src, file_reader::buffer<char> &dest)
{
image intermediate_img(src.meta);
intermediate_img.meta.width = 40;
intermediate_img.meta.height = 40;
auto ret = src.resize_image(intermediate_img);
if (!ret)
{
std::println("Error! {}", ret.error());
return ;
}
size_t resized_size = ret.value();
size_t reference_size = strlen("\033[38;2;255;255;255ma\033[0m ");
dest.allocate(resized_size + (resized_size * intermediate_img.meta.width * intermediate_img.meta.height));
size_t dest_index = 0;
size_t byte_size = (intermediate_img.meta.bit_depth + 7)/8;
size_t lines = 0;
for (int y = 0; y < intermediate_img.meta.height; y++)
{
for (int x = 0; x < intermediate_img.meta.width; x++)
{
unsigned char *pxl = intermediate_img[y, x];
color_rgb tmp{};
tmp.r = pxl[0];
tmp.g = pxl[byte_size];
tmp.b = pxl[byte_size * 2];
std::string format = std::format("\033[38;2;{};{};{}ma\033[0m ", tmp.r, tmp.g, tmp.b);
memcpy(&dest.data[dest_index], format.c_str(), format.size());
dest_index += format.size();
lines++;
if (lines == intermediate_img.meta.width)
{
dest.data[dest_index] = '\n';
dest_index++;
lines = 0;
}
}
}
}

View file

@ -7,5 +7,5 @@
namespace lily_png
{
void convert_to_ascii(image &src, image &dest);
void convert_to_ascii(image &src, file_reader::buffer<char> &dest);
}

View file

@ -181,6 +181,7 @@ std::expected<bool, lily_png::png_error> lily_png::read_png(const std::string &f
{
return std::unexpected(ret.error());
}
data.add_metadata(data.meta);
if (palette_found == true)
{
file_reader::buffer<unsigned char> dest_palette{};

View file

@ -15,24 +15,4 @@ 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<bool, png_error> read_png(const std::string &file_path, image &data);
}
template <>
struct std::formatter<lily_png::png_error>
{
constexpr auto parse(std::format_parse_context& ctx) {
return ctx.begin();
}
auto format(const lily_png::png_error& id, std::format_context& ctx) const
{
if (id == lily_png::png_error::file_doesnt_exist)
return std::format_to(ctx.out(), "{}", "File doesn't exist");
if (id == lily_png::png_error::read_failed)
return std::format_to(ctx.out(), "{}", "Read failed");
if (id == lily_png::png_error::file_is_not_a_png)
return std::format_to(ctx.out(), "{}", "File is not a png");
return std::format_to(ctx.out(), "{}", "Unkown error");
}
};
}

View file

@ -12,7 +12,7 @@ std::expected<size_t, lily_png::png_error> lily_png::get_pixel_bit_size(const me
ret = meta.bit_depth;
}
else
throw std::runtime_error("Invalid bit depht");
return std::unexpected(png_error::invalid_bit_depth);
break;
case static_cast<int>(color::rgb):
if (meta.bit_depth == 8 || meta.bit_depth == 16)
@ -90,7 +90,7 @@ float lily_png::get_aspect_ratio(const metadata &meta)
std::expected<size_t, lily_png::png_error> lily_png::image::resize_image(image &dest)
{
size_t new_size = (dest.meta.width * pixel_size_bytes) * dest.meta.height;
size_t new_size = (dest.meta.width * dest.pixel_size_bytes) * dest.meta.height;
dest.buffer.allocate(new_size);
//this implementation is bad but its only a test
@ -101,7 +101,7 @@ std::expected<size_t, lily_png::png_error> lily_png::image::resize_image(image &
{
for (int x = 0; x < dest.meta.width; x++)
{
*(dest[y, x]) = *(operator[](y * compressed_pixels_height, x * compressed_pixels_width));
memcpy(dest[y, x], operator[](y * compressed_pixels_height, x * compressed_pixels_width), pixel_size_bytes);
}
}
return new_size;

View file

@ -31,9 +31,30 @@ namespace lily_png
pixel_size = pixel_size_ret.value();
pixel_size_bytes = (pixel_size + 7)/8;
}
explicit image(metadata m)
:meta(m)
{
auto pixel_size_ret = get_pixel_bit_size(m).or_else([] (png_error error)
{
return std::expected<size_t, png_error>(0);
});
pixel_size = pixel_size_ret.value();
pixel_size_bytes = (pixel_size + 7)/8;
}
file_reader::buffer<unsigned char> buffer{};
metadata meta{};
void add_metadata(metadata m)
{
auto pixel_size_ret = get_pixel_bit_size(m).or_else([] (png_error error)
{
return std::expected<size_t, png_error>(0);
});
pixel_size = pixel_size_ret.value();
pixel_size_bytes = (pixel_size + 7)/8;
this->meta = m;
}
constexpr unsigned char *operator[](std::size_t y, std::size_t x) const
{
@ -49,3 +70,29 @@ namespace lily_png
size_t pixel_size_bytes;
};
}
template <>
struct std::formatter<lily_png::png_error>
{
constexpr auto parse(std::format_parse_context& ctx) {
return ctx.begin();
}
auto format(const lily_png::png_error& id, std::format_context& ctx) const
{
if (id == lily_png::png_error::file_doesnt_exist)
return std::format_to(ctx.out(), "{}", "File doesn't exist");
if (id == lily_png::png_error::read_failed)
return std::format_to(ctx.out(), "{}", "Read failed");
if (id == lily_png::png_error::file_is_not_a_png)
return std::format_to(ctx.out(), "{}", "File is not a png");
if (id == lily_png::png_error::invalid_bit_depth)
return std::format_to(ctx.out(), "{}", "Invalid bit depth");
if (id == lily_png::png_error::invalid_color_type)
return std::format_to(ctx.out(), "{}", "Invalid color type");
if (id == lily_png::png_error::non_standard_filter)
return std::format_to(ctx.out(), "{}", "Non standard filter");
return std::format_to(ctx.out(), "{}", "Unknown error");
}
};