{"record":{"id":"97bd866889b1257e","repo":"BabylonJS/Babylon.js","slug":"wrong-piz-compression-bitmap-size","errorCode":null,"errorMessage":"Wrong PIZ_COMPRESSION BITMAP_SIZE","messagePattern":"Wrong PIZ_COMPRESSION BITMAP_SIZE","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.compression.ts","lineNumber":218,"sourceCode":"    let outBufferEnd = 0;\r\n    const pizChannelData = new Array(decoder.channels);\r\n    for (let i = 0; i < decoder.channels; i++) {\r\n        pizChannelData[i] = {};\r\n        pizChannelData[i][\"start\"] = outBufferEnd;\r\n        pizChannelData[i][\"end\"] = pizChannelData[i][\"start\"];\r\n        pizChannelData[i][\"nx\"] = decoder.width;\r\n        pizChannelData[i][\"ny\"] = decoder.lines;\r\n        pizChannelData[i][\"size\"] = decoder.type;\r\n\r\n        outBufferEnd += pizChannelData[i].nx * pizChannelData[i].ny * pizChannelData[i].size;\r\n    }\r\n\r\n    // Read range compression data\r\n    const minNonZero = ParseUint16(inDataView, inOffset);\r\n    const maxNonZero = ParseUint16(inDataView, inOffset);\r\n\r\n    if (maxNonZero >= BITMAP_SIZE) {\r\n        throw new Error(\"Wrong PIZ_COMPRESSION BITMAP_SIZE\");\r\n    }\r\n\r\n    if (minNonZero <= maxNonZero) {\r\n        for (let i = 0; i < maxNonZero - minNonZero + 1; i++) {\r\n            bitmap[i + minNonZero] = ParseUint8(inDataView, inOffset);\r\n        }\r\n    }\r\n\r\n    // Reverse LUT\r\n    const lut = new Uint16Array(USHORT_RANGE);\r\n    const maxValue = ReverseLutFromBitmap(bitmap, lut);\r\n\r\n    const length = ParseUint32(inDataView, inOffset);\r\n\r\n    // Huffman decoding\r\n    HufUncompress(decoder.array, inDataView, inOffset, length, outBuffer, outBufferEnd);\r\n\r\n    // Wavelet decoding\r","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/Materials/Textures/Loaders/EXR/exrLoader.compression.ts#L200-L236","documentation":"UncompressPIZ reads a bitmap used to reconstruct the 65536-entry luminance LUT of PIZ data. maxNonZero must be smaller than BITMAP_SIZE; a value >= BITMAP_SIZE means the bitmap section of the block is corrupt or misaligned, so the loader throws before overrunning the bitmap array.","triggerScenarios":"Raised in UncompressPIZ while reading the compressed-block preamble when ParseUint16 for maxNonZero returns a value >= BITMAP_SIZE — caused by wrong block offsets or corrupted compressed data.","commonSituations":"Malformed EXR files produced by broken writers, wrong chunk boundaries due to earlier parse drift, or corrupted downloads.","solutions":["Re-download/re-export the .exr and verify integrity","Open the file in a reference EXR utility to confirm the PIZ block structure is valid","Check the header/offset parsing upstream for drift that would misalign this read","Re-export with ZIP compression instead of PIZ"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await loader.loadAsync(file);\n} catch (e) {\n  if (/Wrong PIZ_COMPRESSION BITMAP_SIZE/.test(String(e))) {\n    console.warn(\"PIZ bitmap corrupt; falling back to PNG\");\n    return loadPngFallback();\n  }\n  throw e;\n}","preventionTips":["Validate EXRs with exrheader/oiiotool at import time","Avoid writers/tools known to emit broken PIZ data","Re-encode problem assets with ZIP compression","Keep checksums of shipped texture assets"],"tags":["exr","piz-compression","corrupted-data"],"backgroundTag":"corrupt-compressed-exr-data","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}