GCC Code Coverage Report


Directory: ./
File: src/importer/main.cpp
Date: 2026-04-01 15:09:43
Exec Total Coverage
Lines: 28 54 51.9%
Functions: 1 1 100.0%
Branches: 60 250 24.0%

Line Branch Exec Source
1 #include <exception>
2 #include <filesystem>
3 #include <fmt/base.h>
4 #include <fmt/format.h>
5 #include <spdlog/spdlog.h>
6 #include <CLI/CLI.hpp>
7
8 #include <internal_use_only/config.hpp>
9 #include "assets_mpq_importer/mpq.hpp"
10 #include "importer.hpp"
11
12 using assmpq::importer::import_blp;
13 using assmpq::importer::import_mdx;
14 using assmpq::importer::import_w3e;
15 using assmpq::importer::import_shd;
16 using assmpq::importer::import_wpm;
17 using assmpq::importer::import_doo;
18
19 2 auto main(int argc, char* argv[])-> int
20 try {
21 2 const auto app_description = fmt::format(
22 "{} version {} importer\n"
23 "* Extract and convert files from MPQ archive.\n"
24 "* Convert MDX meshes to Wavefront OBJ, convert BLP textures to PNG or DDS(BC1,BC3,BC7) with mipmaps.\n"
25 "* Extract and save w3e map files.\n",
26 2 assets_mpq_importer::cmake::project_name, assets_mpq_importer::cmake::project_version);
27
28
2/4
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
6 CLI::App app { app_description };
29 2 assmpq::importer::ProgramOptions popt;
30
31
3/6
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
10 app.set_version_flag("-v,--version", app_description);
32
3/6
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
16 app.add_option("-i,--input", popt.input_mpq_file, "Input MPQ archive file name.")
33 6 ->required()
34
3/6
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
6 ->check(CLI::ExistingFile);
35
3/6
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
16 app.add_option("-o,--output", popt.output_folder, "Output folder.")
36
3/6
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
10 ->check(CLI::ExistingDirectory);
37
3/6
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
10 app.add_option("-f,--filter", popt.pattern, "File extraction filter.");
38
39 static const std::map<std::string, assmpq::blp::Compression> compression_map = {
40 4 { "bc1", assmpq::blp::Compression::DDS_BC1 },
41 4 { "bc3", assmpq::blp::Compression::DDS_BC3 },
42 4 { "bc7", assmpq::blp::Compression::DDS_BC7 }
43
5/12
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 15 taken 6 times.
✓ Branch 16 taken 2 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
16 };
44
3/6
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
16 app.add_option("-c,--compression", popt.compression, "DDS compression format (BC1, BC3, BC7), BC3 by default. ")
45
4/8
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
✓ Branch 20 taken 2 times.
✗ Branch 21 not taken.
14 ->transform(CLI::CheckedTransformer(compression_map, CLI::ignore_case))
46
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
4 ->default_val("bc3");
47
48
3/6
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
10 app.add_flag("--regen-mipmap", popt.is_regen_mipmaps, "Dont use original mipmaps. Recompute it from the scratch.");
49
3/6
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
10 app.add_flag("--nvtt", popt.is_nvtt, "Use Nvidia Texture Tools compressor. AMD Compressionator by default.");
50
3/6
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
10 app.add_flag("-d,--dds", popt.is_dds, "Convert BLP textures to DDS format. Convert to PNG if not present.");
51
3/6
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
10 app.add_flag("-e,--extract", popt.is_extract, "Don't convert the files. Just extract everything.");
52
3/6
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
10 app.add_flag("-w,--w3e", popt.is_w3e_only, "Extract w3e map files only from w3m/w3x maps.");
53
3/6
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
10 app.add_flag("--verbose", popt.is_verbose, "Enable verbose output.");
54
55
3/6
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
2 CLI11_PARSE(app, argc, argv);
56
57 spdlog::info("MPQ archive: {}", popt.input_mpq_file.string());
58
59 const auto list_files = assmpq::mpq::list_mpq_files(popt.input_mpq_file, popt.pattern);
60 if (!list_files.has_value()) {
61 spdlog::error("Error extracting list file from MPQ archive: {}", list_files.error());
62 return 1;
63 }
64
65 for (const auto& file : list_files.value()) {
66 spdlog::info("File processing: {}", file.filename);
67
68 const auto extracted_file = assmpq::mpq::extract_mpq_file(popt.input_mpq_file, file.filename);
69 if (!extracted_file.has_value()) {
70 spdlog::error("File extraction error: {}", extracted_file.error());
71 continue;
72 }
73
74 auto archived_filename = file.filename;
75 std::ranges::replace(archived_filename, '\\', '/');
76
77 const std::filesystem::path archived_file_path = archived_filename;
78 if (popt.is_extract) {
79 import_save(extracted_file.value(), archived_file_path, popt);
80 continue;
81 }
82
83 static const std::unordered_map<std::string, std::vector<assmpq::importer::import_func_t>> importers_mapper = {
84 { ".blp", { import_blp }},
85 { ".BLP", { import_blp }},
86 { ".mdx", { import_mdx }},
87 { ".MDX", { import_mdx }},
88 { ".w3m", { import_w3e, import_shd, import_wpm, import_doo }},
89 { ".W3M", { import_w3e, import_shd, import_wpm, import_doo }},
90 { ".w3x", { import_w3e, import_shd, import_wpm, import_doo }},
91 { ".W3X", { import_w3e, import_shd, import_wpm, import_doo }},
92 };
93
94 if (!importers_mapper.contains(archived_file_path.extension().string())) {
95 spdlog::warn("Importer not found for extension: {}", archived_file_path.extension().string());
96 continue;
97 }
98
99 auto coverterters = importers_mapper.at(archived_file_path.extension().string());
100 for(const auto& coverter_fn : coverterters) {
101 coverter_fn(extracted_file.value(), archived_file_path, popt);
102 }
103 }
104
3/10
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
6 } catch (const std::exception &e) {
105 spdlog::error("Unhandled exception in main: {}", e.what());
106
3/30
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
8 }
107