OpenRA/OpenRA · error · InvalidDataException
Unknown pixel format
Error message
Unknown pixel format
What it means
Thrown by the static IsPaletted() helper when the combination of bit depth and PNG color type does not match any of the three recognized patterns: (1) bitDepth <= 8 with colorType Indexed|Color (palette-based), (2) bitDepth == 8 with colorType Color|Alpha (RGBA), or (3) bitDepth == 8 with colorType Color (RGB). Any other combination is treated as an unknown pixel format.
Source
Thrown at OpenRA.Game/FileFormats/Png.cs:481
return isPng;
}
[Flags]
enum PngColorType : byte { Indexed = 1, Color = 2, Alpha = 4 }
enum PngFilter : byte { None, Sub, Up, Average, Paeth }
static bool IsPaletted(byte bitDepth, PngColorType colorType)
{
if (bitDepth <= 8 && colorType == (PngColorType.Indexed | PngColorType.Color))
return true;
if (bitDepth == 8 && colorType == (PngColorType.Color | PngColorType.Alpha))
return false;
if (bitDepth == 8 && colorType == PngColorType.Color)
return false;
throw new InvalidDataException("Unknown pixel format");
}
static void WritePngChunk(MemoryStream output, uint type, MemoryStream input)
{
Span<byte> header = stackalloc byte[8];
BinaryPrimitives.WriteInt32BigEndian(header[..4], (int)input.Length);
BinaryPrimitives.WriteUInt32BigEndian(header[4..], type);
if (!input.TryGetBuffer(out var dataSegment))
dataSegment = new ArraySegment<byte>(input.ToArray());
ReadOnlySpan<byte> data = dataSegment.AsSpan(0, (int)input.Length);
output.Write(header);
output.Write(data);
var crc = 0xFFFFFFFF;
crc = CRC32.Update(crc, header[4..]);View on GitHub (pinned to a520984d91)
Solutions
- Re-export the PNG as 8-bit RGB (color type 2) or 8-bit RGBA (color type 6).
- Convert to 8-bit: `convert input.png -depth 8 output.png`.
- Convert grayscale to RGB: `convert input.png -type TrueColor output.png`.
- For palette-based images, ensure bit depth is <= 8 with color type 3 (indexed).
Example fix
# convert 16-bit or grayscale PNG to 8-bit RGB convert input.png -depth 8 -type TrueColor output.png # or for RGBA convert input.png -depth 8 -type TrueColorAlpha output.png
Defensive patterns
Strategy: validation
Validate before calling
// Check IHDR bit depth and color type before loading
if (!Png.Verify(stream)) return;
stream.Position = 8 + 4 + 4; // skip sig + length + type
var ihdr = new byte[13];
stream.Read(ihdr, 0, 13);
stream.Seek(0, SeekOrigin.Begin);
var bitDepth = ihdr[8];
var colorType = ihdr[9]; // 0=gray, 2=rgb, 3=indexed, 4=gray+alpha, 6=rgba
if (bitDepth != 8 && !(bitDepth <= 8 && colorType == 3))
throw new InvalidDataException($"Unsupported bit depth {bitDepth}. Use 8-bit.");
if (colorType != 2 && colorType != 3 && colorType != 6)
throw new InvalidDataException($"Unsupported color type {colorType}. Use RGB(2), RGBA(6), or Indexed(3)."); Try / catch
try
{
var png = new Png(stream);
}
catch (InvalidDataException ex) when (ex.Message == "Unknown pixel format")
{
logger.LogError($"Unsupported PNG pixel format — re-export as 8-bit RGB or RGBA: {ex.Message}");
} Prevention
- Export all game assets as 8-bit RGB (color type 2) or 8-bit RGBA (color type 6).
- Avoid grayscale PNGs (color type 0/4) — convert to RGB before use.
- Avoid 16-bit depth PNGs — always use 8-bit.
- Add an asset validation step: `identify -format '%[depth] %[colorspace]' *.png` to check all assets.
When it happens
Trigger: Constructing `new Png(stream)` where the IHDR chunk specifies a bit depth / color type combination not in the supported set. For example: 16-bit depth, grayscale (colorType=0), grayscale+alpha (colorType=4), or bitDepth < 8 with a non-indexed color type. IsPaletted() is called during IHDR parsing and throws for unsupported formats.
Common situations: A 16-bit-per-channel PNG was provided (OpenRA only supports 8-bit). A grayscale PNG (color type 0) was used instead of RGB/RGBA. A grayscale+alpha PNG (color type 4). An unusual bit depth like 2 or 4 with a non-indexed color type.
Related errors
- Invalid PNG file - no end chunk found.
- Unexpected end of stream in IDAT chunk.
- PNG Signature is bogus
- Invalid PNG file - header does not appear first.
- Invalid PNG file - duplicate header.
AI-assisted analysis of OpenRA/OpenRA@a520984d91 (2026-08-13).
Data as JSON: /api/errors/d175b10a5fc208b2.
Report an issue: GitHub.