mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Fix the hack for File::c_str to work (#1242)
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
#include <ios>
|
#include <ios>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <streambuf>
|
#include <streambuf>
|
||||||
|
#include <string>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
@@ -85,17 +86,11 @@ public:
|
|||||||
: nullptr;
|
: nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char const *c_str(std::filesystem::path const &path) const {
|
std::string string(std::filesystem::path const &path) const {
|
||||||
// FIXME: This is a hack to prevent the path string from being destroyed until
|
return std::visit(Visitor{[&path](std::filebuf const &) { return path.string(); },
|
||||||
// `.c_str(path)` is called again. It's necessary because just `return path.c_str()`
|
|
||||||
// fails on Windows, where paths use `wchar_t`.
|
|
||||||
static std::string path_string;
|
|
||||||
return std::visit(Visitor{[&path](std::filebuf const &) {
|
|
||||||
path_string = path.string();
|
|
||||||
return path_string.c_str();
|
|
||||||
},
|
|
||||||
[](std::streambuf const *buf) {
|
[](std::streambuf const *buf) {
|
||||||
return buf == std::cin.rdbuf() ? "<stdin>" : "<stdout>";
|
return std::string{buf == std::cin.rdbuf()
|
||||||
|
? "<stdin>" : "<stdout>"};
|
||||||
}},
|
}},
|
||||||
_file);
|
_file);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ static std::vector<size_t> readAtFile(std::filesystem::path const &path,
|
|||||||
std::vector<char> &argPool) {
|
std::vector<char> &argPool) {
|
||||||
File file;
|
File file;
|
||||||
if (!file.open(path, std::ios_base::in)) {
|
if (!file.open(path, std::ios_base::in)) {
|
||||||
fatal("Error reading @%s: %s", file.c_str(path), strerror(errno));
|
fatal("Error reading @%s: %s", file.string(path).c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only filter out `EOF`, but calling `isblank()` on anything else is UB!
|
// We only filter out `EOF`, but calling `isblank()` on anything else is UB!
|
||||||
|
|||||||
@@ -89,13 +89,13 @@ class Png {
|
|||||||
[[noreturn]] static void handleError(png_structp png, char const *msg) {
|
[[noreturn]] static void handleError(png_structp png, char const *msg) {
|
||||||
Png *self = reinterpret_cast<Png *>(png_get_error_ptr(png));
|
Png *self = reinterpret_cast<Png *>(png_get_error_ptr(png));
|
||||||
|
|
||||||
fatal("Error reading input image (\"%s\"): %s", self->file.c_str(self->path), msg);
|
fatal("Error reading input image (\"%s\"): %s", self->string().c_str(), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleWarning(png_structp png, char const *msg) {
|
static void handleWarning(png_structp png, char const *msg) {
|
||||||
Png *self = reinterpret_cast<Png *>(png_get_error_ptr(png));
|
Png *self = reinterpret_cast<Png *>(png_get_error_ptr(png));
|
||||||
|
|
||||||
warning("In input image (\"%s\"): %s", self->file.c_str(self->path), msg);
|
warning("In input image (\"%s\"): %s", self->string().c_str(), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void readData(png_structp png, png_bytep data, size_t length) {
|
static void readData(png_structp png, png_bytep data, size_t length) {
|
||||||
@@ -107,7 +107,7 @@ class Png {
|
|||||||
if (nbBytesRead != expectedLen) {
|
if (nbBytesRead != expectedLen) {
|
||||||
fatal("Error reading input image (\"%s\"): file too short (expected at least %zd more "
|
fatal("Error reading input image (\"%s\"): file too short (expected at least %zd more "
|
||||||
"bytes after reading %lld)",
|
"bytes after reading %lld)",
|
||||||
self->file.c_str(self->path), length - nbBytesRead,
|
self->string().c_str(), length - nbBytesRead,
|
||||||
self->file->pubseekoff(0, std::ios_base::cur));
|
self->file->pubseekoff(0, std::ios_base::cur));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,6 +129,8 @@ public:
|
|||||||
|
|
||||||
Rgba const &pixel(uint32_t x, uint32_t y) const { return pixels[y * width + x]; }
|
Rgba const &pixel(uint32_t x, uint32_t y) const { return pixels[y * width + x]; }
|
||||||
|
|
||||||
|
std::string string() const { return file.string(path); }
|
||||||
|
|
||||||
bool isSuitableForGrayscale() const {
|
bool isSuitableForGrayscale() const {
|
||||||
// Check that all of the grays don't fall into the same "bin"
|
// Check that all of the grays don't fall into the same "bin"
|
||||||
if (colors.size() > options.maxOpaqueColors()) { // Apply the Pigeonhole Principle
|
if (colors.size() > options.maxOpaqueColors()) { // Apply the Pigeonhole Principle
|
||||||
@@ -172,7 +174,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
explicit Png(std::filesystem::path const &filePath) : path(filePath), colors() {
|
explicit Png(std::filesystem::path const &filePath) : path(filePath), colors() {
|
||||||
if (file.open(path, std::ios_base::in | std::ios_base::binary) == nullptr) {
|
if (file.open(path, std::ios_base::in | std::ios_base::binary) == nullptr) {
|
||||||
fatal("Failed to open input image (\"%s\"): %s", file.c_str(path), strerror(errno));
|
fatal("Failed to open input image (\"%s\"): %s", file.string(path).c_str(),
|
||||||
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
options.verbosePrint(Options::VERB_LOG_ACT, "Opened input file\n");
|
options.verbosePrint(Options::VERB_LOG_ACT, "Opened input file\n");
|
||||||
@@ -182,7 +185,7 @@ public:
|
|||||||
if (file->sgetn(reinterpret_cast<char *>(pngHeader.data()), pngHeader.size())
|
if (file->sgetn(reinterpret_cast<char *>(pngHeader.data()), pngHeader.size())
|
||||||
!= static_cast<std::streamsize>(pngHeader.size()) // Not enough bytes?
|
!= static_cast<std::streamsize>(pngHeader.size()) // Not enough bytes?
|
||||||
|| png_sig_cmp(pngHeader.data(), 0, pngHeader.size()) != 0) {
|
|| png_sig_cmp(pngHeader.data(), 0, pngHeader.size()) != 0) {
|
||||||
fatal("Input file (\"%s\") is not a PNG image!", file.c_str(path));
|
fatal("Input file (\"%s\") is not a PNG image!", file.string(path).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
options.verbosePrint(Options::VERB_INTERM, "PNG header signature is OK\n");
|
options.verbosePrint(Options::VERB_INTERM, "PNG header signature is OK\n");
|
||||||
@@ -641,7 +644,7 @@ static void outputPalettes(std::vector<Palette> const &palettes) {
|
|||||||
if (options.palettes.has_value()) {
|
if (options.palettes.has_value()) {
|
||||||
File output;
|
File output;
|
||||||
if (!output.open(*options.palettes, std::ios_base::out | std::ios_base::binary)) {
|
if (!output.open(*options.palettes, std::ios_base::out | std::ios_base::binary)) {
|
||||||
fatal("Failed to open \"%s\": %s", output.c_str(*options.palettes),
|
fatal("Failed to open \"%s\": %s", output.string(*options.palettes).c_str(),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -772,7 +775,8 @@ static void outputTileData(Png const &png, DefaultInitVec<AttrmapEntry> const &a
|
|||||||
DefaultInitVec<size_t> const &mappings) {
|
DefaultInitVec<size_t> const &mappings) {
|
||||||
File output;
|
File output;
|
||||||
if (!output.open(*options.output, std::ios_base::out | std::ios_base::binary)) {
|
if (!output.open(*options.output, std::ios_base::out | std::ios_base::binary)) {
|
||||||
fatal("Failed to open \"%s\": %s", output.c_str(*options.output), strerror(errno));
|
fatal("Failed to open \"%s\": %s", output.string(*options.output).c_str(),
|
||||||
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t widthTiles = options.inputSlice.width ? options.inputSlice.width : png.getWidth() / 8;
|
uint16_t widthTiles = options.inputSlice.width ? options.inputSlice.width : png.getWidth() / 8;
|
||||||
@@ -809,7 +813,7 @@ static void outputMaps(DefaultInitVec<AttrmapEntry> const &attrmap,
|
|||||||
if (path.has_value()) {
|
if (path.has_value()) {
|
||||||
file.emplace();
|
file.emplace();
|
||||||
if (!file->open(*path, std::ios_base::out | std::ios_base::binary)) {
|
if (!file->open(*path, std::ios_base::out | std::ios_base::binary)) {
|
||||||
fatal("Failed to open \"%s\": %s", file->c_str(*path),
|
fatal("Failed to open \"%s\": %s", file->string(*path).c_str(),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -912,7 +916,8 @@ static UniqueTiles dedupTiles(Png const &png, DefaultInitVec<AttrmapEntry> &attr
|
|||||||
static void outputTileData(UniqueTiles const &tiles) {
|
static void outputTileData(UniqueTiles const &tiles) {
|
||||||
File output;
|
File output;
|
||||||
if (!output.open(*options.output, std::ios_base::out | std::ios_base::binary)) {
|
if (!output.open(*options.output, std::ios_base::out | std::ios_base::binary)) {
|
||||||
fatal("Failed to create \"%s\": %s", output.c_str(*options.output), strerror(errno));
|
fatal("Failed to create \"%s\": %s", output.string(*options.output).c_str(),
|
||||||
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t tileID = 0;
|
uint16_t tileID = 0;
|
||||||
@@ -927,7 +932,8 @@ static void outputTileData(UniqueTiles const &tiles) {
|
|||||||
static void outputTilemap(DefaultInitVec<AttrmapEntry> const &attrmap) {
|
static void outputTilemap(DefaultInitVec<AttrmapEntry> const &attrmap) {
|
||||||
File output;
|
File output;
|
||||||
if (!output.open(*options.tilemap, std::ios_base::out | std::ios_base::binary)) {
|
if (!output.open(*options.tilemap, std::ios_base::out | std::ios_base::binary)) {
|
||||||
fatal("Failed to create \"%s\": %s", output.c_str(*options.tilemap), strerror(errno));
|
fatal("Failed to create \"%s\": %s", output.string(*options.tilemap).c_str(),
|
||||||
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AttrmapEntry const &entry : attrmap) {
|
for (AttrmapEntry const &entry : attrmap) {
|
||||||
@@ -939,7 +945,8 @@ static void outputAttrmap(DefaultInitVec<AttrmapEntry> const &attrmap,
|
|||||||
DefaultInitVec<size_t> const &mappings) {
|
DefaultInitVec<size_t> const &mappings) {
|
||||||
File output;
|
File output;
|
||||||
if (!output.open(*options.attrmap, std::ios_base::out | std::ios_base::binary)) {
|
if (!output.open(*options.attrmap, std::ios_base::out | std::ios_base::binary)) {
|
||||||
fatal("Failed to create \"%s\": %s", output.c_str(*options.attrmap), strerror(errno));
|
fatal("Failed to create \"%s\": %s", output.string(*options.attrmap).c_str(),
|
||||||
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AttrmapEntry const &entry : attrmap) {
|
for (AttrmapEntry const &entry : attrmap) {
|
||||||
@@ -954,7 +961,8 @@ static void outputPalmap(DefaultInitVec<AttrmapEntry> const &attrmap,
|
|||||||
DefaultInitVec<size_t> const &mappings) {
|
DefaultInitVec<size_t> const &mappings) {
|
||||||
File output;
|
File output;
|
||||||
if (!output.open(*options.palmap, std::ios_base::out | std::ios_base::binary)) {
|
if (!output.open(*options.palmap, std::ios_base::out | std::ios_base::binary)) {
|
||||||
fatal("Failed to create \"%s\": %s", output.c_str(*options.palmap), strerror(errno));
|
fatal("Failed to create \"%s\": %s", output.string(*options.palmap).c_str(),
|
||||||
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AttrmapEntry const &entry : attrmap) {
|
for (AttrmapEntry const &entry : attrmap) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
static DefaultInitVec<uint8_t> readInto(std::filesystem::path path) {
|
static DefaultInitVec<uint8_t> readInto(std::filesystem::path path) {
|
||||||
File file;
|
File file;
|
||||||
if (!file.open(path, std::ios::in | std::ios::binary)) {
|
if (!file.open(path, std::ios::in | std::ios::binary)) {
|
||||||
fatal("Failed to open \"%s\": %s", file.c_str(path), strerror(errno));
|
fatal("Failed to open \"%s\": %s", file.string(path).c_str(), strerror(errno));
|
||||||
}
|
}
|
||||||
DefaultInitVec<uint8_t> data(128 * 16); // Begin with some room pre-allocated
|
DefaultInitVec<uint8_t> data(128 * 16); // Begin with some room pre-allocated
|
||||||
|
|
||||||
@@ -144,7 +144,8 @@ void reverse() {
|
|||||||
if (options.palettes.has_value()) {
|
if (options.palettes.has_value()) {
|
||||||
File file;
|
File file;
|
||||||
if (!file.open(*options.palettes, std::ios::in | std::ios::binary)) {
|
if (!file.open(*options.palettes, std::ios::in | std::ios::binary)) {
|
||||||
fatal("Failed to open \"%s\": %s", file.c_str(*options.palettes), strerror(errno));
|
fatal("Failed to open \"%s\": %s", file.string(*options.palettes).c_str(),
|
||||||
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
palettes.clear();
|
palettes.clear();
|
||||||
@@ -231,12 +232,13 @@ void reverse() {
|
|||||||
options.verbosePrint(Options::VERB_LOG_ACT, "Writing image...\n");
|
options.verbosePrint(Options::VERB_LOG_ACT, "Writing image...\n");
|
||||||
File pngFile;
|
File pngFile;
|
||||||
if (!pngFile.open(*options.input, std::ios::out | std::ios::binary)) {
|
if (!pngFile.open(*options.input, std::ios::out | std::ios::binary)) {
|
||||||
fatal("Failed to create \"%s\": %s", pngFile.c_str(*options.input), strerror(errno));
|
fatal("Failed to create \"%s\": %s", pngFile.string(*options.input).c_str(),
|
||||||
|
strerror(errno));
|
||||||
}
|
}
|
||||||
png_structp png = png_create_write_struct(
|
png_structp png = png_create_write_struct(
|
||||||
PNG_LIBPNG_VER_STRING,
|
PNG_LIBPNG_VER_STRING,
|
||||||
const_cast<png_voidp>(static_cast<void const *>(pngFile.c_str(*options.input))), pngError,
|
const_cast<png_voidp>(static_cast<void const *>(pngFile.string(*options.input).c_str())),
|
||||||
pngWarning);
|
pngError, pngWarning);
|
||||||
if (!png) {
|
if (!png) {
|
||||||
fatal("Couldn't create PNG write struct: %s", strerror(errno));
|
fatal("Couldn't create PNG write struct: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user