HMCL-dev/HMCL · error · PngIntegrityException
Valid greyscale bit depths are 1, 2, 4, 8, not
Error message
Valid greyscale bit depths are 1, 2, 4, 8, not %d
What it means
Thrown by Argb8888Palette.forGreyscale as PngIntegrityException when the greyscale bit depth is not one of 1, 2, 4, or 8 — the only depths the PNG spec allows for greyscale images. The palette factory has no ramp for other depths.
Solutions
- Re-export or re-download the PNG — a valid greyscale PNG always uses bit depth 1, 2, 4, or 8
- Validate IHDR bit depth against the colour type before building palettes
- Catch PngIntegrityException and skip/reject the image with a clear diagnostic
- Use pngcheck to identify exactly which header field is non-conformant
Example fix
// before
Argb8888Palette p = Argb8888Palette.forGreyscale(bitDepth); // throws for 16-bit or odd depths
// after
if (bitDepth == 1 || bitDepth == 2 || bitDepth == 4 || bitDepth == 8) {
p = Argb8888Palette.forGreyscale(bitDepth);
} else {
throw new PngIntegrityException("Unsupported greyscale depth: " + bitDepth);
} Defensive patterns
Strategy: validation
Validate before calling
if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 && bitDepth != 8) {
throw new IllegalArgumentException("Unsupported greyscale bit depth: " + bitDepth);
} Type guard
static boolean isGreyscaleBitDepth(int depth) {
return depth == 1 || depth == 2 || depth == 4 || depth == 8;
} Try / catch
try {
palette = Argb8888Palette.forGreyscale(bitDepth);
} catch (PngIntegrityException e) {
throw new IOException("Non-conformant PNG bit depth: " + e.getMessage(), e);
} Prevention
- Cross-check IHDR bit depth against the allowed values per colour type
- Reject 16-bit depth inputs up front if you cannot down-convert
- Use pngcheck to validate headers of untrusted files
- Never hand-edit PNG header bytes; re-export via a tool instead
When it happens
Trigger: Decoding a greyscale PNG whose IHDR declares a bit depth of 3, 5, 6, 7, 16+, or 0 — a corrupt header or a non-conformant file.
Common situations: Corrupt or hand-edited PNG headers; crafted images; misparsed chunk data producing a bogus bit-depth value.
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
- Greyscale supports 1, 2, 4, 8 but not 16.
- Valid PNG colour types are 0, 2, 3, 4, 6. Type
- Invalid greyscale bit-depth
- Invalid greyscale-with-alpha bit-depth
- Invalid indexed colour bit-depth
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/225cc811e9c41398.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/ui/image/apng/argb8888/Argb8888Palette.java:111
if (null == greyPalette2) {
greyPalette2 = forGreyscale(4, 0x55);
}
yield greyPalette2;
}
case 4 -> {
if (null == greyPalette4) {
greyPalette4 = forGreyscale(16, 0x11);
}
yield greyPalette4;
}
case 8 -> {
if (null == greyPalette8) {
greyPalette8 = forGreyscale(256, 0x01);
}
yield greyPalette8;
}
default ->
throw new PngIntegrityException(String.format("Valid greyscale bit depths are 1, 2, 4, 8, not %d", bitDepth));
};
}
}
View on GitHub (pinned to 24702dc5a0)