4304: Support unicode filenames on windows with pnglite (fixes #4301) r=Jupeyy a=def-

<!-- What is the motivation for the changes of this pull request -->

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: def <dennis@felsin9.de>
This commit is contained in:
bors[bot] 2021-11-05 17:05:01 +00:00 committed by GitHub
commit 8ecb3646ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 53 deletions

View file

@ -503,45 +503,41 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTexture(const char *pFilename,
int CGraphics_Threaded::LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType)
{
char aCompleteFilename[IO_MAX_PATH_LENGTH];
unsigned char *pBuffer;
png_t Png; // ignore_convention
// open file for reading
IOHANDLE File = m_pStorage->OpenFile(pFilename, IOFLAG_READ, StorageType, aCompleteFilename, sizeof(aCompleteFilename));
if(File)
io_close(File);
else
if(!File)
{
dbg_msg("game/png", "failed to open file. filename='%s'", pFilename);
return 0;
}
int Error = png_open_file(&Png, aCompleteFilename); // ignore_convention
png_t Png; // ignore_convention
int Error = png_open_read(&Png, 0, File); // ignore_convention
if(Error != PNG_NO_ERROR)
{
dbg_msg("game/png", "failed to open file. filename='%s', pnglite: %s", aCompleteFilename, png_error_string(Error));
if(Error != PNG_FILE_ERROR)
png_close_file(&Png); // ignore_convention
io_close(File);
return 0;
}
if(Png.depth != 8 || (Png.color_type != PNG_TRUECOLOR && Png.color_type != PNG_TRUECOLOR_ALPHA)) // ignore_convention
{
dbg_msg("game/png", "invalid format. filename='%s'", aCompleteFilename);
png_close_file(&Png); // ignore_convention
io_close(File);
return 0;
}
pBuffer = (unsigned char *)malloc((size_t)Png.width * Png.height * Png.bpp); // ignore_convention
unsigned char *pBuffer = (unsigned char *)malloc((size_t)Png.width * Png.height * Png.bpp); // ignore_convention
Error = png_get_data(&Png, pBuffer); // ignore_convention
if(Error != PNG_NO_ERROR)
{
dbg_msg("game/png", "failed to read image. filename='%s', pnglite: %s", aCompleteFilename, png_error_string(Error));
free(pBuffer);
png_close_file(&Png); // ignore_convention
io_close(File);
return 0;
}
png_close_file(&Png); // ignore_convention
io_close(File);
pImg->m_Width = Png.width; // ignore_convention
pImg->m_Height = Png.height; // ignore_convention
@ -667,16 +663,20 @@ void CGraphics_Threaded::ScreenshotDirect()
png_t Png; // ignore_convention
IOHANDLE File = m_pStorage->OpenFile(m_aScreenshotName, IOFLAG_WRITE, IStorage::TYPE_SAVE, aWholePath, sizeof(aWholePath));
if(File)
io_close(File);
// save png
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "saved screenshot to '%s'", aWholePath);
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf, ColorRGBA(1.0f, 0.6f, 0.3f, 1.0f));
png_open_file_write(&Png, aWholePath); // ignore_convention
png_set_data(&Png, Image.m_Width, Image.m_Height, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)Image.m_pData); // ignore_convention
png_close_file(&Png); // ignore_convention
if(!File)
{
dbg_msg("game/screenshot", "failed to open file. filename='%s'", aWholePath);
}
else
{
// save png
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "saved screenshot to '%s'", aWholePath);
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf, ColorRGBA(1.0f, 0.6f, 0.3f, 1.0f));
png_open_write(&Png, 0, File); // ignore_convention
png_set_data(&Png, Image.m_Width, Image.m_Height, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)Image.m_pData); // ignore_convention
io_close(File); // ignore_convention
}
free(Image.m_pData);
}

View file

@ -5,23 +5,29 @@
#include <engine/shared/image_manipulation.h>
#include <pnglite.h>
int DilateFile(const char *pFileName)
int DilateFile(const char *pFilename)
{
png_t Png;
png_init(0, 0);
int Error = png_open_file(&Png, pFileName);
IOHANDLE File = io_open(pFilename, IOFLAG_READ);
if(!File)
{
dbg_msg("dilate", "failed to open file. filename='%s'", pFilename);
return 0;
}
int Error = png_open_read(&Png, 0, File);
if(Error != PNG_NO_ERROR)
{
dbg_msg("dilate", "failed to open image file. filename='%s', pnglite: %s", pFileName, png_error_string(Error));
if(Error != PNG_FILE_ERROR)
png_close_file(&Png);
dbg_msg("dilate", "failed to open image file. filename='%s', pnglite: %s", pFilename, png_error_string(Error));
io_close(File);
return 0;
}
if(Png.color_type != PNG_TRUECOLOR_ALPHA)
{
dbg_msg("dilate", "%s: not an RGBA image", pFileName);
dbg_msg("dilate", "%s: not an RGBA image", pFilename);
return 1;
}
@ -30,12 +36,12 @@ int DilateFile(const char *pFileName)
Error = png_get_data(&Png, pBuffer);
if(Error != PNG_NO_ERROR)
{
dbg_msg("map_convert_07", "failed to read image. filename='%s', pnglite: %s", pFileName, png_error_string(Error));
dbg_msg("map_convert_07", "failed to read image. filename='%s', pnglite: %s", pFilename, png_error_string(Error));
free(pBuffer);
png_close_file(&Png);
io_close(File);
return 0;
}
png_close_file(&Png);
io_close(File);
int w = Png.width;
int h = Png.height;
@ -43,9 +49,22 @@ int DilateFile(const char *pFileName)
DilateImage(pBuffer, w, h, 4);
// save here
png_open_file_write(&Png, pFileName);
File = io_open(pFilename, IOFLAG_WRITE);
if(!File)
{
dbg_msg("dilate", "failed to open file. filename='%s'", pFilename);
free(pBuffer);
return 0;
}
Error = png_open_write(&Png, 0, File);
if(Error != PNG_NO_ERROR)
{
dbg_msg("dilate", "failed to open image file. filename='%s', pnglite: %s", pFilename, png_error_string(Error));
io_close(File);
return 0;
}
png_set_data(&Png, w, h, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)pBuffer);
png_close_file(&Png);
io_close(File);
free(pBuffer);

View file

@ -28,35 +28,39 @@ int g_aImageIDs[64];
int LoadPNG(CImageInfo *pImg, const char *pFilename)
{
unsigned char *pBuffer;
png_t Png;
IOHANDLE File = io_open(pFilename, IOFLAG_READ);
if(!File)
{
dbg_msg("map_convert_07", "failed to open file. filename='%s'", pFilename);
return 0;
}
int Error = png_open_file(&Png, pFilename);
png_t Png;
int Error = png_open_read(&Png, 0, File);
if(Error != PNG_NO_ERROR)
{
dbg_msg("map_convert_07", "failed to open image file. filename='%s', pnglite: %s", pFilename, png_error_string(Error));
if(Error != PNG_FILE_ERROR)
png_close_file(&Png);
io_close(File);
return 0;
}
if(Png.depth != 8 || Png.color_type != PNG_TRUECOLOR_ALPHA || Png.width > (2 << 12) || Png.height > (2 << 12))
{
dbg_msg("map_convert_07", "invalid image format. filename='%s'", pFilename);
png_close_file(&Png);
io_close(File);
return 0;
}
pBuffer = (unsigned char *)malloc((size_t)Png.width * Png.height * Png.bpp);
unsigned char *pBuffer = (unsigned char *)malloc((size_t)Png.width * Png.height * Png.bpp);
Error = png_get_data(&Png, pBuffer);
if(Error != PNG_NO_ERROR)
{
dbg_msg("map_convert_07", "failed to read image. filename='%s', pnglite: %s", pFilename, png_error_string(Error));
free(pBuffer);
png_close_file(&Png);
io_close(File);
return 0;
}
png_close_file(&Png);
io_close(File);
pImg->m_Width = Png.width;
pImg->m_Height = Png.height;

View file

@ -51,10 +51,23 @@ bool Process(IStorage *pStorage, const char *pMapName, const char *pPathSave)
dbg_msg("map_extract", "writing image: %s (%dx%d)", aBuf, pItem->m_Width, pItem->m_Height);
// copy image data
IOHANDLE File = io_open(pPathSave, IOFLAG_WRITE);
if(!File)
{
dbg_msg("map_extract", "failed to open file. filename='%s'", pPathSave);
continue;
}
png_t Png;
png_open_file_write(&Png, aBuf);
png_set_data(&Png, pItem->m_Width, pItem->m_Height, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)Map.GetData(pItem->m_ImageData));
png_close_file(&Png);
int Error = png_open_write(&Png, 0, File);
if(Error != PNG_NO_ERROR)
{
dbg_msg("map_extract", "failed to write image file. filename='%s', pnglite: %s", pPathSave, png_error_string(Error));
}
else
{
png_set_data(&Png, pItem->m_Width, pItem->m_Height, 8, PNG_TRUECOLOR_ALPHA, (unsigned char *)Map.GetData(pItem->m_ImageData));
}
io_close(File);
}
// load sounds

View file

@ -27,35 +27,39 @@ void *g_pNewData = 0;
int LoadPNG(CImageInfo *pImg, const char *pFilename)
{
unsigned char *pBuffer;
png_t Png;
int Error = png_open_file(&Png, pFilename);
IOHANDLE File = io_open(pFilename, IOFLAG_READ);
if(!File)
{
dbg_msg("dilate", "failed to open file. filename='%s'", pFilename);
return 0;
}
int Error = png_open_read(&Png, 0, File);
if(Error != PNG_NO_ERROR)
{
dbg_msg("map_replace_image", "failed to open image file. filename='%s', pnglite: %s", pFilename, png_error_string(Error));
if(Error != PNG_FILE_ERROR)
png_close_file(&Png);
io_close(File);
return 0;
}
if(Png.depth != 8 || (Png.color_type != PNG_TRUECOLOR && Png.color_type != PNG_TRUECOLOR_ALPHA) || Png.width > (2 << 12) || Png.height > (2 << 12))
{
dbg_msg("map_replace_image", "invalid image format. filename='%s'", pFilename);
png_close_file(&Png);
io_close(File);
return 0;
}
pBuffer = (unsigned char *)malloc((size_t)Png.width * Png.height * Png.bpp);
unsigned char *pBuffer = (unsigned char *)malloc((size_t)Png.width * Png.height * Png.bpp);
Error = png_get_data(&Png, pBuffer);
if(Error != PNG_NO_ERROR)
{
dbg_msg("map_convert_07", "failed to read image. filename='%s', pnglite: %s", pFilename, png_error_string(Error));
free(pBuffer);
png_close_file(&Png);
io_close(File);
return 0;
}
png_close_file(&Png);
io_close(File);
pImg->m_Width = Png.width;
pImg->m_Height = Png.height;