{"record":{"id":"b1e5e9e049f69ed1","repo":"PHPOffice/PhpSpreadsheet","slug":"bitmap-only-1-plane-supported-in-bitmap-image-n","errorCode":null,"errorMessage":"$bitmap: only 1 plane supported in bitmap image.\\n","messagePattern":"\\$bitmap: only 1 plane supported in bitmap image\\.\\\\n","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Writer\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Writer/Xls/Worksheet.php","lineNumber":2520,"sourceCode":"        $width = $width_and_height[1];\n        /** @var int */\n        $height = $width_and_height[2];\n        $data = substr($data, 8);\n        if ($width > 0xFFFF) {\n            throw new WriterException(\"$bitmap: largest image width supported is 65k.\\n\");\n        }\n        if ($height > 0xFFFF) {\n            throw new WriterException(\"$bitmap: largest image height supported is 65k.\\n\");\n        }\n\n        // Read and remove the bitmap planes and bpp data. Verify them.\n        $planes_and_bitcount = unpack('v2', substr($data, 0, 4));\n        $data = substr($data, 4);\n        if ($planes_and_bitcount === false || $planes_and_bitcount[2] != 24) { // Bitcount\n            throw new WriterException(\"$bitmap isn't a 24bit true color bitmap.\\n\");\n        }\n        if ($planes_and_bitcount[1] != 1) {\n            throw new WriterException(\"$bitmap: only 1 plane supported in bitmap image.\\n\");\n        }\n\n        // Read and remove the bitmap compression. Verify compression.\n        $compression = unpack('Vcomp', substr($data, 0, 4));\n        $data = substr($data, 4);\n\n        if ($compression === false || $compression['comp'] != 0) {\n            throw new WriterException(\"$bitmap: compression not supported in bitmap image.\\n\");\n        }\n\n        // Remove bitmap data: data size, hres, vres, colours, imp. colours.\n        $data = substr($data, 20);\n\n        // Add the BITMAPCOREHEADER data\n        $header = pack('Vvvvv', 0x000C, $width, $height, 0x01, 0x18);\n        $data = $header . $data;\n\n        return [$width, $height, $size, $data];","sourceCodeStart":2502,"sourceCodeEnd":2538,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Writer/Xls/Worksheet.php#L2502-L2538","documentation":"The second half of the planes/bitcount check: processBitmap() requires the BMP header's planes field to equal exactly 1. Well-formed BMPs always declare 1 plane, so a different value means a malformed or exotic header, and the write is rejected.","triggerScenarios":"insertBitmap() with a hand-crafted or corrupted BMP whose biPlanes field is 0, 2, or higher; files produced by broken generators.","commonSituations":"Binary fixtures edited by hand; output of buggy third-party conversion tools; byte-level corruption.","solutions":["Re-export the bitmap with a reputable tool (GD, Photoshop, GIMP)","Validate the full header (planes == 1, bitcount == 24, compression == 0) before insertion","Fall back to PNG/JPEG via the Drawing API"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"$hdr = unpack('A2ident/vplanes/vbits', (string) file_get_contents($path, false, null, 0, 26));\nif ($hdr === false || $hdr['ident'] !== 'BM' || $hdr['planes'] !== 1) {\n    throw new InvalidArgumentException(\"Malformed BMP header in $path (planes != 1)\");\n}\n$worksheetWriter->insertBitmap($row, $col, $path);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate the full BMP header (magic, planes, bitcount, compression) in one pass before insertion","Regenerate suspicious files with a standard imaging library rather than patching bytes"],"tags":["phpspreadsheet","xls","bitmap","image-header","validation"],"backgroundTag":"invalid-image-header","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}