HMCL-dev/HMCL · error · PngIntegrityException

Illegal combination of bit depth

Error message

Illegal combination of bit depth (%d) and colour type (%d). See http://www.w3.org/TR/2003/REC-PNG-20031110/#table111 .

What it means

Thrown when the IHDR declares a bit depth/colour type combination not allowed by the PNG spec (table 11.1), e.g. bit depth below 8 for a colour type that does not support sub-byte depths (like truecolour RGB or RGBA).

Solutions

  1. Re-encode the image with a compliant PNG encoder to get a legal depth/colourType pair.
  2. Consult the PNG spec table 11.1 and ensure the producer uses valid combinations (e.g. greyscale 1/2/4/8/16, RGB 8/16, palette 1/2/4/8, grey+alpha 8/16, RGBA 8/16).
  3. Catch PngIntegrityException and treat the input as invalid.

Example fix

// before
processPng(inputStream);
// after: validate combination first
PngHeader h = peekHeader(inputStream);
if (!isValidDepthForColourType(h.bitDepth, h.colourType)) {
    throw new PngIntegrityException("illegal depth/colourType combination");
}
processPng(inputStream);
Defensive patterns

Strategy: validation

Validate before calling

// allowed combos per PNG spec table 11.1
boolean ok = (ct==0 && Set.of(1,2,4,8,16).contains(bd))
          || (ct==2 && (bd==8||bd==16))
          || (ct==3 && Set.of(1,2,4,8).contains(bd))
          || (ct==4 && (bd==8||bd==16))
          || (ct==6 && (bd==8||bd==16));
if (!ok) throw new IllegalArgumentException("illegal depth/colourType");

Try / catch

try { decode(bytes); } catch (PngIntegrityException e) { rejectImage("illegal header combination"); }

Prevention

When it happens

Trigger: An IHDR with, say, colour type 2 (truecolour) or 6 (RGBA) and bit depth 1/2/4, or colour type 0 (greyscale) with an illegal depth like 3.

Common situations: Corrupted or truncated images, malformed files from buggy encoders, fuzzed inputs.

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

Appendix: source

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

            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();
        byte bitDepth = dis.readByte();
        PngColourType colourType = PngColourType.fromByte(dis.readByte());
        byte compressionMethod = dis.readByte();
        byte filterMethod = dis.readByte();
        byte interlaceMethod = dis.readByte();
        checkHeaderParameters(width, height, bitDepth, colourType, compressionMethod, filterMethod, interlaceMethod);

View on GitHub (pinned to 24702dc5a0)