HMCL-dev/HMCL · error · PngIntegrityException

Indexed images (colour type ) cannot have bitdepth > 8 (bit…

Error message

Indexed images (colour type %d) cannot have bitdepth > 8 (bit depth %d). See http://www.w3.org/TR/2003/REC-PNG-20031110/#table111 .

What it means

This guard enforces the PNG spec rule that indexed-colour (palette) images may only use bit depths up to 8. When checkHeaderParameters sees an indexed colour type whose declared bitDepth is 16, the IHDR combination is illegal per the PNG specification (Table 11, referenced in the message), so the header is rejected as an integrity error.

Solutions

  1. Fix the source image: re-encode it with a compliant tool so indexed images use bit depth <= 8.
  2. If you control generation, emit colour type 3 only with bit depths 1, 2, 4 or 8.
  3. Catch PngIntegrityException and reject the file as non-conformant.

Example fix

// before: accepting any header
PngHeader.from(dis);
// after: pre-check
if (colourType.code == 3 && bitDepth > 8) {
    throw new IllegalArgumentException("indexed PNG must have bitDepth <= 8");
}
PngHeader.from(dis);
Defensive patterns

Strategy: validation

Validate before calling

if (colourType == 3 && bitDepth > 8) throw new IllegalArgumentException("indexed PNG bitDepth must be <= 8");

Try / catch

try { header = PngHeader.from(dis); } catch (PngIntegrityException e) { showUnsupportedImageMessage(); }

Prevention

When it happens

Trigger: An IHDR with colour type 3 (indexed) and bit depth 16, typically from a corrupt header or a broken encoder.

Common situations: Corrupted PNGs, files produced by non-conformant tools, hand-crafted header bytes in test suites.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/0251b1d8d8b28094. Report an issue: GitHub.

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/ui/image/apng/chunks/PngHeader.java:197

        }
    }

    public static void checkHeaderParameters(int width, int height, byte bitDepth, PngColourType colourType, byte compressionMethod, byte filterMethod, byte interlaceMethod) throws PngException {

        switch (bitDepth) {
            case 1:
            case 2:
            case 4:
            case 8:
            case 16:
                break; // all fine
            default:
                throw new PngIntegrityException("Invalid bit depth " + bitDepth);
        }

        // thanks to pypng
        if (colourType.isIndexed() && bitDepth > 8) {
            throw new PngIntegrityException(String.format(
                    "Indexed images (colour type %d) cannot have bitdepth > 8 (bit depth %d)." +
                            " See http://www.w3.org/TR/2003/REC-PNG-20031110/#table111 .", colourType.code, bitDepth));
        }

        if (bitDepth < 8 && !colourType.supportsSubByteDepth()) {
            throw new PngIntegrityException(String.format(
                    "Illegal combination of bit depth (%d) and colour type (%d)." +
                            " See http://www.w3.org/TR/2003/REC-PNG-20031110/#table111 .", colourType.code, bitDepth));
        }

        if (interlaceMethod != 0) {
            throw new PngFeatureException("Interlaced images are not yet supported");
        }
    }

    public static PngHeader from(DataInput dis) throws IOException, PngException {
        int width = dis.readInt();
        int height = dis.readInt();

View on GitHub (pinned to 24702dc5a0)