lily_png/src/utils.cpp

75 lines
1.8 KiB
C++
Raw Normal View History

2025-07-17 05:18:26 +02:00
#include "utils.h"
2025-07-18 07:16:46 +02:00
size_t lily_png::get_pixel_bit_size(const metadata &meta)
2025-07-17 05:18:26 +02:00
{
size_t ret = 0;
switch (meta.color_type)
{
case static_cast<int>(color::grayscale):
2025-07-17 05:18:26 +02:00
if (meta.bit_depth == 1 || meta.bit_depth == 2 || meta.bit_depth == 4 || meta.bit_depth == 8 || meta.bit_depth == 16)
{
ret = meta.bit_depth;
}
else
throw std::runtime_error("Invalid bit depht");
break;
case static_cast<int>(color::rgb):
2025-07-17 05:18:26 +02:00
if (meta.bit_depth == 8 || meta.bit_depth == 16)
{
ret = meta.bit_depth * 3;
}
else
throw std::runtime_error("Invalid bit depht");
break;
case static_cast<int>(color::indexed):
2025-07-17 05:18:26 +02:00
if (meta.bit_depth == 1 || meta.bit_depth == 2 || meta.bit_depth == 4 || meta.bit_depth == 8)
{
ret = meta.bit_depth;
}
else
throw std::runtime_error("Invalid bit depht");
break;
case static_cast<int>(color::grayscale_alpha):
2025-07-17 05:18:26 +02:00
if (meta.bit_depth == 8 || meta.bit_depth == 16)
{
ret = meta.bit_depth * 2;
}
else
throw std::runtime_error("Invalid bit depht");
break;
case static_cast<int>(color::rgba):
2025-07-17 05:18:26 +02:00
if (meta.bit_depth == 8 || meta.bit_depth == 16)
{
ret = meta.bit_depth * 4;
}
else
throw std::runtime_error("Invalid bit depht");
break;
default:
throw std::runtime_error("Invalid color type");
}
return ret;
}
2025-07-18 07:16:46 +02:00
size_t lily_png::get_uncompressed_size(const metadata meta)
2025-07-17 05:18:26 +02:00
{
size_t ret = (meta.width * get_pixel_bit_size(meta) + 7)/8; //ceil() but for bytes
ret = (ret + 1) * meta.height;
std::println("Uncompressed size {}", ret);
return ret;
}
int lily_png::paeth_predict(const int a, const int b, const int c)
2025-07-17 05:18:26 +02:00
{
const int pred = a+b-c;
const int pred1 = abs(pred - a);
const int pred2 = abs(pred - b);
const int pred3 = abs(pred - c);
2025-07-17 05:18:26 +02:00
if (pred1 <= pred2 && pred1 <= pred3)
return a;
if (pred2 <= pred3)
return b;
return c;
}