GCC Code Coverage Report


Directory: ./
File: src/blp_library/converter_png.cpp
Date: 2026-04-01 15:09:43
Exec Total Coverage
Lines: 49 51 96.1%
Functions: 4 4 100.0%
Branches: 31 48 64.6%

Line Branch Exec Source
1 #include <cstddef>
2 #include <expected>
3 #include <spanstream>
4 #include <format>
5
6 #include <nvtt/nvtt.h>
7 #define STB_IMAGE_WRITE_IMPLEMENTATION
8 #include <stb/stb_image_write.h>
9
10 #include <blp/blp.hpp>
11 #include "assets_mpq_importer/blp.hpp"
12
13
14 namespace assmpq::blp {
15
16 // NOLINTNEXTLINE
17 3 static void write_to_vector(void* context, void* data, int size) {
18 3 auto* buffer = static_cast<std::vector<unsigned char>*>(context);
19 3 auto* bytes = static_cast<unsigned char*>(data);
20 3 auto bytes_size = static_cast<size_t>(size);
21
22 3 const std::span<unsigned char> data_span(bytes, bytes_size);
23
1/2
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
3 buffer->insert(buffer->end(), data_span.begin(), data_span.end());
24 3 }
25
26 2 static auto fill_rgba_pixel_buffer(const wc3lib::blp::Blp::MipMap& mipmap)-> std::vector<uint32_t>
27 {
28 2 const uint32_t width = mipmap.width();
29 2 const uint32_t height = mipmap.height();
30
31
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
6 std::vector<uint32_t> pixel_buffer(static_cast<size_t>(width) * height);
32
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
11 for (uint32_t iy = 0; iy < height; ++iy) {
33
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 9 times.
74 for (uint32_t ix = 0; ix < width; ++ix) {
34
1/2
✓ Branch 2 taken 65 times.
✗ Branch 3 not taken.
65 const auto& color = mipmap.colorAt(ix, iy);
35
1/2
✓ Branch 2 taken 65 times.
✗ Branch 3 not taken.
65 const uint32_t rgba = color.rgba();
36 65 pixel_buffer[(iy * width) + ix] = std::byteswap(rgba);
37 }
38 }
39
40 2 return pixel_buffer;
41 }
42
43 1 static auto fill_palette_pixel_buffer(
44 const wc3lib::blp::Blp::MipMap& mipmap,
45 const wc3lib::blp::Blp::ColorPtr& palette)-> std::vector<uint32_t>
46 {
47 1 const uint32_t width = mipmap.width();
48 1 const uint32_t height = mipmap.height();
49
50
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
3 std::vector<uint32_t> pixel_buffer(static_cast<size_t>(width) * height);
51
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 1 times.
33 for (uint32_t iy = 0; iy < height; ++iy) {
52
2/2
✓ Branch 0 taken 1024 times.
✓ Branch 1 taken 32 times.
1056 for (uint32_t ix = 0; ix < width; ++ix) {
53
1/2
✓ Branch 2 taken 1024 times.
✗ Branch 3 not taken.
1024 const auto& color = mipmap.colorAt(ix, iy);
54
1/2
✓ Branch 4 taken 1024 times.
✗ Branch 5 not taken.
1024 const uint32_t rgba = color.paletteColor(palette.get());
55 1024 pixel_buffer[(iy * width) + ix] = std::byteswap(rgba);
56 }
57 }
58
59 1 return pixel_buffer;
60 }
61
62 5 auto convert_blp_to_png_image(const FileData& blp_file, size_t mipmap_idx)-> std::expected<FileData, ErrorMessage>
63 try {
64
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 wc3lib::blp::Blp texture;
65
66
1/2
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
5 std::ispanstream input(blp_file);
67
2/2
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1 times.
5 texture.read(input);
68
69
2/2
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 3 times.
4 if (mipmap_idx >= texture.mipMaps().size()) {
70
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 return std::unexpected(std::format("Mipmap index {} is out of range.", mipmap_idx));
71 }
72
73
1/2
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
3 const auto& mipmap = texture.mipMaps()[mipmap_idx];
74 3 const uint32_t width = mipmap.width();
75 3 const uint32_t height = mipmap.height();
76
77 3 std::vector<uint32_t> pixel_buffer;
78
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
3 if (texture.compression() == wc3lib::blp::Blp::Compression::Paletted) {
79
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 const auto& palette = texture.palette();
80
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 pixel_buffer = fill_palette_pixel_buffer(mipmap, palette);
81 } else {
82
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 pixel_buffer = fill_rgba_pixel_buffer(mipmap);
83 }
84
85 3 std::vector<char> output_buffer;
86
87 // Use stb_image_write to write the PNG to the memory buffer via the callback
88 // The stride_bytes parameter is the pitch, which can be width * channels for tightly packed data
89
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 stbi_write_png_to_func(
90 write_to_vector,
91 &output_buffer,
92 static_cast<int>(width),
93 static_cast<int>(height),
94 kRgbaChannels,
95 3 pixel_buffer.data(),
96 3 static_cast<int>(width) * kRgbaChannels);
97
98 3 return output_buffer;
99
1/2
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
7 } catch (std::exception &e) {
100
1/2
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
1 return std::unexpected(e.what());
101 1 }
102
103
104 } // namespace assmpq::blp
105
106
107
108