From 92a5143df8ead84008b5d76197fc581913f3fd90 Mon Sep 17 00:00:00 2001 From: luna Date: Sat, 26 Jul 2025 20:27:25 +0200 Subject: [PATCH] almost finished doing error handling better --- src/convert.cpp | 6 ++++-- src/filter.cpp | 15 ++++++++++++--- src/lily_png.cpp | 34 ++++++++++++++++++++++++++-------- src/utils.cpp | 19 +++++++++++-------- src/utils.h | 9 ++++++--- 5 files changed, 59 insertions(+), 24 deletions(-) diff --git a/src/convert.cpp b/src/convert.cpp index 2aacc30..7a05cc8 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -6,8 +6,10 @@ std::expected lily_png::convert_to_R32G32B32A32(f return std::unexpected(CONVERT_ERROR::color_type_mismatch); if (!(meta.bit_depth == 8 || meta.bit_depth == 16)) return std::unexpected(CONVERT_ERROR::non_standard_bit_depth); - - size_t size = get_uncompressed_size(meta); + auto uncompress_ret = get_uncompressed_size(meta); + if (!uncompress_ret) + return std::unexpected(CONVERT_ERROR::non_standard_bit_depth); + size_t size = uncompress_ret.value(); size_t dest_size = 0; if (meta.bit_depth == 8) { diff --git a/src/filter.cpp b/src/filter.cpp index 44ac5cd..e804127 100644 --- a/src/filter.cpp +++ b/src/filter.cpp @@ -2,7 +2,10 @@ std::expected lily_png::filter_scanline(unsigned char *scanline, unsigned char *previous_scanline, unsigned char *dest, metadata &meta, unsigned char filter_type) { - size_t pixel_size = get_pixel_bit_size(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; size_t scanline_size = (meta.width * pixel_size + 7)/8; for (int i = 0; i < scanline_size; i++) @@ -47,11 +50,17 @@ std::expected lily_png::filter(file_reader::buffer read_raw_data(const std::string break; } - data.allocate(get_uncompressed_size(meta)); + auto uncompress_ret = get_uncompressed_size(meta); + if (!uncompress_ret) + return std::unexpected(uncompress_ret.error()); + data.allocate(uncompress_ret.value()); size_t prev_allocated = data.allocated; int r = uncompress(data.data, &prev_allocated, raw_dat.data, raw_dat.allocated); if (r != Z_OK) @@ -103,9 +106,12 @@ static std::expected read_raw_data(const std::string } -static void apply_palette_scanline(unsigned char *scanline, unsigned char *dest, lily_png::metadata &meta) +static std::expected apply_palette_scanline(unsigned char *scanline, unsigned char *dest, lily_png::metadata &meta) { - size_t pixel_size = get_pixel_bit_size(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; size_t scanline_size = (meta.width * pixel_size + 7)/8; unsigned long dest_index = 0; @@ -116,26 +122,36 @@ static void apply_palette_scanline(unsigned char *scanline, unsigned char *dest, dest[dest_index++] = tmp_color.g; dest[dest_index++] = tmp_color.b; } + return true; } -static void apply_palette(file_reader::buffer &data, file_reader::buffer &dest, lily_png::metadata &meta) +static std::expected apply_palette(file_reader::buffer &data, file_reader::buffer &dest, lily_png::metadata &meta) { unsigned long index = 0; unsigned long index_dest = 0; - size_t pixel_size = lily_png::get_pixel_bit_size(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; size_t scanline_size = (meta.width * pixel_size + 7)/8; unsigned long scanlines = 0; - dest.allocate(get_uncompressed_size(meta) * 3); + auto uncompress_ret = get_uncompressed_size(meta); + if (!uncompress_ret) + return std::unexpected(uncompress_ret.error()); + dest.allocate(uncompress_ret.value() * 3); while (scanlines < meta.height) { unsigned char filter = data.data[index]; std::println("Filter {}", filter); - apply_palette_scanline(&data.data[index + 1], &dest.data[index_dest], meta); + auto ret = apply_palette_scanline(&data.data[index + 1], &dest.data[index_dest], meta); + if (!ret) + return std::unexpected(ret.error()); index += scanline_size + 1; index_dest += scanline_size; scanlines++; } + return true; } std::expected lily_png::read_png(const std::string &file_path, file_reader::buffer &data) @@ -150,7 +166,9 @@ std::expected lily_png::read_png(const if (palette_found == true) { file_reader::buffer dest_palette{}; - apply_palette(tmp_data, dest_palette, meta); + auto apply_ret = apply_palette(tmp_data, dest_palette, meta); + if (!apply_ret) + return std::unexpected(apply_ret.error()); tmp_data = dest_palette; } auto res = filter(tmp_data, data, meta); diff --git a/src/utils.cpp b/src/utils.cpp index d2d39a0..fb0d327 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,7 +1,7 @@ #include "utils.h" -size_t lily_png::get_pixel_bit_size(const metadata &meta) +std::expected lily_png::get_pixel_bit_size(const metadata &meta) { size_t ret = 0; switch (meta.color_type) @@ -20,7 +20,7 @@ size_t lily_png::get_pixel_bit_size(const metadata &meta) ret = meta.bit_depth * 3; } else - throw std::runtime_error("Invalid bit depht"); + return std::unexpected(png_error::invalid_bit_depth); break; case static_cast(color::indexed): if (meta.bit_depth == 1 || meta.bit_depth == 2 || meta.bit_depth == 4 || meta.bit_depth == 8) @@ -28,7 +28,7 @@ size_t lily_png::get_pixel_bit_size(const metadata &meta) ret = meta.bit_depth; } else - throw std::runtime_error("Invalid bit depht"); + return std::unexpected(png_error::invalid_bit_depth); break; case static_cast(color::grayscale_alpha): if (meta.bit_depth == 8 || meta.bit_depth == 16) @@ -36,7 +36,7 @@ size_t lily_png::get_pixel_bit_size(const metadata &meta) ret = meta.bit_depth * 2; } else - throw std::runtime_error("Invalid bit depht"); + return std::unexpected(png_error::invalid_bit_depth); break; case static_cast(color::rgba): if (meta.bit_depth == 8 || meta.bit_depth == 16) @@ -44,17 +44,20 @@ size_t lily_png::get_pixel_bit_size(const metadata &meta) ret = meta.bit_depth * 4; } else - throw std::runtime_error("Invalid bit depht"); + return std::unexpected(png_error::invalid_bit_depth); break; default: - throw std::runtime_error("Invalid color type"); + return std::unexpected(png_error::invalid_color_type); } return ret; } -size_t lily_png::get_uncompressed_size(const metadata &meta) +std::expected lily_png::get_uncompressed_size(const metadata &meta) { - size_t ret = (meta.width * get_pixel_bit_size(meta) + 7)/8; //ceil() but for bytes + auto pixel_ret = get_pixel_bit_size(meta); + if (!pixel_ret) + return std::unexpected(pixel_ret.error()); + size_t ret = (meta.width * pixel_ret.value() + 7)/8; //ceil() but for bytes ret = (ret + 1) * meta.height; std::println("Uncompressed size {}", ret); return ret; diff --git a/src/utils.h b/src/utils.h index 3d68654..a4f5d32 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,5 +1,6 @@ #pragma once #include "metadata.h" +#include namespace lily_png { @@ -8,9 +9,11 @@ namespace lily_png file_doesnt_exist, read_failed, file_is_not_a_png, - non_standard_filter + non_standard_filter, + invalid_bit_depth, + invalid_color_type }; - size_t get_pixel_bit_size(const metadata &meta); - size_t get_uncompressed_size(const metadata &meta); + std::expected get_pixel_bit_size(const metadata &meta); + std::expected get_uncompressed_size(const metadata &meta); int paeth_predict(const int a, const int b, const int c); }