Skip to content

Commit ddeb51c

Browse files
committed
ADD: imgunpkr - all in one for pack and extract resources form IPC vbf
1 parent ca34248 commit ddeb51c

File tree

3 files changed

+212
-0
lines changed

3 files changed

+212
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ add_subdirectory(EifViewer)
1414
add_subdirectory(ImgSectionParser)
1515
add_subdirectory(VbfEditor)
1616
add_subdirectory(ZipRepacker)
17+
add_subdirectory(ImgUnpacker)
1718

1819
set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}")

ImgUnpacker/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
cmake_minimum_required(VERSION 3.10)
2+
3+
project(imgunpkr)
4+
5+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
6+
7+
include_directories(../cxxopts/include)
8+
include_directories(../VbfEditor)
9+
include_directories(../ImgSectionParser)
10+
include_directories(../EifViewer)
11+
include_directories(../utils)
12+
13+
add_executable(imgunpkr main.cpp)
14+
target_include_directories(imgunpkr PUBLIC ../miniz)
15+
target_link_libraries(imgunpkr vbf imgsec eif miniz)
16+
if(WIN32)
17+
target_link_libraries(imgunpkr ws2_32)
18+
endif()
19+
20+
install(TARGETS imgunpkr)

ImgUnpacker/main.cpp

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
//
2+
// Created by user on 03.05.2020.
3+
//
4+
#include <filesystem>
5+
#include <VbfFile.h>
6+
#include <ImageSection.h>
7+
#include <miniz_zip.h>
8+
#include <utils.h>
9+
#include <EifConverter.h>
10+
#include <cxxopts.hpp>
11+
12+
namespace fs = std::filesystem;
13+
14+
struct Opts {
15+
fs::path conf_p;
16+
fs::path out_p;
17+
fs::path vbf_p;
18+
bool pack;
19+
};
20+
21+
void parse_opts(int argc, char **argv, Opts& opts) {
22+
23+
try {
24+
cxxopts::Options options("imgunpkr", "Ford IMG resources unpacker");
25+
options.add_options()
26+
("p,pack","Pack VBF file")
27+
("u,unpack","Unpack VBF file")
28+
("c,conf","Config file", cxxopts::value<string>())
29+
("o,output","Output file", cxxopts::value<string>())
30+
("v,vbf","VBF file which will be patched", cxxopts::value<string>())
31+
("h,help","Print help");
32+
33+
// options.parse_positional({"vbf"});
34+
auto result = options.parse(argc, argv);
35+
36+
if(result.arguments().empty() || result.count("help")){
37+
cout << options.help() << std::endl;
38+
exit(0);
39+
}
40+
41+
if(result.count("pack")) {
42+
opts.pack = true;
43+
44+
if(!result.count("conf")){
45+
cout << "Please, specify VBF file" << std::endl;
46+
exit(0);
47+
}
48+
49+
opts.conf_p = result["conf"].as<string>();
50+
if(!fs::exists(opts.conf_p)) {
51+
cout << "VBF file not found" << std::endl;
52+
exit(0);
53+
}
54+
55+
} else if (!result.count("unpack")) {
56+
cout << "Please, specify mode (pack|unpack)" << std::endl;
57+
exit(0);
58+
}
59+
60+
if(!result.count("vbf")){
61+
cout << "Please, specify vbf file" << std::endl;
62+
exit(0);
63+
}
64+
65+
fs::path in_file(result["vbf"].as<string>());
66+
if(!fs::exists(in_file)) {
67+
cout << "Input file not found" << std::endl;
68+
exit(0);
69+
}
70+
71+
fs::path out_path;
72+
if(result.count("output")){
73+
out_path = result["output"].as<string>();
74+
if(!fs::exists(out_path) || !fs::is_directory(out_path)) {
75+
cout << "Output dir not found" << std::endl;
76+
exit(0);
77+
}
78+
} else {
79+
out_path = in_file.parent_path();
80+
}
81+
82+
opts.vbf_p = in_file;
83+
opts.out_p = out_path;
84+
85+
} catch (const cxxopts::OptionException& e){
86+
cout << "error parsing options: " << e.what() << endl;
87+
exit(-1);
88+
}
89+
}
90+
91+
int UnpackImg(const fs::path& in_path, const fs::path& out_path) {
92+
93+
//unpack vbf
94+
VbfFile vbf;
95+
vbf.OpenFile(in_path);
96+
if(!vbf.IsOpen()) {
97+
return -1; //can't parse vbf
98+
}
99+
100+
std::vector<uint8_t> img_sec_bin;
101+
if(vbf.GetSectionRaw(1, img_sec_bin)) {
102+
return -1; //can't get image function
103+
}
104+
105+
//unpack image section
106+
ImageSection img_sec;
107+
img_sec.Parse(img_sec_bin);
108+
109+
img_sec.Export(out_path);
110+
111+
//unpack eifs
112+
int zip_items = img_sec.GetItemsCount(ImageSection::RT_ZIP);
113+
114+
fs::path eifs_path = out_path/"eif";
115+
fs::path bmps_path = out_path/"bmp";
116+
117+
fs::create_directory(eifs_path);
118+
fs::create_directory(bmps_path);
119+
120+
for(int i = 0; i < zip_items; i++) {
121+
std::vector<uint8_t> img_zip_bin;
122+
img_sec.GetItemData(ImageSection::RT_ZIP, i, img_zip_bin);
123+
124+
// unzip eif
125+
mz_zip_archive zip_archive;
126+
memset(&zip_archive, 0, sizeof(zip_archive));
127+
if (!mz_zip_reader_init_mem(&zip_archive,
128+
(const void *)img_zip_bin.data(), img_zip_bin.size(), 0))
129+
{
130+
throw runtime_error("Can't get image name form archive");
131+
}
132+
unsigned file_index =0;
133+
mz_zip_archive_file_stat file_stat;
134+
mz_zip_reader_file_stat(&zip_archive, file_index , &file_stat);
135+
vector<uint8_t> eif(file_stat.m_uncomp_size);
136+
mz_zip_reader_extract_to_mem(&zip_archive, file_index, (void *)eif.data(), eif.size(), 0);
137+
mz_zip_reader_end(&zip_archive);
138+
139+
FTUtils::bufferToFile(eifs_path/file_stat.m_filename, (char*)eif.data(), eif.size());
140+
141+
//convert eif to bmp
142+
auto p = bmps_path/file_stat.m_filename;
143+
p.replace_extension(".bmp");
144+
EIF::EifConverter::eifToBmpFile(eif, p.string());
145+
146+
}
147+
return 0;
148+
}
149+
150+
int PackImg(const fs::path& config_path, const fs::path& vbf_path, const fs::path& out_path) {
151+
152+
//open image section config
153+
//pack image section
154+
ImageSection section;
155+
section.Import(config_path);
156+
157+
vector<uint8_t> v;
158+
fs::path tmp_f = out_path/"ft.tmp";
159+
section.SaveToFile(tmp_f);
160+
FTUtils::fileToVector(tmp_f, v);
161+
fs::remove(tmp_f);
162+
163+
//open vbf
164+
VbfFile vbf;
165+
vbf.OpenFile(vbf_path);
166+
if(!vbf.IsOpen()) {
167+
throw runtime_error("Can't open vbf");
168+
}
169+
170+
//replace vbf image content
171+
vbf.ReplaceSectionRaw(1, v);
172+
173+
//pack vbf
174+
vbf.SaveToFile(out_path/"patched.vbf");
175+
176+
return 0;
177+
}
178+
179+
int main(int argc, char **argv) {
180+
181+
Opts opts = {};
182+
parse_opts(argc, argv, opts);
183+
184+
if(opts.pack) {
185+
PackImg(opts.conf_p, opts.vbf_p, opts.out_p);
186+
} else {
187+
UnpackImg(opts.vbf_p, opts.out_p);
188+
}
189+
190+
return 0;
191+
}

0 commit comments

Comments
 (0)