Replace resource tools with python scripts

May fix pipeline failures on ghactions where makeico or toarray just exit with a non-zero status for no reason.

Also makes it easier (possible, rather) to build TPT using a cross-compiling msvc toolchain on windows; you can't have two different msvc toolchains in PATH on windows because of course you can't.

toarray had been python before, maybe I converted it to cpp to avoid pulling in python as a dependency, I'm not sure. With android vanilla development (hopefully) gaining traction soon, we'll be relying anyway on helper scripts I've written in python, so python will be a dependency sooner or later. Meson implicitly makes python a dependency, but there could be Meson implementations out there that don't rely on python, who knows.
This commit is contained in:
Tamás Bálint Misius
2024-04-26 11:50:28 +02:00
parent 4179155963
commit 7e674a887d
7 changed files with 71 additions and 197 deletions

View File

@@ -6,9 +6,6 @@ project(
'c_std=c99',
'cpp_std=c++17',
'cpp_rtti=false',
'build.c_std=c99', # used by to_array
'build.cpp_std=c++17', # used by to_array
'build.cpp_rtti=false', # used by to_array
],
meson_version: '>=0.64.0',
)
@@ -20,9 +17,9 @@ endif
fs = import('fs')
to_array = generator(
executable('toarray', sources: 'resources/ToArray.cpp', native: true),
find_program('python'),
output: [ '@PLAINNAME@.cpp', '@PLAINNAME@.h' ],
arguments: [ '@OUTPUT0@', '@OUTPUT1@', '@INPUT@', '@EXTRA_ARGS@' ]
arguments: [ join_paths(meson.current_source_dir(), 'resources/to-array.py'), '@OUTPUT0@', '@OUTPUT1@', '@INPUT@', '@EXTRA_ARGS@' ]
)
render_icons_with_inkscape = get_option('render_icons_with_inkscape')

View File

@@ -1,137 +0,0 @@
#include <cstdint>
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
static void writeU32LE(uint8_t *dest, uint32_t value)
{
dest[0] = uint8_t( value & 0xFF);
dest[1] = uint8_t((value >> 8) & 0xFF);
dest[2] = uint8_t((value >> 16) & 0xFF);
dest[3] = uint8_t((value >> 24) & 0xFF);
}
static uint32_t readU32BE(const uint8_t *src)
{
return uint32_t(src[3]) |
(uint32_t(src[2]) << 8) |
(uint32_t(src[1]) << 16) |
(uint32_t(src[0]) << 24);
}
int main(int argc, char *argv[])
{
if (argc < 3)
{
std::cerr << "usage: " << argv[0] << " OUTPUT INPUT..." << std::endl;
exit(1);
}
auto images = argc - 2;
if (images > 255)
{
std::cerr << "too many images specified" << std::endl;
exit(1);
}
std::string outputPath = argv[1];
std::ofstream output(outputPath, std::ios::binary);
auto outputFailure = [&outputPath](std::string action) {
std::cerr << "failed to " << action << " " << outputPath << ": " << strerror(errno) << std::endl;
exit(1);
};
if (!output)
{
outputFailure("open");
}
std::vector<char> header(6 + images * 16, 0);
auto writeHeader = [&header, &output, &outputFailure]() {
output.seekp(0, std::ios_base::beg);
output.write(&header[0], header.size());
if (!output)
{
outputFailure("write");
}
};
writeHeader(); // make space for header
auto *headerU8 = reinterpret_cast<uint8_t *>(&header[0]);
headerU8[2] = 1;
headerU8[4] = images;
for (auto image = 0; image < images; ++image)
{
std::string inputPath = argv[2 + image];
std::ifstream input(inputPath, std::ios::binary);
auto inputFailure = [&inputPath](std::string action) {
std::cerr << "failed to " << action << " " << inputPath << ": " << strerror(errno) << std::endl;
exit(1);
};
auto imageFailure = [&inputPath](std::string failure) {
std::cerr << "failed to process " << inputPath << ": " << failure << std::endl;
exit(1);
};
if (!input)
{
inputFailure("open");
}
std::vector<char> buf;
input.seekg(0, std::ios_base::end);
buf.resize(input.tellg());
input.seekg(0, std::ios_base::beg);
input.read(&buf[0], buf.size());
if (!input)
{
inputFailure("read");
}
auto *bufU8 = reinterpret_cast<uint8_t *>(&buf[0]);
if (buf.size() < 0x21 ||
readU32BE(&bufU8[0]) != UINT32_C(0x89504E47) ||
readU32BE(&bufU8[4]) != UINT32_C(0x0D0A1A0A) ||
bufU8[0x18] != 8 ||
bufU8[0x19] != 6)
{
imageFailure("not a 32bpp RGBA PNG");
}
auto writeOffset = output.tellp();
output.write(&buf[0], buf.size());
if (!output)
{
outputFailure("write");
}
auto width = readU32BE(&bufU8[0x10]);
auto height = readU32BE(&bufU8[0x14]);
if (width == 256)
{
width = 0;
}
if (width > 255)
{
imageFailure("width exceeds U8 limit");
}
if (height == 256)
{
height = 0;
}
if (height > 255)
{
imageFailure("height exceeds U8 limit");
}
auto *entryU8 = headerU8 + 6 + image * 16;
entryU8[0] = width;
entryU8[1] = height;
entryU8[4] = 1;
entryU8[6] = 32;
if (buf.size() > UINT32_MAX)
{
imageFailure("data size exceeds U32 limit");
}
writeU32LE(&entryU8[8], uint32_t(buf.size()));
if (writeOffset > UINT32_MAX)
{
std::cerr << "output data size exceeds U32 limit" << std::endl;
exit(1);
}
writeU32LE(&entryU8[12], uint32_t(writeOffset));
}
writeHeader(); // actually write it out
return 0;
}

View File

@@ -1,52 +0,0 @@
#include <fstream>
int main(int argc, char *argv[])
{
if (argc != 5)
{
return 1;
}
auto *outputCppPath = argv[1];
auto *outputHPath = argv[2];
auto *inputAnyPath = argv[3];
auto *symbolName = argv[4];
std::ifstream inputAny(inputAnyPath, std::ios::binary);
std::ofstream outputCpp(outputCppPath);
if (!outputCpp)
{
return 2;
}
outputCpp << "#include \"" << outputHPath << "\"\nconst unsigned char " << symbolName << "[] = { ";
auto dataLen = 0U;
while (true)
{
char ch;
inputAny.read(&ch, 1);
if (inputAny.eof())
{
break;
}
if (!inputAny)
{
return 3;
}
outputCpp << (unsigned int)(unsigned char)(ch) << ", ";
dataLen += 1;
}
outputCpp << " }; const unsigned int " << symbolName << "_size = " << dataLen << ";\n";
if (!outputCpp)
{
return 4;
}
std::ofstream outputH(outputHPath);
if (!outputH)
{
return 5;
}
outputH << "#pragma once\nextern const unsigned char " << symbolName << "[]; extern const unsigned int " << symbolName << "_size;\n";
if (!outputH)
{
return 6;
}
return 0;
}

38
resources/make-ico.py Normal file
View File

@@ -0,0 +1,38 @@
import struct
import sys
(
script,
output_ico,
*input_pngs,
) = sys.argv
input_pngs_size = len(input_pngs)
assert(input_pngs_size <= 255)
ico_header = b''
ico_data = b''
data_offset = 6 + 16 * input_pngs_size
for input_png in input_pngs:
with open(input_png, 'rb') as input_png_f:
data = input_png_f.read()
data_size = len(data)
assert(data_size >= 0x21)
magic, width, height, bit_depth, color_type = struct.unpack('>QxxxxxxxxLLBBxxxxxxx', data[0 : 0x21])
assert(magic == 0x89504E470D0A1A0A)
assert(width <= 256)
assert(height <= 256)
assert(bit_depth == 8)
assert(color_type == 6)
if width == 256:
width = 0
if height == 256:
height = 0
ico_header += struct.pack('<BBxxHHLL', width, height, 1, 32, data_size, data_offset)
data_offset += data_size
ico_data += data
with open(output_ico, 'wb') as output_ico_f:
output_ico_f.write(struct.pack('<xxHH', 1, input_pngs_size))
output_ico_f.write(ico_header)
output_ico_f.write(ico_data)

View File

@@ -42,7 +42,6 @@ if host_platform == 'windows'
icon_cps_ico_path = ''
winutf8_xml_path = ''
if windows_icons
make_ico = executable('makeico', sources: 'MakeIco.cpp', native: true)
generated_win_icos = {}
win_icos = {
'icon_exe': [ 'icon_exe', 'icon_exe_48', 'icon_exe_32', 'icon_exe_16' ],
@@ -50,7 +49,8 @@ if host_platform == 'windows'
}
foreach key, icons : win_icos
command = [
make_ico,
find_program('python'),
join_paths(meson.current_source_dir(), 'make-ico.py'),
'@OUTPUT@',
]
foreach ikey : icons

View File

@@ -3,7 +3,7 @@
#include "@RESOUCE_H@"
#include <winuser.h>
#include <winver.h>
#include <ntdef.h>
// #include <ntdef.h> // maybe not needed?
#define HAVE_ICONS @HAVE_ICONS@
#define HAVE_UTF8CP @HAVE_UTF8CP@

28
resources/to-array.py Normal file
View File

@@ -0,0 +1,28 @@
import sys
(
script,
output_cpp_path,
output_h_path,
input_path,
symbol_name,
) = sys.argv
with open(input_path, 'rb') as input_f:
data = input_f.read()
data_size = len(data)
bytes_str = ', '.join([ str(ch) for ch in data ])
with open(output_cpp_path, 'w') as output_cpp_f:
output_cpp_f.write(f'''
#include "{output_h_path}"
const unsigned char {symbol_name}[] = {{ {bytes_str} }};
const unsigned int {symbol_name}_size = {data_size};
''')
with open(output_h_path, 'w') as output_h_f:
output_h_f.write(f'''
#pragma once
extern const unsigned char {symbol_name}[];
extern const unsigned int {symbol_name}_size;
''')