From 2e49dc709b0bcf0a31c144342e7f0f3193ee9d9d Mon Sep 17 00:00:00 2001 From: noah Date: Wed, 20 Nov 2024 12:30:37 -0800 Subject: [PATCH] switch to a closed form computation - it passed all the tests, what could go wrong? --- packages/dzi/src/loader.test.ts | 2 +- packages/dzi/src/loader.ts | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/dzi/src/loader.test.ts b/packages/dzi/src/loader.test.ts index 04cb0e6..09467b2 100644 --- a/packages/dzi/src/loader.test.ts +++ b/packages/dzi/src/loader.test.ts @@ -24,7 +24,7 @@ describe('tiling math', () => { const pretend_max_image_width = 512; expect(firstSuitableLayer(pretend_max_image_width, 4096)).toEqual(9); }); - it('never picks a layer that cant exist', () => { + it('never picks a layer that cant exist (negative layer indexes)', () => { expect(firstSuitableLayer(512, 0.00001)).toEqual(0); }); }); diff --git a/packages/dzi/src/loader.ts b/packages/dzi/src/loader.ts index f934d14..fd17b45 100644 --- a/packages/dzi/src/loader.ts +++ b/packages/dzi/src/loader.ts @@ -121,15 +121,23 @@ export function tileWithOverlap(total: number, step: number, overlap: number): I function boxFromRowCol(row: Interval, col: Interval) { return Box2D.create([col.min, row.min], [col.max, row.max]); } + +const logBaseHalf = (x: number) => Math.log2(x) / Math.log2(0.5); + export function imageSizeAtLayer(dzi: DziImage, layer: number) { - const { size } = dzi; + const { size: dim } = dzi; const layerMaxSize = 2 ** (isFinite(layer) ? Math.max(0, layer) : 0); - let total: vec2 = [size.width, size.height]; + const size: vec2 = [dim.width, dim.height]; + // the question is how many times do we need to divide size + // by 2 to make it less than layerMaxSize? + // solve for N, X = the larger the image dimensions: + // X * (0.5^N) <= maxLayerSize ... + // 0.5^N = maxLayerSize/X ... + // log_0.5(maxLayerSize/X) = N + const bigger = Math.max(size[0], size[1]); + const N = Math.ceil(logBaseHalf(layerMaxSize / bigger)) + return Vec2.ceil(Vec2.scale(size, 0.5 ** N)); - while (total[0] > layerMaxSize || total[1] > layerMaxSize) { - total = Vec2.ceil(Vec2.scale(total, 1 / 2)); - } - return total; } export function tilesInLayer(dzi: DziImage, layer: number): box2D[][] { const { overlap, tileSize } = dzi;