76 lines
1.6 KiB
Go
76 lines
1.6 KiB
Go
package codec
|
||
|
||
// CalculateLipmaaLayerSequence calculates a set of nearest lipmaa
|
||
// layer natural indexes given the current layer, requested depth, and
|
||
// a starting set. It follows these basic math rules:
|
||
//
|
||
// Given:
|
||
// - N: N ∈ {0,1,2...}
|
||
// - l: l ∈ N
|
||
// - d: d ∈ N
|
||
// - x: I->X i|->floor(log(x))+1 = x(i)
|
||
// - s: s ⊊ {0,1,4,13,40...}
|
||
// - c: c ∈ s ∧ c = 0 ∨ (c >= 1 ∧ x(l,s))
|
||
// - v: v = (c*3)+1
|
||
func CalculateLipmaaLayerSequence(l, d uint, s []uint) []uint {
|
||
sl := uint(len(s))
|
||
// If the sequence set is empty make it equal to {0}
|
||
if sl == 0 {
|
||
s = append(s, 0) // Add the base value 0
|
||
sl++ // Increment the sequence set length counter
|
||
}
|
||
// Calculate v based on the last value in the sequence set
|
||
c := s[sl-1]
|
||
v := (c * 3) + 1
|
||
// If the length of the sequence set is less than the layer we are on
|
||
if sl < l {
|
||
l = sl // Make the layer equal to the sequence set length
|
||
s = s[:l] // Take only a valid set of sequences for the layer
|
||
}
|
||
// If the layer is equal to the requested depth
|
||
if l == d {
|
||
return s // Return the generated sequeces
|
||
}
|
||
// Expand the sequence set and layer
|
||
s = append(s, v)
|
||
l++
|
||
// Calculate the next layer
|
||
return CalculateLipmaaLayerSequence(l, d, s)
|
||
}
|
||
|
||
// lipmaaLink returns the lipmaa link index from a given index
|
||
func lipmaaLink(idx uint) uint {
|
||
if idx == 0 {
|
||
return 0
|
||
}
|
||
n := int(idx)
|
||
k, po3, x := 1, 3, n
|
||
for {
|
||
if k >= n {
|
||
break
|
||
}
|
||
po3 *= 3
|
||
k = (po3 - 1) / 2
|
||
}
|
||
po3 /= 3
|
||
if k != n {
|
||
for {
|
||
if x == 0 {
|
||
break
|
||
}
|
||
k = (po3 - 1) / 2
|
||
po3 /= 3
|
||
x %= k
|
||
}
|
||
if k != po3 {
|
||
po3 = k
|
||
}
|
||
}
|
||
return uint(n - po3)
|
||
}
|
||
|
||
func lipmaaLink2(idx uint) uint {
|
||
return idx
|
||
}
|
||
|