If I load 24bit pngs instead of palettized pngs, I get this result:
If I modify Convert24ToIndexed as follows:
/* set colors with palette indexes */
for (y = 0; y < source->height; y += 1)
{
RGBTRIPLE* srccolor = (RGBTRIPLE*)srcscan;
uint8_t* dstcolor = dstscan;
for (x = 0; x < source->width; x += 1)
{
uint32_t value = PackRGB32(srccolor->r, srccolor->g, srccolor->b);
uint8_t idx = set_get_index(&colors, value);
*dstcolor = !idx ? 0 : idx + 1; ///<<< preserve palette entry zero as clear color!
srccolor += 1;
dstcolor += 1;
}
srcscan += source->pitch;
dstscan += bitmap->pitch;
}
it shows that we must preserve zero as a clear pixel, however the palette indexing with the +1 is clearly incorrect.
BuildPaletteFromSet hardcodes 0xFFFF00FF in entry zero, which explains why there is a +1 in the algorithm above, and makes me think that we do need to preserve zero as a clear color.
So the remaining question is why are red and blue swapped.
I came across this using stb to load the png, stb unpalettizes, which forces repalettizing.
static TLN_Bitmap LoadPNG (const char* filename)
{
TLN_Bitmap bitmap = NULL;
int width, height, bpp;
uint8_t* data = stbi_load (filename, &width, &height, &bpp, 0);
if (data)
{
bitmap = TLN_CreateBitmap (width, height, bpp * 8);
if (bitmap)
{
int pitch = TLN_GetBitmapPitch (bitmap);
uint8_t* dst = TLN_GetBitmapPtr (bitmap, 0, 0);
int y;
for (y=0; y<height; y++)
{
memcpy (dst, data + y * width * bpp, width * bpp);
dst += pitch;
}
}
stbi_image_free (data);
}
return bitmap;
}
If I load the png with stb in the same program, and ask Dear ImGui to draw it, we can see that stb did not corrupt the image:
If I load with libpng, Dear ImGui displays it properly, and it still looks incorrect in game.
[update] The problem with colors turns out to be that I was creating my Metal texture using MTLPixelFormatRGBA8Unorm, using MTLPixelFormatBGRA8Unorm gives me the right colors.
PS, I found #64 which suggests what I am trying is not supported, but since there is a palettizer in the code, I tried it out, hence this report.
If I load 24bit pngs instead of palettized pngs, I get this result:
If I modify
Convert24ToIndexedas follows:it shows that we must preserve zero as a clear pixel, however the palette indexing with the +1 is clearly incorrect.
BuildPaletteFromSethardcodes0xFFFF00FFin entry zero, which explains why there is a +1 in the algorithm above, and makes me think that we do need to preserve zero as a clear color.So the remaining question is why are red and blue swapped.
I came across this using stb to load the png, stb unpalettizes, which forces repalettizing.
If I load the png with stb in the same program, and ask Dear ImGui to draw it, we can see that stb did not corrupt the image:
If I load with libpng, Dear ImGui displays it properly, and it still looks incorrect in game.
[update] The problem with colors turns out to be that I was creating my Metal texture using
MTLPixelFormatRGBA8Unorm, usingMTLPixelFormatBGRA8Unormgives me the right colors.PS, I found #64 which suggests what I am trying is not supported, but since there is a palettizer in the code, I tried it out, hence this report.