{"record":{"id":"2bf5ae2b88542210","repo":"Tencent/matrix","slug":"unable-to-obtained-scaled-bitmap-s-dimensions","errorCode":null,"errorMessage":"Unable to obtained scaled bitmap's dimensions","messagePattern":"Unable to obtained scaled bitmap's dimensions","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-resource-canary/matrix-resource-canary-analyzer-cli/src/main/java/com/tencent/matrix/resource/analyzer/utils/BitmapDecoder.java","lineNumber":90,"sourceCode":"        if (bitmapExtractor == null) {\n            throw new RuntimeException(\"Unsupported bitmap configuration: \" + config);\n        }\n\n        Dimension size = dataProvider.getDimension();\n        if (size == null) {\n            throw new RuntimeException(\"Unable to determine image dimensions.\");\n        }\n\n        // if the image is rather large, then scale it down\n        if (size.width > MAX_DIMENSION || size.height > MAX_DIMENSION) {\n            boolean couldDownsize = dataProvider.downsizeBitmap(size);\n            if (!couldDownsize) {\n                throw new RuntimeException(\"Unable to create scaled bitmap\");\n            }\n\n            size = dataProvider.getDimension();\n            if (size == null) {\n                throw new RuntimeException(\"Unable to obtained scaled bitmap's dimensions\");\n            }\n        }\n\n        return bitmapExtractor.getImage(size.width, size.height, dataProvider.getPixelBytes(size));\n    }\n\n    private static class ARGB8888_BitmapExtractor implements BitmapExtractor {\n        @Override\n        public BufferedImage getImage(int width, int height, byte[] rgba) {\n            @SuppressWarnings(\"UndesirableClassUsage\")\n            BufferedImage bufferedImage = new BufferedImage(width, height,\n                BufferedImage.TYPE_INT_ARGB);\n\n            for (int y = 0; y < height; y++) {\n                int stride = y * width;\n                for (int x = 0; x < width; x++) {\n                    int i = (stride + x) * 4;\n                    long rgb = 0;","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-resource-canary/matrix-resource-canary-analyzer-cli/src/main/java/com/tencent/matrix/resource/analyzer/utils/BitmapDecoder.java#L72-L108","documentation":"Matrix Resource Canary fails to read the width/height of a bitmap stored in an hprof heap dump after it has downsized the bitmap data. The decoder first re-encodes/downsizes the bitmap buffer, then calls dataProvider.getDimension(); if that returns null the scaled bitmap has no readable dimensions, so analysis cannot proceed and it throws a RuntimeException.","triggerScenarios":"getBitmap is called during hprof bitmap analysis when the bitmap buffer could be downsized but dataProvider.getDimension() returns null — i.e. the heap dump data for the bitmap is truncated, corrupted, or the bitmap's internal width/height fields could not be decoded from the scaled buffer.","commonSituations":"Analyzing hprof dumps from devices where the bitmap was too large and the downsizing step produced an unreadable buffer; corrupted or truncated hprof files; bitmaps whose mWidth/mHeight fields were recycled/cleared before the dump was taken.","solutions":["Verify the hprof file is complete and uncorrupted (re-capture the dump).","Check that the bitmap was not recycled before the heap dump was taken; skip analysis for recycled bitmaps.","Increase or disable the downsizing threshold (bitmap downsize config) so the original buffer is decoded directly.","Update Matrix to the latest version; bitmap decoding across Android bitmap representations (Bitmap.Config, hardware bitmaps) has been patched repeatedly.","Wrap the analysis step in try-catch and treat this bitmap as unanalyzable instead of failing the whole report."],"exampleFix":"// before\nsize = dataProvider.getDimension();\nif (size == null) {\n    throw new RuntimeException(\"Unable to obtained scaled bitmap's dimensions\");\n}\n// after\nsize = dataProvider.getDimension();\nif (size == null) {\n    // fall back to decoding without downscaling\n    size = decodeDimensionsWithoutDownsize(dataProvider);\n    if (size == null) {\n        return null; // skip this bitmap rather than aborting analysis\n    }\n}","handlingStrategy":"try-catch","validationCode":"// before analysis\nif (hprofFile == null || hprofFile.length() == 0) throw new IllegalArgumentException(\"empty hprof\");","typeGuard":null,"tryCatchPattern":"try { size = dataProvider.getDimension(); } catch (RuntimeException e) { log.warn(\"bitmap unreadable, skipping\", e); return null; }","preventionTips":["Re-capture hprof files rather than reusing possibly truncated dumps","Avoid analyzing bitmaps already recycled before the dump","Keep Matrix updated for bitmap-format compatibility","Treat per-bitmap decode failures as non-fatal in the report pipeline"],"tags":["android","heap-dump","bitmap","hprof"],"backgroundTag":"file-read-failed","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}