HMCL-dev/HMCL · error · PngIntegrityException

Invalid bit depth

Error message

Invalid bit depth 

What it means

This integrity guard in PngHeader.checkHeaderParameters fires when a PNG IHDR chunk declares a bit depth value outside the PNG specification's legal set (1, 2, 4, 8, 16). The input at fault is the raw bitDepth byte parsed from the IHDR chunk; any other value means the file is malformed or corrupt, so parsing cannot proceed safely.

Solutions

  1. Check the file starts with the 8-byte PNG signature and a well-formed IHDR before decoding.
  2. Re-obtain or re-encode the image; the source file's header is corrupt.
  3. Catch PngIntegrityException and fall back to another decoder or show an 'unsupported/corrupt image' message.

Example fix

// before
PngHeader.from(dataInput);
// after: sniff first
byte[] sig = new byte[8];
in.readFully(sig);
if (!Arrays.equals(sig, PNG_SIGNATURE)) throw new PngIntegrityException("not a PNG");
PngHeader.from(dataInput);
Defensive patterns

Strategy: validation

Validate before calling

// after reading IHDR fields
if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8 && bitDepth != 16) {
    throw new IllegalArgumentException("illegal PNG bit depth " + bitDepth);
}

Try / catch

try { header = PngHeader.from(dis); } catch (PngIntegrityException e) { reportCorruptImage(file, e); return null; }

Prevention

When it happens

Trigger: Parsing a PNG whose IHDR byte 8 (bit depth) holds a value like 0, 3, 5, 32, or random garbage because the file is not actually a PNG or has been corrupted.

Common situations: Feeding renamed non-PNG files (e.g. a JPEG renamed to .png), truncated/corrupted downloads, fuzzed or malicious images.

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/2c41220eb05ba16b. Report an issue: GitHub.

Appendix: source

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

    public PngHeader adjustFor(PngFrameControl frame) {
        if (frame == null) {
            return this;
        } else {
            return new PngHeader(frame.width, frame.height, this.bitDepth, this.colourType, this.compressionMethod, this.filterMethod, this.interlaceMethod);
        }
    }

    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");
        }

View on GitHub (pinned to 24702dc5a0)