Skip to content

Commit aa63d2a

Browse files
h2dmgr: convert images on extraction
1 parent 22bb2bd commit aa63d2a

File tree

1 file changed

+59
-25
lines changed

1 file changed

+59
-25
lines changed

src/tools/h2dmgr.cpp

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ namespace
4747
{
4848
constexpr size_t validPaletteSize = 768;
4949

50+
bool isH2DImageItem( const std::string_view name )
51+
{
52+
return std::filesystem::path( name ).extension() == ".image";
53+
}
54+
5055
bool isImageFile( const std::string_view fileName )
5156
{
5257
const std::string extension = StringLower( std::filesystem::path( fileName ).extension().string() );
@@ -59,7 +64,7 @@ namespace
5964
std::string baseName = System::GetBasename( argv[0] );
6065

6166
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
6368
<< " " << baseName << " combine target_file.h2d palette_file.pal input_file ..." << std::endl;
6469
}
6570

@@ -83,12 +88,16 @@ namespace
8388

8489
int extractH2D( const int argc, char ** argv )
8590
{
86-
assert( argc >= 4 );
91+
assert( argc >= 5 );
8792

8893
const char * dstDir = argv[2];
8994

95+
if ( !loadPalette( argv[3] ) ) {
96+
return EXIT_FAILURE;
97+
}
98+
9099
std::vector<std::string> inputFileNames;
91-
for ( int i = 3; i < argc; ++i ) {
100+
for ( int i = 4; i < argc; ++i ) {
92101
if ( System::isShellLevelGlobbingSupported() ) {
93102
inputFileNames.emplace_back( argv[i] );
94103
}
@@ -120,28 +129,53 @@ namespace
120129
}
121130

122131
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+
}
139154
}
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+
}
145179
}
146180

147181
++itemsExtracted;
@@ -283,7 +317,7 @@ namespace
283317

284318
int main( int argc, char ** argv )
285319
{
286-
if ( argc >= 4 && strcmp( argv[1], "extract" ) == 0 ) {
320+
if ( argc >= 5 && strcmp( argv[1], "extract" ) == 0 ) {
287321
return extractH2D( argc, argv );
288322
}
289323

0 commit comments

Comments
 (0)