[Scummvm-git-logs] scummvm master -> 1fa5e17b243269b00bd042407eef2976602600a9
dreammaster
dreammaster at scummvm.org
Thu Dec 24 03:35:15 UTC 2020
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
1fa5e17b24 IMAGE: Support pngs with alphas for multiple palette entries
Commit: 1fa5e17b243269b00bd042407eef2976602600a9
https://github.com/scummvm/scummvm/commit/1fa5e17b243269b00bd042407eef2976602600a9
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-12-23T19:32:19-08:00
Commit Message:
IMAGE: Support pngs with alphas for multiple palette entries
Changed paths:
image/png.cpp
diff --git a/image/png.cpp b/image/png.cpp
index 307334a64b..5a4fad2dab 100644
--- a/image/png.cpp
+++ b/image/png.cpp
@@ -151,6 +151,9 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) {
// No handling for unknown chunks yet.
int bitDepth, colorType, width, height, interlaceType;
png_uint_32 w, h;
+ uint32 rgbaPalette[256];
+ bool hasRgbaPalette = false;
+
png_get_IHDR(pngPtr, infoPtr, &w, &h, &bitDepth, &colorType, &interlaceType, NULL, NULL);
width = w;
height = h;
@@ -164,6 +167,9 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) {
if (colorType == PNG_COLOR_TYPE_PALETTE && (_keepTransparencyPaletted || !png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS))) {
int numPalette = 0;
png_colorp palette = NULL;
+ png_bytep trans = nullptr;
+ int numTrans = 0;
+
uint32 success = png_get_PLTE(pngPtr, infoPtr, &palette, &numPalette);
if (success != PNG_INFO_PLTE) {
png_destroy_read_struct(&pngPtr, &infoPtr, NULL);
@@ -175,20 +181,42 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) {
_palette[(i * 3)] = palette[i].red;
_palette[(i * 3) + 1] = palette[i].green;
_palette[(i * 3) + 2] = palette[i].blue;
-
}
if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) {
- png_bytep trans;
- int numTrans;
png_color_16p transColor;
png_get_tRNS(pngPtr, infoPtr, &trans, &numTrans, &transColor);
- assert(numTrans == 1);
- _transparentColor = *trans;
+
+ if (numTrans == 1) {
+ // For a single transparency color, the alpha should be fully transparent
+ assert(*trans == 0);
+ _transparentColor = 0;
+ } else {
+ // Multiple alphas are being specified for the palette, so we can't use
+ // _transparentColor, and will instead need to build an RGBA surface
+ assert(numTrans > 1);
+ hasRgbaPalette = true;
+ }
}
- _outputSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+ _outputSurface->create(width, height,
+ hasRgbaPalette ? getByteOrderRgbaPixelFormat() : Graphics::PixelFormat::createFormatCLUT8());
png_set_packing(pngPtr);
+
+ if (hasRgbaPalette) {
+ // Build up the RGBA palette using the transparency alphas
+ Common::fill(&rgbaPalette[0], &rgbaPalette[256], 0);
+ for (int i = 0; i < _paletteColorCount; ++i) {
+ byte a = (i < numTrans) ? trans[i] : 0xff;
+ rgbaPalette[i] = _outputSurface->format.ARGBToColor(
+ a, palette[i].red, palette[i].green, palette[i].blue);
+ }
+
+ // We won't be needing a separate palette
+ _paletteColorCount = 0;
+ delete[] _palette;
+ _palette = nullptr;
+ }
} else {
if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) {
png_set_expand(pngPtr);
@@ -217,7 +245,22 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) {
width = w;
height = h;
- if (interlaceType == PNG_INTERLACE_NONE) {
+ if (hasRgbaPalette) {
+ // Build up the RGBA surface from paletted rows
+ png_bytep rowPtr = new byte[width];
+ if (!rowPtr)
+ error("Could not allocate memory for row.");
+
+ for (int yp = 0; yp < height; ++yp) {
+ png_read_row(pngPtr, rowPtr, nullptr);
+ uint32 *destRowP = (uint32 *)_outputSurface->getBasePtr(0, yp);
+
+ for (int xp = 0; xp < width; ++xp)
+ destRowP[xp] = rgbaPalette[rowPtr[xp]];
+ }
+
+ delete[] rowPtr;
+ } else if (interlaceType == PNG_INTERLACE_NONE) {
// PNGs without interlacing can simply be read row by row.
for (int i = 0; i < height; i++) {
png_read_row(pngPtr, (png_bytep)_outputSurface->getBasePtr(0, i), NULL);
More information about the Scummvm-git-logs
mailing list