Support 24 bit png loading.

This commit is contained in:
Paul Chote
2019-03-04 18:55:11 +00:00
committed by abcdefg30
parent ea2e452075
commit ab6ae7bc8d

View File

@@ -38,6 +38,7 @@ namespace OpenRA.FileFormats
s.Position += 8; s.Position += 8;
var headerParsed = false; var headerParsed = false;
var isPaletted = false; var isPaletted = false;
var is24Bit = false;
var data = new List<byte>(); var data = new List<byte>();
for (;;) for (;;)
@@ -64,6 +65,7 @@ namespace OpenRA.FileFormats
var bitDepth = ms.ReadUInt8(); var bitDepth = ms.ReadUInt8();
var colorType = (PngColorType)ms.ReadByte(); var colorType = (PngColorType)ms.ReadByte();
isPaletted = IsPaletted(bitDepth, colorType); isPaletted = IsPaletted(bitDepth, colorType);
is24Bit = colorType == PngColorType.Color;
var dataLength = Width * Height; var dataLength = Width * Height;
if (!isPaletted) if (!isPaletted)
@@ -130,21 +132,33 @@ namespace OpenRA.FileFormats
{ {
using (var ds = new InflaterInputStream(ns)) using (var ds = new InflaterInputStream(ns))
{ {
var pxStride = isPaletted ? 1 : 4; var pxStride = isPaletted ? 1 : is24Bit ? 3 : 4;
var stride = Width * pxStride; var srcStride = Width * pxStride;
var destStride = Width * (isPaletted ? 1 : 4);
var prevLine = new byte[stride]; var prevLine = new byte[srcStride];
for (var y = 0; y < Height; y++) for (var y = 0; y < Height; y++)
{ {
var filter = (PngFilter)ds.ReadByte(); var filter = (PngFilter)ds.ReadByte();
var line = ds.ReadBytes(stride); var line = ds.ReadBytes(srcStride);
for (var i = 0; i < stride; i++) for (var i = 0; i < srcStride; i++)
line[i] = i < pxStride line[i] = i < pxStride
? UnapplyFilter(filter, line[i], 0, prevLine[i], 0) ? UnapplyFilter(filter, line[i], 0, prevLine[i], 0)
: UnapplyFilter(filter, line[i], line[i - pxStride], prevLine[i], prevLine[i - pxStride]); : UnapplyFilter(filter, line[i], line[i - pxStride], prevLine[i], prevLine[i - pxStride]);
Array.Copy(line, 0, Data, y * stride, line.Length); if (is24Bit)
{
// Fold alpha channel into RGB data
for (var i = 0; i < line.Length / 3; i++)
{
Array.Copy(line, 3 * i, Data, y * destStride + 4 * i, 3);
Data[y * destStride + 4 * i + 3] = 255;
}
}
else
Array.Copy(line, 0, Data, y * destStride, line.Length);
prevLine = line; prevLine = line;
} }
} }
@@ -169,6 +183,7 @@ namespace OpenRA.FileFormats
if (data.Length != expectLength) if (data.Length != expectLength)
throw new InvalidDataException("Input data does not match expected length"); throw new InvalidDataException("Input data does not match expected length");
Width = width; Width = width;
Height = height; Height = height;
@@ -225,6 +240,9 @@ namespace OpenRA.FileFormats
if (bitDepth == 8 && colorType == (PngColorType.Color | PngColorType.Alpha)) if (bitDepth == 8 && colorType == (PngColorType.Color | PngColorType.Alpha))
return false; return false;
if (bitDepth == 8 && colorType == PngColorType.Color)
return false;
throw new InvalidDataException("Unknown pixel format"); throw new InvalidDataException("Unknown pixel format");
} }