8#include "roo_backport.h"
9#include "roo_backport/byte.h"
13#include "roo_io/data/byte_order.h"
16template <
typename ColorMode, roo_io::ByteOrder byte_order,
17 typename Enable =
void>
20 const ColorMode& mode = ColorMode())
const;
21 Color load(
const roo::byte* src,
const ColorMode& mode = ColorMode())
const;
25template <
typename ColorMode, roo_io::ByteOrder
byte_order>
27 std::
enable_if_t<ColorTraits<ColorMode>::bytes_per_pixel == 1 &&
28 ColorTraits<ColorMode>::pixels_per_byte == 1>> {
30 const ColorMode& mode = ColorMode())
const
32 dest[0] =
static_cast<roo::byte
>(mode.fromArgbColor(src));
36 return mode.toArgbColor(
static_cast<uint8_t>(src[0]));
41template <
typename ColorMode, roo_io::ByteOrder
byte_order>
43 std::
enable_if_t<ColorTraits<ColorMode>::bytes_per_pixel == 2>> {
45 const ColorMode& mode = ColorMode())
const
48 roo_io::hto<uint16_t, byte_order>(mode.fromArgbColor(src));
52 return mode.toArgbColor(
53 roo_io::toh<uint16_t, byte_order>(*(
const uint16_t*)src));
58template <
typename ColorMode, roo_io::ByteOrder
byte_order>
60 std::
enable_if_t<ColorTraits<ColorMode>::bytes_per_pixel == 3 &&
61 ColorTraits<ColorMode>::pixels_per_byte == 1>> {
63 const ColorMode& mode = ColorMode())
const
66 if constexpr (byte_order == roo_io::kBigEndian) {
67 dest[0] =
static_cast<roo::byte
>(
raw >> 16);
68 dest[1] =
static_cast<roo::byte
>(
raw >> 8);
69 dest[2] =
static_cast<roo::byte
>(
raw >> 0);
71 dest[0] =
static_cast<roo::byte
>(
raw >> 0);
72 dest[1] =
static_cast<roo::byte
>(
raw >> 8);
73 dest[2] =
static_cast<roo::byte
>(
raw >> 16);
78 if constexpr (byte_order == roo_io::kBigEndian) {
79 return mode.toArgbColor((
static_cast<uint32_t>(src[0]) << 16) |
80 (
static_cast<uint32_t>(src[1]) << 8) |
81 (
static_cast<uint32_t>(src[2]) << 0));
83 return mode.toArgbColor((
static_cast<uint32_t>(src[0]) << 0) |
84 (
static_cast<uint32_t>(src[1]) << 8) |
85 (
static_cast<uint32_t>(src[2]) << 16));
91template <
typename ColorMode, roo_io::ByteOrder
byte_order>
93 std::
enable_if_t<ColorTraits<ColorMode>::bytes_per_pixel == 4>> {
95 const ColorMode& mode = ColorMode())
const
98 roo_io::hto<uint32_t, byte_order>(mode.fromArgbColor(src));
102 return mode.toArgbColor(
103 roo_io::toh<uint32_t, byte_order>(*(
const uint32_t*)src));
138 int8_t pixels_per_byte = ColorTraits<ColorMode>::pixels_per_byte>
142template <
typename ColorMode>
146 *
target |= (roo::byte{0x01} << index);
148 *
target &= ~(roo::byte{0x01} << index);
152 return (source & (roo::byte{0x01} << index)) != roo::byte{0};
155 return raw_color ? roo::byte{0xFF} : roo::byte{0x00};
159 result[0] = mode.toArgbColor((
in & roo::byte{0x01}) != roo::byte{0});
160 result[1] = mode.toArgbColor((
in & roo::byte{0x02}) != roo::byte{0});
161 result[2] = mode.toArgbColor((
in & roo::byte{0x04}) != roo::byte{0});
162 result[3] = mode.toArgbColor((
in & roo::byte{0x08}) != roo::byte{0});
163 result[4] = mode.toArgbColor((
in & roo::byte{0x10}) != roo::byte{0});
164 result[5] = mode.toArgbColor((
in & roo::byte{0x20}) != roo::byte{0});
165 result[6] = mode.toArgbColor((
in & roo::byte{0x40}) != roo::byte{0});
166 result[7] = mode.toArgbColor((
in & roo::byte{0x80}) != roo::byte{0});
171template <
typename ColorMode>
175 *
target |= (roo::byte{0x80} >> index);
177 *
target &= ~(roo::byte{0x80} >> index);
181 return (source & (roo::byte{0x80} >> index)) != roo::byte{0};
184 return raw_color ? roo::byte{0xFF} : roo::byte{0x00};
188 result[0] = mode.toArgbColor((
in & roo::byte{0x80}) != roo::byte{0});
189 result[1] = mode.toArgbColor((
in & roo::byte{0x40}) != roo::byte{0});
190 result[2] = mode.toArgbColor((
in & roo::byte{0x20}) != roo::byte{0});
191 result[3] = mode.toArgbColor((
in & roo::byte{0x10}) != roo::byte{0});
192 result[4] = mode.toArgbColor((
in & roo::byte{0x08}) != roo::byte{0});
193 result[5] = mode.toArgbColor((
in & roo::byte{0x04}) != roo::byte{0});
194 result[6] = mode.toArgbColor((
in & roo::byte{0x02}) != roo::byte{0});
195 result[7] = mode.toArgbColor((
in & roo::byte{0x01}) != roo::byte{0});
200template <
typename ColorMode>
203 roo::byte mask = roo::byte{0xF0} >> (index << 2);
208 return (
uint8_t)((source >> (index << 2)) & roo::byte{0x0F});
220template <
typename ColorMode>
223 roo::byte mask = (roo::byte{0x0F} << (index << 2));
228 return (
uint8_t)((source >> ((1 - index) << 2)) & roo::byte{0x0F});
241template <
typename ColorMode>
244 roo::byte mask = roo::byte{0x03} << (index << 1);
249 return (
uint8_t)((source >> (index << 1)) & roo::byte{0x03});
263template <
typename ColorMode, roo_io::ByteOrder byte_order,
265 typename Enable =
void>
269template <
typename ColorMode, roo_io::ByteOrder byte_order,
272 ColorMode, byte_order, pixel_order,
273 std::
enable_if_t<ColorTraits<ColorMode>::pixels_per_byte != 1>> {
276 const ColorMode& mode = ColorMode())
const {
279 const uint16_t height = y1 - y0 + 1;
281 if (x0 == 0 &&
static_cast<size_t>(width * ColorMode::bits_per_pixel) ==
287 io.loadBulk(mode, *
ptr++, output);
288 output += pixels_per_byte;
298 for (
int16_t y = y0; y <= y1; ++y) {
305 *output++ = mode.toArgbColor(
raw);
307 if (x > x1)
continue;
309 for (; x <
full_limit; x += pixels_per_byte) {
310 io.loadBulk(mode, *pos++, output);
311 output += pixels_per_byte;
313 if (x > x1)
continue;
316 *output++ = mode.toArgbColor(
raw);
324 const ColorMode& mode = ColorMode())
const {
335 const int16_t width = x1 - x0 + 1;
336 const int16_t height = y1 - y0 + 1;
337 if (x0 == 0 &&
static_cast<size_t>(width * ColorMode::bits_per_pixel) ==
340 for (
int16_t y = 0; y < height; ++y) {
341 const roo::byte*
ptr =
row;
347 *output = mode.toArgbColor(
raw);
357 for (
int16_t y = y0; y <= y1; ++y) {
364 if (
io.loadRaw(*pos,
pidx) !=
raw)
return false;
366 if (x > x1)
continue;
369 for (; x <
full_limit; x += pixels_per_byte) {
372 if (x > x1)
continue;
375 if (
io.loadRaw(*pos,
pidx) !=
raw)
return false;
379 *output = mode.toArgbColor(
raw);
385template <
typename ColorMode, roo_io::ByteOrder byte_order,
388 ColorMode, byte_order, pixel_order,
389 std::
enable_if_t<ColorTraits<ColorMode>::pixels_per_byte == 1>> {
392 const ColorMode& mode = ColorMode())
const {
394 const int16_t width = x1 - x0 + 1;
395 const int16_t height = y1 - y0 + 1;
400 while (count-- > 0) {
401 *output++ =
io.load(
ptr, mode);
402 ptr += bytes_per_pixel;
407 for (
int16_t y = y0; y <= y1; ++y) {
409 for (
int16_t x = x0; x <= x1; ++x) {
410 *output++ =
io.load(
pixel, mode);
411 pixel += bytes_per_pixel;
420 const ColorMode& mode = ColorMode())
const {
422 const int16_t width = x1 - x0 + 1;
426 for (
int16_t y = y0; y <= y1; ++y) {
428 for (
int16_t x = 0; x < width; ++x) {
429 if (std::memcmp(
pixel,
first, bytes_per_pixel) != 0)
return false;
430 pixel += bytes_per_pixel;
436 *output =
io.load(
first, mode);
441template <
typename ColorMode>
444 roo::byte mask = (roo::byte{0x03} << ((3 - index) << 1));
449 return (
uint8_t)((source >> ((3 - index) << 1)) & roo::byte{0x03});
ARGB8888 color stored as a 32-bit unsigned integer.
Defines 140 opaque HTML named colors.
Color load(const roo::byte *src, const ColorMode &mode=ColorMode()) const __attribute__((always_inline))
void store(Color src, roo::byte *dest, const ColorMode &mode=ColorMode()) const __attribute__((always_inline))
void store(Color src, roo::byte *dest, const ColorMode &mode=ColorMode()) const __attribute__((always_inline))
Color load(const roo::byte *src, const ColorMode &mode=ColorMode()) const __attribute__((always_inline))
Color load(const roo::byte *src, const ColorMode &mode=ColorMode()) const __attribute__((always_inline))
void store(Color src, roo::byte *dest, const ColorMode &mode=ColorMode()) const __attribute__((always_inline))
Color load(const roo::byte *src, const ColorMode &mode=ColorMode()) const __attribute__((always_inline))
void store(Color src, roo::byte *dest, const ColorMode &mode=ColorMode()) const __attribute__((always_inline))
Color load(const roo::byte *src, const ColorMode &mode=ColorMode()) const
void store(Color src, roo::byte *dest, const ColorMode &mode=ColorMode()) const
bool decodeIfUniform(const roo::byte *data, size_t row_width_bytes, int16_t x0, int16_t y0, int16_t x1, int16_t y1, Color *output, const ColorMode &mode=ColorMode()) const
void decode(const roo::byte *data, size_t row_width_bytes, int16_t x0, int16_t y0, int16_t x1, int16_t y1, Color *output, const ColorMode &mode=ColorMode()) const
void decode(const roo::byte *data, size_t row_width_bytes, int16_t x0, int16_t y0, int16_t x1, int16_t y1, Color *output, const ColorMode &mode=ColorMode()) const
bool decodeIfUniform(const roo::byte *data, size_t row_width_bytes, int16_t x0, int16_t y0, int16_t x1, int16_t y1, Color *output, const ColorMode &mode=ColorMode()) const
Traits for a color mode's storage characteristics.
roo::byte expandRaw(uint8_t raw_color)
void loadBulk(const ColorMode &mode, roo::byte in, Color *result) const
uint8_t loadRaw(const roo::byte source, int index)
void storeRaw(uint8_t raw_color, roo::byte *target, int index)
uint8_t loadRaw(const roo::byte source, int index)
void storeRaw(uint8_t raw_color, roo::byte *target, int index)
void loadBulk(const ColorMode &mode, roo::byte in, Color *result) const
roo::byte expandRaw(uint8_t raw_color)
void loadBulk(const ColorMode &mode, roo::byte in, Color *result) const
uint8_t loadRaw(const roo::byte source, int index)
roo::byte expandRaw(uint8_t raw_color)
void storeRaw(uint8_t raw_color, roo::byte *target, int index) const
uint8_t loadRaw(const roo::byte source, int index)
void storeRaw(uint8_t raw_color, roo::byte *target, int index)
roo::byte expandRaw(uint8_t raw_color)
void loadBulk(const ColorMode &mode, roo::byte in, Color *result) const
void storeRaw(uint8_t raw_color, roo::byte *target, int index)
roo::byte expandRaw(uint8_t raw_color)
void loadBulk(const ColorMode &mode, roo::byte in, Color *result) const
uint8_t loadRaw(const roo::byte source, int index)
roo::byte expandRaw(uint8_t raw_color)
void loadBulk(const ColorMode &mode, roo::byte in, Color *result) const
void storeRaw(uint8_t raw_color, roo::byte *target, int index)
uint8_t loadRaw(const roo::byte source, int index)