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

  1. Re-export or re-download the PNG — a valid greyscale PNG always uses bit depth 1, 2, 4, or 8
  2. Validate IHDR bit depth against the colour type before building palettes
  3. Catch PngIntegrityException and skip/reject the image with a clear diagnostic
  4. 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

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


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)