4#include <haio_codecs.hpp>
14constexpr uint8_t imageTypeOf(
Color colour) {
27constexpr uint8_t attributeBitsOf(
Color colour) {
33void appendU16LE(std::vector<uint8_t>& out, uint16_t value) {
34 out.push_back(
static_cast<uint8_t
>(value));
35 out.push_back(
static_cast<uint8_t
>(value >> 8));
39void appendRotated(std::vector<uint8_t>& out,
Bytes pixels) {
40 for (
size_t at = 0; at + 1 < pixels.size(); at += 2) {
41 const auto packed =
static_cast<uint16_t
>(pixels[at] | (pixels[at + 1] << 8));
42 appendU16LE(out,
static_cast<uint16_t
>((packed >> 1) | (packed << 15)));
64 HAIO_FAIL(
InvalidInput,
"a tga says its size in two bytes, and this picture is wider than that reaches");
67 std::vector<uint32_t> entries;
69 entries = img.entries;
70 if (entries.empty())
HAIO_FAIL(
InvalidInput,
"this picture is indices with no palette to write beside them");
71 if (entries.size() > 256)
HAIO_FAIL(
InvalidInput,
"a tga colour map here is reached by one byte, so it holds at most 256 colours");
72 if (
const auto highest = std::ranges::max(img.
data); highest >= entries.size()) {
74 +
" and the palette has " + std::to_string(entries.size()));
78 std::vector<uint8_t> out;
82 out.push_back(entries.empty() ? 0 : 1);
83 out.push_back(imageTypeOf(P));
85 appendU16LE(out,
static_cast<uint16_t
>(entries.size()));
86 out.push_back(entries.empty() ? 0 : 24);
89 appendU16LE(out,
static_cast<uint16_t
>(img.
width));
90 appendU16LE(out,
static_cast<uint16_t
>(img.
height));
91 out.push_back(
static_cast<uint8_t
>(
strideOf(P) * 8));
93 out.push_back(
static_cast<uint8_t
>(0x20 | attributeBitsOf(P)));
103 for (
const auto colour : entries) {
104 out.push_back(
static_cast<uint8_t
>(colour));
105 out.push_back(
static_cast<uint8_t
>(colour >> 8));
106 out.push_back(
static_cast<uint8_t
>(colour >> 16));
110 appendRotated(out, img.
data);
112 out.insert(out.end(), img.
data.begin(), img.
data.end());
117 for (
int i = 0; i < 8; i++) out.push_back(0);
135 return encodeTga<Color::BGRA8888>(std::move(img));
145 return encodeTga<Color::BGR888>(std::move(img));
155 return encodeTga<Color::RGBA5551>(std::move(img));
165 return encodeTga<Color::RGB555>(std::move(img));
182 return encodeTga<Color::PALETTE>(std::move(img));
197 return encodeTga<Color::GRAY8>(std::move(img));
Result< Blob > Encode< Format::TGA, Color::RGB555 >(Image< Color::RGB555 > img)
Result< Blob > Encode< Format::TGA, Color::BGR888 >(Image< Color::BGR888 > img)
Result< Blob > Encode< Format::TGA, Color::RGBA5551 >(Image< Color::RGBA5551 > img)
Result< Blob > Encode< Format::TGA, Color::GRAY8 >(Image< Color::GRAY8 > img)
Result< Blob > Encode< Format::TGA, Color::PALETTE >(Image< Color::PALETTE > img)
Result< Blob > Encode< Format::TGA, Color::BGRA8888 >(Image< Color::BGRA8888 > img)
#define HAIO_TRY(name, expr)
#define HAIO_FAIL(why, message)
constexpr size_t footerBytes
constexpr std::string_view footerSignature
constexpr size_t headerBytes
std::expected< T, Error > Result
Result< size_t > sizeOf(Color color, Size size)
constexpr size_t strideOf(Color color)
std::span< const uint8_t > Bytes
std::vector< uint8_t > data