File include/jrf/image.h changed (mode: 100644) (index 23a0775..8af9e6d) |
24 |
24 |
namespace jrf { struct Image; } |
namespace jrf { struct Image; } |
25 |
25 |
struct jrf::Image |
struct jrf::Image |
26 |
26 |
{ |
{ |
|
27 |
|
enum Format : uint32_t { |
|
28 |
|
R_8, |
|
29 |
|
RG_8, |
|
30 |
|
RGB_8, |
|
31 |
|
RGBA_8, |
|
32 |
|
RGB_8_sRGB, |
|
33 |
|
RGBA_8_sRGB, |
|
34 |
|
}; |
27 |
35 |
constexpr static const uint16_t DEPTH_LIMIT = uint16_t(~0u); |
constexpr static const uint16_t DEPTH_LIMIT = uint16_t(~0u); |
28 |
36 |
struct Extent { |
struct Extent { |
29 |
37 |
[[nodiscard]] uint64_t pixel_count() { |
[[nodiscard]] uint64_t pixel_count() { |
|
... |
... |
struct jrf::Image |
40 |
48 |
uint16_t depth; |
uint16_t depth; |
41 |
49 |
uint16_t pixelSize; |
uint16_t pixelSize; |
42 |
50 |
}; |
}; |
43 |
|
static_assert (sizeof (Extent) == 8, "Important for compatibility"); |
|
44 |
|
|
|
45 |
|
enum Format { |
|
46 |
|
B8G8R8_UINT = 34, |
|
47 |
|
B8G8R8_SRGB = 36, |
|
48 |
|
R8G8B8A8_SRGB = 43, |
|
49 |
|
B8G8R8A8_UINT = 48, |
|
50 |
|
B8G8R8A8_SRGB = 50, |
|
51 |
|
}; |
|
52 |
|
static_assert (sizeof(Format) == 4, "Important for compatibility"); |
|
53 |
|
|
|
54 |
51 |
[[nodiscard]] bool init(Extent extent, Format format) { |
[[nodiscard]] bool init(Extent extent, Format format) { |
55 |
52 |
this->extent = extent; |
this->extent = extent; |
56 |
53 |
this->size = extent.size(); |
this->size = extent.size(); |
File src/convert.cpp changed (mode: 100644) (index c59a1fb..1c78579) |
... |
... |
from_tga(const jl::byte_array_ro &data, Image *p_dst) { |
72 |
72 |
extent.pixelSize /= 8; |
extent.pixelSize /= 8; |
73 |
73 |
Image::Format format; |
Image::Format format; |
74 |
74 |
switch (extent.pixelSize) { |
switch (extent.pixelSize) { |
75 |
|
case 3: format = Image::Format::B8G8R8_UINT; |
|
|
75 |
|
case 3: format = Image::Format::RGB_8; |
76 |
76 |
break; |
break; |
77 |
|
case 4: format = Image::Format::B8G8R8A8_UINT; |
|
|
77 |
|
case 4: format = Image::Format::RGBA_8; |
78 |
78 |
break; |
break; |
79 |
79 |
default: return Result::PIXEL_SIZE_UNSUPPORTED; |
default: return Result::PIXEL_SIZE_UNSUPPORTED; |
80 |
80 |
} |
} |
|
... |
... |
from_tga(const jl::byte_array_ro &data, Image *p_dst) { |
83 |
83 |
return Result::FILE_UNEXPECTED_EOF; |
return Result::FILE_UNEXPECTED_EOF; |
84 |
84 |
if (not p_dst->init(extent, format)) |
if (not p_dst->init(extent, format)) |
85 |
85 |
return Result::ALLOCATION_FAIL; |
return Result::ALLOCATION_FAIL; |
86 |
|
memcpy(p_dst->p_pixels, data.begin() + HEADER_SIZE, pixels_size); |
|
|
86 |
|
const uint8_t *p_src = data.begin() + HEADER_SIZE; |
|
87 |
|
uint8_t *p_p = p_dst->p_pixels; |
|
88 |
|
auto write_component = [&p_p, &p_src] (uint8_t src_i, uint8_t dst_i) { |
|
89 |
|
memcpy(p_p + dst_i, p_src + src_i, 1); |
|
90 |
|
}; |
|
91 |
|
uint8_t *p_end = p_p + pixels_size; |
|
92 |
|
do { // BGR -> RGB |
|
93 |
|
write_component(0, 2); // B -> B |
|
94 |
|
write_component(1, 1); // G -> G |
|
95 |
|
write_component(2, 0); // R -> R |
|
96 |
|
if (extent.pixelSize > 3) |
|
97 |
|
write_component(3, 3); // A -> A |
|
98 |
|
p_p += extent.pixelSize; |
|
99 |
|
p_src += extent.pixelSize; |
|
100 |
|
} while (p_p < p_end); |
87 |
101 |
return Result::SUCCESS; |
return Result::SUCCESS; |
88 |
102 |
} |
} |
89 |
103 |
[[nodiscard]] jrf::Result jrf::convert:: |
[[nodiscard]] jrf::Result jrf::convert:: |
90 |
104 |
add_alpha_channel(const Image &src, Image *p_dst) { |
add_alpha_channel(const Image &src, Image *p_dst) { |
91 |
105 |
Image::Format result_format; |
Image::Format result_format; |
92 |
106 |
switch(src.format) { |
switch(src.format) { |
93 |
|
case Image::Format::B8G8R8_SRGB: |
|
94 |
|
result_format = Image::Format::B8G8R8A8_SRGB; break; |
|
95 |
|
case Image::Format::B8G8R8_UINT: |
|
96 |
|
result_format = Image::Format::B8G8R8A8_UINT; break; |
|
97 |
|
default: return FORMAT_UNSUPPORTED; |
|
|
107 |
|
case Image::Format::RGB_8: |
|
108 |
|
result_format = Image::Format::RGBA_8; break; |
|
109 |
|
default: return Result::FORMAT_UNSUPPORTED; |
98 |
110 |
} |
} |
99 |
111 |
*p_dst = src; |
*p_dst = src; |
100 |
112 |
p_dst->format = result_format; |
p_dst->format = result_format; |