@@ -262,19 +262,39 @@ bool tImagePNG::Load(const uint8* pngFileInMemory, int numBytes, const LoadParam
262
262
return false ;
263
263
}
264
264
265
- int bitDepth = ihdr.bit_depth ;
266
- bool hasAlpha = (ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA) || (ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA);
267
265
Width = ihdr.width ;
268
266
Height = ihdr.height ;
269
267
int numPixels = Width * Height;
268
+ int bitDepth = ihdr.bit_depth ;
270
269
271
- // If the src bit depth is 16, RGBA are all linear. Otherwise RGB are sRGB and A is linear.
272
- if (bitDepth == 16 )
273
- PixelFormatSrc = hasAlpha ? tPixelFormat::R16G16B16A16 : tPixelFormat::R16G16B16;
270
+ if (ihdr.color_type == SPNG_COLOR_TYPE_INDEXED)
271
+ {
272
+ switch (bitDepth)
273
+ {
274
+ case 1 : PixelFormatSrc = tPixelFormat::PAL1BIT; break ;
275
+ case 2 : PixelFormatSrc = tPixelFormat::PAL2BIT; break ;
276
+ case 3 : PixelFormatSrc = tPixelFormat::PAL3BIT; break ;
277
+ case 4 : PixelFormatSrc = tPixelFormat::PAL4BIT; break ;
278
+ case 5 : PixelFormatSrc = tPixelFormat::PAL5BIT; break ;
279
+ case 6 : PixelFormatSrc = tPixelFormat::PAL6BIT; break ;
280
+ case 7 : PixelFormatSrc = tPixelFormat::PAL7BIT; break ;
281
+ default :
282
+ case 8 : PixelFormatSrc = tPixelFormat::PAL8BIT; break ;
283
+ }
284
+ }
274
285
else
275
- PixelFormatSrc = hasAlpha ? tPixelFormat::R8G8B8A8 : tPixelFormat::R8G8B8;
286
+ {
287
+ bool hasAlpha = (ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA) || (ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA);
288
+
289
+ // If the src bit depth is 16, RGBA are all linear. Otherwise RGB are sRGB and A is linear.
290
+ if (bitDepth == 16 )
291
+ PixelFormatSrc = hasAlpha ? tPixelFormat::R16G16B16A16 : tPixelFormat::R16G16B16;
292
+ else
293
+ PixelFormatSrc = hasAlpha ? tPixelFormat::R8G8B8A8 : tPixelFormat::R8G8B8;
294
+ ColourProfileSrc = (bitDepth == 16 ) ? tColourProfile::lRGB : tColourProfile::sRGB ;
295
+ }
296
+
276
297
PixelFormat = PixelFormatSrc;
277
- ColourProfileSrc = (bitDepth == 16 ) ? tColourProfile::lRGB : tColourProfile::sRGB ;
278
298
ColourProfile = ColourProfileSrc;
279
299
280
300
// Are we being asked to do auto-gamma-compression?
@@ -296,13 +316,11 @@ bool tImagePNG::Load(const uint8* pngFileInMemory, int numBytes, const LoadParam
296
316
}
297
317
298
318
// Output format, does not depend on source PNG format except for SPNG_FMT_PNG, which is the PNGs format in
299
- // host-endian (or big-endian for SPNG_FMT_RAW). Note that for these two formats <8-bit images are left byte-packed.
300
- // Here we decode to a 16 bit buffer if the src is 16 bit to keep full precision.
319
+ // host-endian (or big-endian for SPNG_FMT_RAW). Note that for these two formats < 8-bit images are left byte-packed.
320
+ // Here we decode to a 16 bit buffer if the src is 16 bit to keep full precision. For non-16-bit per component
321
+ // buffers, including palettized, we decode to RGBA8.
301
322
int fmt = (bitDepth == 16 ) ? SPNG_FMT_RGBA16 : SPNG_FMT_RGBA8;
302
323
303
- // With SPNG_FMT_PNG indexed color images are output as palette indices, pick another format to expand them.
304
- // if (ihdr.color_type == SPNG_COLOR_TYPE_INDEXED)
305
- // fmt = SPNG_FMT_RGBA8;
306
324
size_t rawPixelsSize = 0 ;
307
325
errCode = spng_decoded_image_size (ctx, fmt, &rawPixelsSize);
308
326
if (errCode)
@@ -314,8 +332,9 @@ bool tImagePNG::Load(const uint8* pngFileInMemory, int numBytes, const LoadParam
314
332
315
333
uint8* rawPixels = new uint8[rawPixelsSize];
316
334
317
- // Decode the image in one go.
318
- errCode = spng_decode_image (ctx, rawPixels, rawPixelsSize, fmt, 0 );
335
+ // Decode the image in one go. I'm pretty sure we always want to decode transparency.
336
+ // Certainly for palettized images it is required.
337
+ errCode = spng_decode_image (ctx, rawPixels, rawPixelsSize, fmt, SPNG_DECODE_TRNS);
319
338
if (errCode)
320
339
{
321
340
delete[] rawPixels;
0 commit comments