{"record":{"id":"216813c440262eae","repo":"HMCL-dev/HMCL","slug":"illegal-to-have-trns-chunk-with-image-type","errorCode":null,"errorMessage":"Illegal to have tRNS chunk with image type ","messagePattern":"Illegal to have tRNS chunk with image type ","errorType":"exception","errorClass":"PngIntegrityException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/ui/image/apng/argb8888/Argb8888Processor.java","lineNumber":88,"sourceCode":"                }\n                builder.processTransparentGreyscale(bytes[0], bytes[1]);\n                break;\n\n            case PNG_TRUECOLOUR: // colour type 2\n                // red, green, blue samples, EACH with two bytes (16-bits)\n                builder.processTransparentTruecolour(bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5]);\n                break;\n\n            case PNG_INDEXED_COLOUR: // colour type 3\n                // This is a sequence of one-byte alpha values to apply to each palette entry starting at zero.\n                // The number of entries may be less than the size of the palette, but not more.\n                builder.processTransparentPalette(bytes, position, length);\n                break;\n\n            case PNG_GREYSCALE_WITH_ALPHA:\n            case PNG_TRUECOLOUR_WITH_ALPHA:\n            default:\n                throw new PngIntegrityException(\"Illegal to have tRNS chunk with image type \" + header.colourType.name);\n        }\n    }\n\n    /**\n     * The only supported animation type is not \"NOT_ANIMATED\".\n     */\n//    @Override\n//    public PngAnimationType chooseApngImageType(PngAnimationType type, PngFrameControl currentFrame) throws PngException {\n//        scanlineProcessor = Argb8888ScanlineProcessor.from(header, scanlineReader, currentFrame);\n//        return PngAnimationType.NOT_ANIMATED;\n//    }\n    @Override\n    public void processDefaultImageData(InputStream inputStream, PngChunkCode code, int position, int length) throws IOException, PngException {\n        if (!builder.wantDefaultImage()) {\n            inputStream.skip(length); // important!\n            return;\n        }\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/ui/image/apng/argb8888/Argb8888Processor.java#L70-L106","documentation":"PngIntegrityException thrown when a tRNS chunk is present for a colour type that must not carry one: greyscale-with-alpha (4), truecolour-with-alpha (6), or any unrecognized colour type. Per the PNG spec, images whose samples already include an alpha channel are fully transparent-capable, so tRNS is illegal. The processor rejects this as an integrity violation.","triggerScenarios":"Calling processTransparency on an Argb8888Processor when header.colourType is PNG_GREYSCALE_WITH_ALPHA or PNG_TRUECOLOUR_WITH_ALPHA, or falls into the default branch with an unknown colour type.","commonSituations":"PNG files edited to add an alpha channel while retaining a legacy tRNS chunk; broken encoders emitting tRNS for RGBA images; files converted from palette to RGBA with chunks copied over verbatim.","solutions":["Remove the tRNS chunk from the PNG (e.g. with pngcrush -rem trns or an image editor re-save)","If transparency is needed, encode the alpha directly in the image's alpha channel instead of tRNS","Verify the IHDR colour type matches the chunk set produced by the encoder","Catch PngIntegrityException and treat the file as invalid or strip transparency"],"exampleFix":"// before: tRNS chunk kept on a RGBA (colour type 6) image\npngWriter.writeChunk(\"tRNS\", trnsData); // processor throws\n// after: drop tRNS for alpha-channel colour types\nif (colourType != GREYSCALE_WITH_ALPHA && colourType != TRUECOLOUR_WITH_ALPHA) {\n    pngWriter.writeChunk(\"tRNS\", trnsData);\n}","handlingStrategy":"validation","validationCode":"if ((header.colourType == PngColourType.PNG_GREYSCALE_WITH_ALPHA\n        || header.colourType == PngColourType.PNG_TRUECOLOUR_WITH_ALPHA)\n        && chunkPresent(\"tRNS\")) {\n    throw new IllegalArgumentException(\"tRNS is illegal for alpha-channel colour types\");\n}","typeGuard":"boolean tRnsAllowed(PngHeader header) {\n    return header.colourType == PngColourType.PNG_GREYSCALE\n        || header.colourType == PngColourType.PNG_TRUECOLOUR\n        || header.colourType == PngColourType.PNG_INDEXED_COLOUR;\n}","tryCatchPattern":"try {\n    processor.processTransparency(bytes, position, length);\n} catch (PngIntegrityException e) {\n    LOG.warn(\"Illegal tRNS for image type, skipping: \" + e.getMessage());\n}","preventionTips":["Strip tRNS chunks when converting images to alpha-channel colour types","Verify colour type / chunk-set consistency when generating PNGs","Use pngcrush or similar to sanitize third-party images"],"tags":["png","transparency","chunk-validation","apng"],"backgroundTag":"invalid-state-transition","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}