fix (i hope) all bugs
This commit is contained in:
parent
e8cd664965
commit
201f9d7a7e
11 changed files with 195 additions and 37 deletions
53
src/icons.js
53
src/icons.js
|
|
@ -120,6 +120,36 @@ function pngSize(img) {
|
|||
return null
|
||||
}
|
||||
|
||||
// Raw RT_ICON payloads are BITMAPINFOHEADER-based bitmaps: biSize, biWidth,
|
||||
// biHeight (2x the visible height - XOR + AND mask), biPlanes, biBitCount,
|
||||
// ..., biClrUsed. Read the real dimensions from there instead of treating the
|
||||
// first bytes as an ICONDIRENTRY (which yielded garbage like h=0, planes=48
|
||||
// and made Chromium decode an empty image).
|
||||
function bmpDims(img) {
|
||||
if (img.length < 12) return null
|
||||
const biSize = img.readUInt32LE(0)
|
||||
if (biSize === 12) {
|
||||
// BITMAPCOREHEADER (Win 2.x/3.x era icons): DWORD size, then WORD width,
|
||||
// height, planes, bitcount
|
||||
const w = img.readUInt16LE(4)
|
||||
const h = Math.floor(img.readUInt16LE(6) / 2)
|
||||
const planes = img.readUInt16LE(8) || 1
|
||||
const bpp = img.readUInt16LE(10) || 32
|
||||
const colors = bpp <= 8 ? 1 << bpp : 0
|
||||
if (w > 0 && h > 0 && w <= 1024 && h <= 1024) return { w, h, planes, bpp, colors }
|
||||
return null
|
||||
}
|
||||
if (biSize >= 40 && biSize <= 124 && img.length > 40) {
|
||||
const w = img.readUInt32LE(4)
|
||||
const h = Math.floor(img.readUInt32LE(8) / 2)
|
||||
const planes = img.readUInt16LE(12) || 1
|
||||
const bpp = img.readUInt16LE(14) || 32
|
||||
const colors = img.readUInt32LE(32) || (bpp <= 8 ? 1 << bpp : 0)
|
||||
if (w > 0 && h > 0 && w <= 1024 && h <= 1024) return { w, h, planes, bpp, colors }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function buildIco(images) {
|
||||
const header = Buffer.alloc(6)
|
||||
header.writeUInt16LE(0, 0)
|
||||
|
|
@ -135,16 +165,27 @@ function buildIco(images) {
|
|||
w = dim.w
|
||||
h = dim.h
|
||||
} else {
|
||||
w = img.readUInt8(0) || 256
|
||||
h = img.readUInt8(1) || 256
|
||||
colors = img.readUInt8(2)
|
||||
planes = img.length > 4 ? img.readUInt16LE(4) || 1 : 1
|
||||
bpp = img.length > 6 ? img.readUInt16LE(6) || 32 : 32
|
||||
const dims = bmpDims(img)
|
||||
if (dims) {
|
||||
w = dims.w
|
||||
h = dims.h
|
||||
colors = dims.colors
|
||||
planes = dims.planes
|
||||
bpp = dims.bpp
|
||||
} else {
|
||||
// legacy fallback: ICONDIRENTRY-style first bytes (PNG-era heuristic)
|
||||
w = img.readUInt8(0) || 256
|
||||
h = img.readUInt8(1) || 256
|
||||
colors = img.readUInt8(2)
|
||||
planes = img.length > 4 ? img.readUInt16LE(4) || 1 : 1
|
||||
bpp = img.length > 6 ? img.readUInt16LE(6) || 32 : 32
|
||||
}
|
||||
}
|
||||
const meta = Buffer.alloc(16)
|
||||
meta.writeUInt8(w >= 256 ? 0 : w, 0)
|
||||
meta.writeUInt8(h >= 256 ? 0 : h, 1)
|
||||
meta.writeUInt8(colors, 2)
|
||||
// 0 in the ICO dir entry means "256+ colors" (palette implied by bpp)
|
||||
meta.writeUInt8(colors >= 256 ? 0 : colors, 2)
|
||||
meta.writeUInt8(0, 3)
|
||||
meta.writeUInt16LE(planes, 4)
|
||||
meta.writeUInt16LE(bpp, 6)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue