@@ -47,6 +47,11 @@ namespace
47
47
{
48
48
constexpr size_t validPaletteSize = 768 ;
49
49
50
+ bool isH2DImageItem ( const std::string_view name )
51
+ {
52
+ return std::filesystem::path ( name ).extension () == " .image" ;
53
+ }
54
+
50
55
bool isImageFile ( const std::string_view fileName )
51
56
{
52
57
const std::string extension = StringLower ( std::filesystem::path ( fileName ).extension ().string () );
@@ -59,7 +64,7 @@ namespace
59
64
std::string baseName = System::GetBasename ( argv[0 ] );
60
65
61
66
std::cerr << baseName << " manages the contents of the specified H2D file(s)." << std::endl
62
- << " Syntax: " << baseName << " extract dst_dir input_file.h2d ..." << std::endl
67
+ << " Syntax: " << baseName << " extract dst_dir palette_file.pal input_file.h2d ..." << std::endl
63
68
<< " " << baseName << " combine target_file.h2d palette_file.pal input_file ..." << std::endl;
64
69
}
65
70
@@ -83,12 +88,16 @@ namespace
83
88
84
89
int extractH2D ( const int argc, char ** argv )
85
90
{
86
- assert ( argc >= 4 );
91
+ assert ( argc >= 5 );
87
92
88
93
const char * dstDir = argv[2 ];
89
94
95
+ if ( !loadPalette ( argv[3 ] ) ) {
96
+ return EXIT_FAILURE;
97
+ }
98
+
90
99
std::vector<std::string> inputFileNames;
91
- for ( int i = 3 ; i < argc; ++i ) {
100
+ for ( int i = 4 ; i < argc; ++i ) {
92
101
if ( System::isShellLevelGlobbingSupported () ) {
93
102
inputFileNames.emplace_back ( argv[i] );
94
103
}
@@ -120,28 +129,53 @@ namespace
120
129
}
121
130
122
131
for ( const std::string & name : reader.getAllFileNames () ) {
123
- static_assert ( std::is_same_v<uint8_t , unsigned char >, " uint8_t is not the same as char, check the logic below" );
124
-
125
- const std::vector<uint8_t > buf = reader.getFile ( name );
126
-
127
- const std::filesystem::path outputFilePath = prefixPath / std::filesystem::path ( name );
128
-
129
- std::ofstream outputStream ( outputFilePath, std::ios_base::binary | std::ios_base::trunc );
130
- if ( !outputStream ) {
131
- std::cerr << " Cannot open file " << outputFilePath << std::endl;
132
- return EXIT_FAILURE;
133
- }
134
-
135
- const auto streamSize = fheroes2::checkedCast<std::streamsize>( buf.size () );
136
- if ( !streamSize ) {
137
- std::cerr << inputFileName << " : item " << name << " is too large" << std::endl;
138
- return EXIT_FAILURE;
132
+ // Image files need special processing
133
+ if ( isH2DImageItem ( name ) ) {
134
+ fheroes2::Sprite image;
135
+
136
+ if ( !fheroes2::readImageFromH2D ( reader, name, image ) ) {
137
+ std::cerr << inputFileName << " : item " << name << " contains an invalid image" << std::endl;
138
+ return EXIT_FAILURE;
139
+ }
140
+
141
+ std::string outputFileName = ( prefixPath / std::filesystem::path ( name ).replace_extension () ).string ();
142
+
143
+ if ( fheroes2::isPNGFormatSupported () ) {
144
+ outputFileName += " .png" ;
145
+ }
146
+ else {
147
+ outputFileName += " .bmp" ;
148
+ }
149
+
150
+ if ( !fheroes2::Save ( image, outputFileName ) ) {
151
+ std::cerr << inputFileName << " : error saving image " << name << std::endl;
152
+ return EXIT_FAILURE;
153
+ }
139
154
}
140
-
141
- outputStream.write ( reinterpret_cast <const char *>( buf.data () ), streamSize.value () );
142
- if ( !outputStream ) {
143
- std::cerr << " Error writing to file " << outputFilePath << std::endl;
144
- return EXIT_FAILURE;
155
+ else {
156
+ static_assert ( std::is_same_v<uint8_t , unsigned char >, " uint8_t is not the same as char, check the logic below" );
157
+
158
+ const std::vector<uint8_t > buf = reader.getFile ( name );
159
+
160
+ const std::filesystem::path outputFilePath = prefixPath / std::filesystem::path ( name );
161
+
162
+ std::ofstream outputStream ( outputFilePath, std::ios_base::binary | std::ios_base::trunc );
163
+ if ( !outputStream ) {
164
+ std::cerr << " Cannot open file " << outputFilePath << std::endl;
165
+ return EXIT_FAILURE;
166
+ }
167
+
168
+ const auto streamSize = fheroes2::checkedCast<std::streamsize>( buf.size () );
169
+ if ( !streamSize ) {
170
+ std::cerr << inputFileName << " : item " << name << " is too large" << std::endl;
171
+ return EXIT_FAILURE;
172
+ }
173
+
174
+ outputStream.write ( reinterpret_cast <const char *>( buf.data () ), streamSize.value () );
175
+ if ( !outputStream ) {
176
+ std::cerr << " Error writing to file " << outputFilePath << std::endl;
177
+ return EXIT_FAILURE;
178
+ }
145
179
}
146
180
147
181
++itemsExtracted;
@@ -283,7 +317,7 @@ namespace
283
317
284
318
int main ( int argc, char ** argv )
285
319
{
286
- if ( argc >= 4 && strcmp ( argv[1 ], " extract" ) == 0 ) {
320
+ if ( argc >= 5 && strcmp ( argv[1 ], " extract" ) == 0 ) {
287
321
return extractH2D ( argc, argv );
288
322
}
289
323
0 commit comments