From 01332377ecee37e725f10527c0304b3772f2533a Mon Sep 17 00:00:00 2001 From: SLP-DEV1 Date: Thu, 27 Aug 2026 01:38:12 +0200 Subject: [PATCH 1/3] fix: add key-aware PSB tagged block length reader --- src/lib/psbAdditionalInfoLength.ts | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/lib/psbAdditionalInfoLength.ts diff --git a/src/lib/psbAdditionalInfoLength.ts b/src/lib/psbAdditionalInfoLength.ts new file mode 100644 index 0000000..2737a0e --- /dev/null +++ b/src/lib/psbAdditionalInfoLength.ts @@ -0,0 +1,34 @@ +const PSB_EIGHT_BYTE_LENGTH_KEYS = new Set([ + "LMsk", + "Lr16", + "Lr32", + "Layr", + "Mt16", + "Mt32", + "Mtrn", + "Alph", + "FMsk", + "lnk2", + "FEid", + "FXid", + "PxSD", +]); + +export function usesEightBytePsbAdditionalInfoLength(key: string): boolean { + return PSB_EIGHT_BYTE_LENGTH_KEYS.has(key); +} + +export function readAdditionalInfoLength( + view: DataView, + offset: number, + isPsb: boolean, + key: string, +): { length: number; bytesRead: 4 | 8 } { + if (isPsb && usesEightBytePsbAdditionalInfoLength(key)) { + const high = view.getUint32(offset, false); + const low = view.getUint32(offset + 4, false); + return { length: high * 0x100000000 + low, bytesRead: 8 }; + } + + return { length: view.getUint32(offset, false), bytesRead: 4 }; +} From dee0a8d6f5cb5cc8e68ae25545349ab2b5b19272 Mon Sep 17 00:00:00 2001 From: SLP-DEV1 Date: Thu, 27 Aug 2026 01:38:23 +0200 Subject: [PATCH 2/3] test: cover PSB tagged block length widths --- src/lib/psbAdditionalInfoLength.test.ts | 39 +++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/lib/psbAdditionalInfoLength.test.ts diff --git a/src/lib/psbAdditionalInfoLength.test.ts b/src/lib/psbAdditionalInfoLength.test.ts new file mode 100644 index 0000000..a45c5f9 --- /dev/null +++ b/src/lib/psbAdditionalInfoLength.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it } from "vitest"; +import { + readAdditionalInfoLength, + usesEightBytePsbAdditionalInfoLength, +} from "./psbAdditionalInfoLength"; + +describe("PSB additional layer information lengths", () => { + it("keeps normal tagged blocks at 4-byte lengths in PSB", () => { + const buffer = new ArrayBuffer(8); + const view = new DataView(buffer); + view.setUint32(0, 0x00000012, false); + view.setUint32(4, 0xdeadbeef, false); + + expect(readAdditionalInfoLength(view, 0, true, "luni")) + .toEqual({ length: 0x12, bytesRead: 4 }); + }); + + it("uses 8-byte lengths for the PSB keys defined by Adobe", () => { + const buffer = new ArrayBuffer(8); + const view = new DataView(buffer); + view.setUint32(0, 0x00000001, false); + view.setUint32(4, 0x00000002, false); + + expect(readAdditionalInfoLength(view, 0, true, "Layr")) + .toEqual({ length: 0x100000002, bytesRead: 8 }); + expect(usesEightBytePsbAdditionalInfoLength("Lr16")).toBe(true); + expect(usesEightBytePsbAdditionalInfoLength("PxSD")).toBe(true); + }); + + it("uses 4-byte lengths for PSD regardless of key", () => { + const buffer = new ArrayBuffer(8); + const view = new DataView(buffer); + view.setUint32(0, 1234, false); + view.setUint32(4, 5678, false); + + expect(readAdditionalInfoLength(view, 0, false, "Layr")) + .toEqual({ length: 1234, bytesRead: 4 }); + }); +}); From 757fb6245edb9bd1f093e86846d7cab4f167c5af Mon Sep 17 00:00:00 2001 From: SLP-DEV1 Date: Thu, 27 Aug 2026 01:38:58 +0200 Subject: [PATCH 3/3] fix: parse PSB additional info lengths by key --- src/lib/psdSmartObjectDetection.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib/psdSmartObjectDetection.ts b/src/lib/psdSmartObjectDetection.ts index a87daa1..cf02bd7 100644 --- a/src/lib/psdSmartObjectDetection.ts +++ b/src/lib/psdSmartObjectDetection.ts @@ -1,3 +1,5 @@ +import { readAdditionalInfoLength } from "./psbAdditionalInfoLength"; + export interface SmartObjectBounds { left: number; top: number; @@ -216,8 +218,10 @@ export async function detectSmartObjectNameFromPsd(file: File): Promise