made an image object and added a way to parse through them
This commit is contained in:
parent
9e0f25dd82
commit
a8a44bd993
6 changed files with 60 additions and 84 deletions
|
@ -6,50 +6,7 @@
|
|||
|
||||
#include "convert.h"
|
||||
|
||||
void lily_png::convert_to_ascii(file_reader::buffer<unsigned char> &src, file_reader::buffer<char> &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<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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
|
||||
namespace lily_png
|
||||
{
|
||||
void convert_to_ascii(file_reader::buffer<unsigned char> &src, file_reader::buffer<char> &dest, metadata &meta);
|
||||
void convert_to_ascii(image &src, image &dest);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "lily_png.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
std::vector<lily_png::color_rgb> palette;
|
||||
bool palette_found = false;
|
||||
|
||||
|
@ -171,11 +173,10 @@ std::expected<bool, lily_png::png_error> lily_png::apply_to_pixel(file_reader::b
|
|||
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<bool, lily_png::png_error> lily_png::read_png(const std::string &file_path, image &data)
|
||||
{
|
||||
file_reader::buffer<unsigned char> 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::metadata, lily_png::png_error> lily_png::read_png(const
|
|||
if (palette_found == true)
|
||||
{
|
||||
file_reader::buffer<unsigned char> 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;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
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<bool, png_error> read_png(const std::string &file_path, image &data);
|
||||
}
|
||||
|
||||
template <>
|
||||
|
|
|
@ -63,37 +63,6 @@ std::expected<size_t, lily_png::png_error> lily_png::get_uncompressed_size(const
|
|||
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)
|
||||
{
|
||||
const int pred = a+b-c;
|
||||
|
@ -118,3 +87,22 @@ float lily_png::get_aspect_ratio(const metadata &meta)
|
|||
|
||||
return aspect_ratio;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
|
32
src/utils.h
32
src/utils.h
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include "metadata.h"
|
||||
#include <expected>
|
||||
#include <cassert>
|
||||
|
||||
namespace lily_png
|
||||
{
|
||||
|
@ -13,9 +14,38 @@ namespace lily_png
|
|||
invalid_bit_depth,
|
||||
invalid_color_type
|
||||
};
|
||||
|
||||
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> 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);
|
||||
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<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{};
|
||||
|
||||
|
||||
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<size_t, png_error> resize_image(image &dest);
|
||||
|
||||
private:
|
||||
size_t pixel_size;
|
||||
size_t pixel_size_bytes;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue