fix(capture): warn 300–799px PNG floor; hard-block only below 300

Split FLOOR_WARN_PX=800 / FLOOR_BLOCK_PX=300. Warn-band still encodes and
includes the photo (Photos-ready + batchApply ok+warn). Block excludes
siblings and clean cal. CAPTURE-105 / CAPTURE.md / PHOTOS.md updated.
This commit is contained in:
grokbot_ty
2026-09-26 09:11:34 -07:00
parent df87d97a7d
commit 1b5ad112cc
17 changed files with 246 additions and 69 deletions
+37 -7
View File
@@ -30,7 +30,8 @@ test('alpha contract: removed pixels transparent, slab pixels keep RGB at alpha
const source: Pick<Source, 'widthPx' | 'heightPx'> = { widthPx: W, heightPx: H };
const out = composeInventoryFrame(src, maskFor(bitset, { x: 1, y: 1, w: 4, h: 4 }), source);
assert.equal(out.sourceBelowFloor, true);
assert.equal(out.sourceBelowBlock, true, '4px slab is below block floor');
assert.equal(out.sourceBelowWarn, false);
assert.ok(out.width < 800, 'undersized source stays small');
let opaque = 0;
@@ -66,10 +67,11 @@ test('3:4 frame at the floor: 2000×1800 slab → 800×1067', () => {
);
assert.equal(out.width, 800);
assert.equal(out.height, 1067);
assert.equal(out.sourceBelowFloor, false);
assert.equal(out.sourceBelowBlock, false);
assert.equal(out.sourceBelowWarn, false);
});
test('mid-band: slab shorter side 1000 (between 800 and 1600) → at floor, not belowFloor', () => {
test('mid-band: slab shorter side 1000 (between 800 and 1600) → at floor, no warn/block', () => {
const source: Pick<Source, 'widthPx' | 'heightPx'> = { widthPx: 1200, heightPx: 1000 };
const bitset = new Uint8Array(source.widthPx * source.heightPx).fill(1);
const out = composeInventoryFrame(
@@ -77,10 +79,24 @@ test('mid-band: slab shorter side 1000 (between 800 and 1600) → at floor, not
maskFor(bitset, { x: 0, y: 0, w: 1200, h: 1000 }),
source,
);
assert.equal(out.sourceBelowFloor, false);
assert.equal(out.sourceBelowBlock, false);
assert.equal(out.sourceBelowWarn, false);
assert.equal(out.width, 800);
});
test('warn band: shorter side 500 (300–799) → sourceBelowWarn, encode allowed, no upscale past source', () => {
const source: Pick<Source, 'widthPx' | 'heightPx'> = { widthPx: 600, heightPx: 500 };
const bitset = new Uint8Array(source.widthPx * source.heightPx).fill(1);
const out = composeInventoryFrame(
makePhoto(source.widthPx, source.heightPx),
maskFor(bitset, { x: 0, y: 0, w: 600, h: 500 }),
source,
);
assert.equal(out.sourceBelowWarn, true);
assert.equal(out.sourceBelowBlock, false);
assert.ok(out.width <= 800, `outW ${out.width} must not exceed warn floor`);
});
test('90% fill: limiting dimension maps to 0.9 × frame side (#68)', () => {
const source: Pick<Source, 'widthPx' | 'heightPx'> = { widthPx: 2200, heightPx: 2000 };
const bitset = new Uint8Array(source.widthPx * source.heightPx).fill(1);
@@ -107,7 +123,7 @@ test('90% fill: limiting dimension maps to 0.9 × frame side (#68)', () => {
assert.ok(Math.abs(hExtent - 648) <= 2, `height extent ${hExtent} ≈ 648 (1800×0.36)`);
});
test('belowFloor: small slab → sourceBelowFloor, outW capped at floor (no upscale)', () => {
test('belowWarn (was belowFloor): 900×700 → warn not block, outW capped at warn floor', () => {
const source: Pick<Source, 'widthPx' | 'heightPx'> = { widthPx: 900, heightPx: 700 };
const bitset = new Uint8Array(source.widthPx * source.heightPx).fill(1);
const out = composeInventoryFrame(
@@ -115,6 +131,20 @@ test('belowFloor: small slab → sourceBelowFloor, outW capped at floor (no upsc
maskFor(bitset, { x: 0, y: 0, w: 900, h: 700 }),
source,
);
assert.equal(out.sourceBelowFloor, true);
assert.ok(out.width <= 800, `outW ${out.width} must not exceed the floor`);
assert.equal(out.sourceBelowWarn, true);
assert.equal(out.sourceBelowBlock, false);
assert.ok(out.width <= 800, `outW ${out.width} must not exceed the warn floor`);
});
test('belowBlock: shorter side 200 → sourceBelowBlock, no upscale', () => {
const source: Pick<Source, 'widthPx' | 'heightPx'> = { widthPx: 250, heightPx: 200 };
const bitset = new Uint8Array(source.widthPx * source.heightPx).fill(1);
const out = composeInventoryFrame(
makePhoto(source.widthPx, source.heightPx),
maskFor(bitset, { x: 0, y: 0, w: 250, h: 200 }),
source,
);
assert.equal(out.sourceBelowBlock, true);
assert.equal(out.sourceBelowWarn, false);
assert.ok(out.width <= 800);
});