Haio
0.2.X
Homebrew Asset IO/CDN
Toggle main menu visibility
Loading...
Searching...
No Matches
etc1.cpp
Go to the documentation of this file.
1
#include <
haio_convert.hpp
>
2
3
#include <algorithm>
4
#include <cstring>
5
#include <limits>
6
#include <optional>
7
8
#include <Decode.hpp>
9
#include <ProcessRGB.hpp>
10
11
namespace
{
12
13
using
Haio::Bytes
;
14
15
int
paddedSize(
int
size) {
16
return
(size + 3) & ~3;
17
}
18
19
size_t
blockCount(
int
width,
int
height) {
20
return
static_cast<
size_t
>
(paddedSize(width) / 4) *
static_cast<
size_t
>
(paddedSize(height) / 4);
21
}
22
23
std::optional<Haio::Error> validateDimensions(
int
width,
int
height) {
24
if
(width <= 0 || height <= 0) {
25
return
Haio::Error
{
Haio::ErrorCode::InvalidInput
,
"etc1 images require positive width and height"
};
26
}
27
return
std::nullopt;
28
}
29
30
Haio::Result<std::vector<uint32_t>
> makePaddedBGRA(
Bytes
src,
Haio::Size
size,
int
paddedWidth,
int
paddedHeight) {
31
const
auto
expectedSize =
static_cast<
size_t
>
(size.
width
) *
static_cast<
size_t
>
(size.
height
) * 4;
32
if
(src.size() != expectedSize) {
33
return
std::unexpected(
Haio::Error
{
Haio::ErrorCode::InvalidInput
,
"invalid rgba8888 data size for etc1 encode"
});
34
}
35
36
std::vector<uint32_t> pixels(
static_cast<
size_t
>
(paddedWidth) *
static_cast<
size_t
>
(paddedHeight));
37
for
(
int
y = 0; y < paddedHeight; y++) {
38
const
int
srcY = std::min(y, size.
height
- 1);
39
for
(
int
x = 0; x < paddedWidth; x++) {
40
const
int
srcX = std::min(x, size.
width
- 1);
41
const
auto
srcOffset = (
static_cast<
size_t
>
(srcY) *
static_cast<
size_t
>
(size.
width
) +
static_cast<
size_t
>
(srcX)) * 4;
42
const
uint8_t bgra[4] = {
43
src[srcOffset + 2],
44
src[srcOffset + 1],
45
src[srcOffset + 0],
46
src[srcOffset + 3]
47
};
48
std::memcpy(&pixels[
static_cast<
size_t
>
(y) *
static_cast<
size_t
>
(paddedWidth) +
static_cast<
size_t
>
(x)], bgra, 4);
49
}
50
}
51
return
pixels;
52
}
53
54
}
55
56
namespace
Haio::Codecs
{
57
58
/**
59
* @addtogroup move
60
* @{
61
*/
62
/** lossy: four by four blocks, and the dimensions round up to whole blocks */
63
template
<>
64
Result<void>
Move<Color::RGBA8888, Color::ETC1>
(
Bytes
src, std::span<uint8_t> dst, Size size) {
65
const
int
paddedWidth = paddedSize(size.width);
66
const
int
paddedHeight = paddedSize(size.height);
67
const
size_t
blocks = blockCount(size.width, size.height);
68
if
(blocks > std::numeric_limits<uint32_t>::max()) {
69
HAIO_FAIL
(InvalidInput,
"etc1 image is too large"
);
70
}
71
72
HAIO_TRY
(pixels, makePaddedBGRA(src, size, paddedWidth, paddedHeight));
73
std::vector<uint64_t> compressed(blocks);
74
75
CompressEtc1RgbDither(
76
pixels.data(),
77
compressed.data(),
78
static_cast<
uint32_t
>
(blocks),
79
static_cast<
size_t
>
(paddedWidth)
80
);
81
82
std::memcpy(dst.data(), compressed.data(), std::min(dst.size(), blocks * 8));
83
return
{};
84
}
85
/** @} */
86
87
/**
88
* @addtogroup convert
89
* @{
90
*/
91
template
<>
92
Result<Image<Color::ETC1>
>
Convert<Color::RGBA8888, Color::ETC1>
(Image<Color::RGBA8888> src) {
93
return
convertVia<Color::RGBA8888, Color::ETC1>
(std::move(src));
94
}
95
/** @} */
96
97
}
Haio::Codecs::Convert< Color::RGBA8888, Color::ETC1 >
Result< Image< Color::ETC1 > > Convert< Color::RGBA8888, Color::ETC1 >(Image< Color::RGBA8888 > src)
Definition
etc1.cpp:92
Haio::Codecs::Move< Color::RGBA8888, Color::ETC1 >
Result< void > Move< Color::RGBA8888, Color::ETC1 >(Bytes src, std::span< uint8_t > dst, Size size)
Definition
etc1.cpp:64
HAIO_TRY
#define HAIO_TRY(name, expr)
Definition
haio_codec.hpp:246
HAIO_FAIL
#define HAIO_FAIL(why, message)
Definition
haio_codec.hpp:258
haio_convert.hpp
Haio::Codecs
Definition
haio_codec.hpp:136
Haio::Codecs::convertVia
Result< Image< To > > convertVia(Image< From > src)
Definition
haio_convert.hpp:21
Haio::Result
std::expected< T, Error > Result
Definition
haio_codec.hpp:32
Haio::Size::height
int height
Definition
haio_object.hpp:14
Haio::ErrorCode::InvalidInput
@ InvalidInput
Definition
haio_codec.hpp:18
Haio::Bytes
std::span< const uint8_t > Bytes
Definition
haio_codec.hpp:14
Haio::Size::width
int width
Definition
haio_object.hpp:13
Haio::Error
Definition
haio_codec.hpp:26
Haio::Size
Definition
haio_object.hpp:12
library
backend
codecs
color
rgba8888
etc1.cpp
Generated by
1.18.0