Merge pull request #7513 from Robyt3/ImageLoader-Greyscale-Fix

Handle all color channel counts in image loader, refactoring
This commit is contained in:
Dennis Felsing 2023-11-20 21:55:00 +00:00 committed by GitHub
commit 35f071b021
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 26 deletions

View file

@ -2,6 +2,7 @@
/* If you are missing that file, acquire a complete release at teeworlds.com. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */
#include <base/detect.h> #include <base/detect.h>
#include <base/log.h>
#include <base/math.h> #include <base/math.h>
#if defined(CONF_FAMILY_UNIX) #if defined(CONF_FAMILY_UNIX)
@ -551,7 +552,7 @@ bool CGraphics_Threaded::UpdateTextTexture(CTextureHandle TextureID, int x, int
return true; return true;
} }
int CGraphics_Threaded::LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType) bool CGraphics_Threaded::LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType)
{ {
char aCompleteFilename[IO_MAX_PATH_LENGTH]; char aCompleteFilename[IO_MAX_PATH_LENGTH];
IOHANDLE File = m_pStorage->OpenFile(pFilename, IOFLAG_READ, StorageType, aCompleteFilename, sizeof(aCompleteFilename)); IOHANDLE File = m_pStorage->OpenFile(pFilename, IOFLAG_READ, StorageType, aCompleteFilename, sizeof(aCompleteFilename));
@ -574,17 +575,17 @@ int CGraphics_Threaded::LoadPNG(CImageInfo *pImg, const char *pFilename, int Sto
int PngliteIncompatible; int PngliteIncompatible;
if(::LoadPNG(ImageByteBuffer, pFilename, PngliteIncompatible, pImg->m_Width, pImg->m_Height, pImgBuffer, ImageFormat)) if(::LoadPNG(ImageByteBuffer, pFilename, PngliteIncompatible, pImg->m_Width, pImg->m_Height, pImgBuffer, ImageFormat))
{ {
pImg->m_pData = pImgBuffer; if(ImageFormat == IMAGE_FORMAT_RGB)
if(ImageFormat == IMAGE_FORMAT_RGB) // ignore_convention
pImg->m_Format = CImageInfo::FORMAT_RGB; pImg->m_Format = CImageInfo::FORMAT_RGB;
else if(ImageFormat == IMAGE_FORMAT_RGBA) // ignore_convention else if(ImageFormat == IMAGE_FORMAT_RGBA)
pImg->m_Format = CImageInfo::FORMAT_RGBA; pImg->m_Format = CImageInfo::FORMAT_RGBA;
else else
{ {
free(pImgBuffer); free(pImgBuffer);
return 0; log_error("game/png", "image had unsupported image format. filename='%s' format='%d'", pFilename, (int)ImageFormat);
return false;
} }
pImg->m_pData = pImgBuffer;
if(m_WarnPngliteIncompatibleImages && PngliteIncompatible != 0) if(m_WarnPngliteIncompatibleImages && PngliteIncompatible != 0)
{ {
@ -612,17 +613,17 @@ int CGraphics_Threaded::LoadPNG(CImageInfo *pImg, const char *pFilename, int Sto
} }
else else
{ {
dbg_msg("game/png", "image had unsupported image format. filename='%s'", pFilename); log_error("game/png", "failed to load file. filename='%s'", pFilename);
return 0; return false;
} }
} }
else else
{ {
dbg_msg("game/png", "failed to open file. filename='%s'", pFilename); log_error("game/png", "failed to open file. filename='%s'", pFilename);
return 0; return false;
} }
return 1; return true;
} }
void CGraphics_Threaded::FreePNG(CImageInfo *pImg) void CGraphics_Threaded::FreePNG(CImageInfo *pImg)

View file

@ -965,7 +965,7 @@ public:
// simple uncompressed RGBA loaders // simple uncompressed RGBA loaders
IGraphics::CTextureHandle LoadTexture(const char *pFilename, int StorageType, int Flags = 0) override; IGraphics::CTextureHandle LoadTexture(const char *pFilename, int StorageType, int Flags = 0) override;
int LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType) override; bool LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType) override;
void FreePNG(CImageInfo *pImg) override; void FreePNG(CImageInfo *pImg) override;
bool CheckImageDivisibility(const char *pFileName, CImageInfo &Img, int DivX, int DivY, bool AllowResize) override; bool CheckImageDivisibility(const char *pFileName, CImageInfo &Img, int DivX, int DivY, bool AllowResize) override;

View file

@ -59,12 +59,15 @@ static EImageFormat LibPNGGetImageFormat(int ColorChannelCount)
{ {
case 1: case 1:
return IMAGE_FORMAT_R; return IMAGE_FORMAT_R;
case 2:
return IMAGE_FORMAT_RA;
case 3: case 3:
return IMAGE_FORMAT_RGB; return IMAGE_FORMAT_RGB;
case 4: case 4:
return IMAGE_FORMAT_RGBA; return IMAGE_FORMAT_RGBA;
default: default:
return IMAGE_FORMAT_RGBA; dbg_assert(false, "ColorChannelCount invalid");
dbg_break();
} }
} }
@ -276,14 +279,20 @@ static void FlushPNGWrite(png_structp png_ptr) {}
static int ImageLoaderHelperFormatToColorChannel(EImageFormat Format) static int ImageLoaderHelperFormatToColorChannel(EImageFormat Format)
{ {
if(Format == IMAGE_FORMAT_R) switch(Format)
{
case IMAGE_FORMAT_R:
return 1; return 1;
else if(Format == IMAGE_FORMAT_RGB) case IMAGE_FORMAT_RA:
return 2;
case IMAGE_FORMAT_RGB:
return 3; return 3;
else if(Format == IMAGE_FORMAT_RGBA) case IMAGE_FORMAT_RGBA:
return 4; return 4;
default:
return 4; dbg_assert(false, "Format invalid");
dbg_break();
}
} }
bool SavePNG(EImageFormat ImageFormat, const uint8_t *pRawBuffer, SImageByteBuffer &WrittenBytes, int Width, int Height) bool SavePNG(EImageFormat ImageFormat, const uint8_t *pRawBuffer, SImageByteBuffer &WrittenBytes, int Width, int Height)

View file

@ -8,6 +8,7 @@
enum EImageFormat enum EImageFormat
{ {
IMAGE_FORMAT_R = 0, IMAGE_FORMAT_R = 0,
IMAGE_FORMAT_RA,
IMAGE_FORMAT_RGB, IMAGE_FORMAT_RGB,
IMAGE_FORMAT_RGBA, IMAGE_FORMAT_RGBA,
}; };

View file

@ -320,7 +320,7 @@ public:
virtual const TTWGraphicsGPUList &GetGPUs() const = 0; virtual const TTWGraphicsGPUList &GetGPUs() const = 0;
virtual int LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType) = 0; virtual bool LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType) = 0;
virtual void FreePNG(CImageInfo *pImg) = 0; virtual void FreePNG(CImageInfo *pImg) = 0;
virtual bool CheckImageDivisibility(const char *pFileName, CImageInfo &Img, int DivX, int DivY, bool AllowResize) = 0; virtual bool CheckImageDivisibility(const char *pFileName, CImageInfo &Img, int DivX, int DivY, bool AllowResize) = 0;

View file

@ -23,7 +23,7 @@ int g_NewDataID = -1;
int g_NewDataSize = 0; int g_NewDataSize = 0;
void *g_pNewData = nullptr; void *g_pNewData = nullptr;
int LoadPNG(CImageInfo *pImg, const char *pFilename) bool LoadPNG(CImageInfo *pImg, const char *pFilename)
{ {
IOHANDLE File = io_open(pFilename, IOFLAG_READ); IOHANDLE File = io_open(pFilename, IOFLAG_READ);
if(File) if(File)
@ -48,23 +48,23 @@ int LoadPNG(CImageInfo *pImg, const char *pFilename)
{ {
pImg->m_pData = pImgBuffer; pImg->m_pData = pImgBuffer;
if(ImageFormat == IMAGE_FORMAT_RGB) // ignore_convention if(ImageFormat == IMAGE_FORMAT_RGB)
pImg->m_Format = CImageInfo::FORMAT_RGB; pImg->m_Format = CImageInfo::FORMAT_RGB;
else if(ImageFormat == IMAGE_FORMAT_RGBA) // ignore_convention else if(ImageFormat == IMAGE_FORMAT_RGBA)
pImg->m_Format = CImageInfo::FORMAT_RGBA; pImg->m_Format = CImageInfo::FORMAT_RGBA;
else else
{ {
free(pImgBuffer); free(pImgBuffer);
return 0; return false;
} }
} }
} }
else else
return 0; return false;
} }
else else
return 0; return false;
return 1; return true;
} }
void *ReplaceImageItem(int Index, CMapItemImage *pImgItem, const char *pImgName, const char *pImgFile, CMapItemImage *pNewImgItem) void *ReplaceImageItem(int Index, CMapItemImage *pImgItem, const char *pImgName, const char *pImgFile, CMapItemImage *pNewImgItem)