add PNG palette translation (#1865)

* fix m_butt1, m_butt2, m_vbox
This commit is contained in:
Roman Fomin 2024-08-23 16:23:47 +07:00 committed by GitHub
parent 23ae392ed6
commit bc39a9b1fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 73 additions and 5 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 999 B

After

Width:  |  Height:  |  Size: 999 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 999 B

After

Width:  |  Height:  |  Size: 999 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 931 B

After

Width:  |  Height:  |  Size: 931 B

View File

@ -20,6 +20,7 @@
#include "doomtype.h" #include "doomtype.h"
#include "i_printf.h" #include "i_printf.h"
#include "i_video.h"
#include "m_swap.h" #include "m_swap.h"
#include "r_defs.h" #include "r_defs.h"
#include "v_video.h" #include "v_video.h"
@ -339,6 +340,8 @@ patch_t *V_CachePatchNum(int lump, pu_tag tag)
return buffer; return buffer;
} }
byte *image = NULL, *translate = NULL;
spng_ctx *ctx = spng_ctx_new(0); spng_ctx *ctx = spng_ctx_new(0);
// Ignore and don't calculate chunk CRC's // Ignore and don't calculate chunk CRC's
@ -386,6 +389,25 @@ patch_t *V_CachePatchNum(int lump, pu_tag tag)
} }
} }
struct spng_plte plte = {0};
ret = spng_get_plte(ctx, &plte);
if (ret)
{
I_Printf(VB_ERROR, "V_CachePatchNum: spng_get_plte %s\n",
spng_strerror(ret));
goto error;
}
// Build translation table for palette.
byte *playpal = W_CacheLumpName("PLAYPAL", PU_CACHE);
translate = malloc(plte.n_entries);
for (int i = 0; i < plte.n_entries; ++i)
{
struct spng_plte_entry *e = &plte.entries[i];
translate[i] = I_GetPaletteIndex(playpal, e->red, e->green, e->blue);
}
int leftoffset = 0, topoffset = 0; int leftoffset = 0, topoffset = 0;
uint32_t n_chunks = 0; uint32_t n_chunks = 0;
ret = spng_get_unknown_chunks(ctx, NULL, &n_chunks); ret = spng_get_unknown_chunks(ctx, NULL, &n_chunks);
@ -424,18 +446,21 @@ patch_t *V_CachePatchNum(int lump, pu_tag tag)
goto error; goto error;
} }
byte *image = malloc(image_size); image = malloc(image_size);
ret = spng_decode_image(ctx, image, image_size, SPNG_FMT_PNG, 0); ret = spng_decode_image(ctx, image, image_size, SPNG_FMT_PNG, 0);
if (ret) if (ret)
{ {
I_Printf(VB_ERROR, "V_CachePatchNum: spng_decode_image %s", I_Printf(VB_ERROR, "V_CachePatchNum: spng_decode_image %s",
spng_strerror(ret)); spng_strerror(ret));
free(image);
goto error; goto error;
} }
for (int i = 0; i < image_size; ++i)
{
image[i] = translate[image[i]];
}
spng_ctx_free(ctx); spng_ctx_free(ctx);
Z_Free(buffer); Z_Free(buffer);
@ -453,12 +478,21 @@ patch_t *V_CachePatchNum(int lump, pu_tag tag)
patch->leftoffset = leftoffset; patch->leftoffset = leftoffset;
patch->topoffset = topoffset; patch->topoffset = topoffset;
free(image); free(image);
free(translate);
return lumpcache[lump]; return lumpcache[lump];
error: error:
spng_ctx_free(ctx); spng_ctx_free(ctx);
Z_Free(buffer); Z_Free(buffer);
if (image)
{
free(image);
}
if (translate)
{
free(translate);
}
return DummyPatch(lump, tag); return DummyPatch(lump, tag);
} }
@ -483,6 +517,8 @@ void *V_CacheFlatNum(int lump, pu_tag tag)
return buffer; return buffer;
} }
byte *image = NULL, *translate = NULL;
spng_ctx *ctx = spng_ctx_new(0); spng_ctx *ctx = spng_ctx_new(0);
// Ignore and don't calculate chunk CRC's // Ignore and don't calculate chunk CRC's
@ -508,6 +544,25 @@ void *V_CacheFlatNum(int lump, pu_tag tag)
goto error; goto error;
} }
struct spng_plte plte = {0};
ret = spng_get_plte(ctx, &plte);
if (ret)
{
I_Printf(VB_ERROR, "V_CacheFlatNum: spng_get_plte %s\n",
spng_strerror(ret));
goto error;
}
// Build translation table for palette.
byte *playpal = W_CacheLumpName("PLAYPAL", PU_CACHE);
translate = malloc(plte.n_entries);
for (int i = 0; i < plte.n_entries; ++i)
{
struct spng_plte_entry *e = &plte.entries[i];
translate[i] = I_GetPaletteIndex(playpal, e->red, e->green, e->blue);
}
size_t image_size = 0; size_t image_size = 0;
ret = spng_decoded_image_size(ctx, SPNG_FMT_PNG, &image_size); ret = spng_decoded_image_size(ctx, SPNG_FMT_PNG, &image_size);
@ -518,14 +573,18 @@ void *V_CacheFlatNum(int lump, pu_tag tag)
goto error; goto error;
} }
void *image = malloc(image_size); image = malloc(image_size);
ret = spng_decode_image(ctx, image, image_size, SPNG_FMT_PNG, 0); ret = spng_decode_image(ctx, image, image_size, SPNG_FMT_PNG, 0);
for (int i = 0; i < image_size; ++i)
{
image[i] = translate[image[i]];
}
if (ret) if (ret)
{ {
I_Printf(VB_ERROR, "V_CacheFlatNum: spng_decode_image %s", I_Printf(VB_ERROR, "V_CacheFlatNum: spng_decode_image %s",
spng_strerror(ret)); spng_strerror(ret));
free(image);
goto error; goto error;
} }
@ -535,12 +594,21 @@ void *V_CacheFlatNum(int lump, pu_tag tag)
Z_Malloc(image_size, tag, &lumpcache[lump]); Z_Malloc(image_size, tag, &lumpcache[lump]);
memcpy(lumpcache[lump], image, image_size); memcpy(lumpcache[lump], image, image_size);
free(image); free(image);
free(translate);
return lumpcache[lump]; return lumpcache[lump];
error: error:
spng_ctx_free(ctx); spng_ctx_free(ctx);
Z_Free(buffer); Z_Free(buffer);
if (image)
{
free(image);
}
if (translate)
{
free(translate);
}
return DummyFlat(lump, tag); return DummyFlat(lump, tag);
} }