-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: dzi viewer would loop forever due to some faulty math #43
Changes from 4 commits
b569d13
2e49dc7
1fbb17c
1f3c11e
f86312f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -93,7 +93,7 @@ export function getVisibleTiles(dzi: DziImage, camera: { view: box2D; screenSize | |
export function firstSuitableLayer(imageWidth: number, screenWidth: number) { | ||
const idealLayer = Math.ceil(Math.log2(screenWidth)); | ||
const biggestRealLayer = Math.ceil(Math.log2(imageWidth)); | ||
return Math.min(biggestRealLayer, idealLayer); | ||
return Math.max(0, Math.min(biggestRealLayer, idealLayer)); | ||
} | ||
|
||
/** | ||
|
@@ -121,14 +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 layerMaxSize = 2 ** layer; | ||
let total: vec2 = [size.width, size.height]; | ||
while (total[0] > layerMaxSize || total[1] > layerMaxSize) { | ||
total = Vec2.ceil(Vec2.scale(total, 1 / 2)); | ||
} | ||
return total; | ||
const { size: dim } = dzi; | ||
const layerMaxSize = 2 ** (isFinite(layer) ? Math.max(0, layer) : 0); | ||
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)); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the issue here is that the while loop below will use ceil after dividing the total by 2 - that means that if maxLayerSize was a number less than 1 (for example 2**-1 == 0.5), then the progressive dividing of total would never reach the exit condition, resulting in an infinite loop. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. using 0 as a fallback value is fine, because 2**0 = 1 |
||
} | ||
export function tilesInLayer(dzi: DziImage, layer: number): box2D[][] { | ||
const { overlap, tileSize } = dzi; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the log of numbers smaller than 1 can be negative. In many circumstances, the width passed in as what is needed could be very small, and in that case, the result would be a layer at a negative index, which of course does not exist.