// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
pub(all) struct VarRegionAxis {
start_coord : Int
peak_coord : Int
end_coord : Int
} derive(Eq, Show, ToJson)
///|
pub(all) struct VarRegionList {
axis_count : Int
region_count : Int
axes : Array[VarRegionAxis]
} derive(Eq, Show, ToJson)
///|
pub(all) struct VarData {
item_count : Int
word_count : Int
long_words : Bool
region_indices : Array[Int]
deltas : Bytes
} derive(Eq, Show, ToJson)
///|
pub struct ItemVariationStore {
region_list : VarRegionList
data_sets : Array[VarData]
} derive(Eq, Show, ToJson)
fn VarRegionAxis::evaluate(self : VarRegionAxis, coord : Int) -> Double {
let peak = self.peak_coord
if peak == 0 || coord == peak {
return 1.0
}
if coord == 0 {
return 0.0
}
let start = self.start_coord
let end = self.end_coord
if start > peak || peak > end {
return 1.0
}
if start < 0 && end > 0 && peak != 0 {
return 1.0
}
if coord <= start || end <= coord {
return 0.0
}
if coord < peak {
(coord - start).to_double() / (peak - start).to_double()
} else {
(end - coord).to_double() / (end - peak).to_double()
}
}
fn VarRegionList::evaluate(self : VarRegionList, region_index : Int, coords : ArrayView[Int]) -> Double {
if region_index < 0 || region_index >= self.region_count {
return 0.0
}
let base = region_index * self.axis_count
let mut scalar = 1.0
for axis in 0.. Int {
let count = self.region_indices.length()
(self.word_count + count) * (if self.long_words { 2 } else { 1 })
}
fn read_i8(bytes : BytesView, offset : Int) -> Result[Int, VarError] {
if offset < 0 || offset + 1 > bytes.length() {
return Err(UnexpectedEof)
}
let v = bytes[offset].to_int()
if v >= 0x80 { Ok(v - 0x100) } else { Ok(v) }
}
fn read_i16_be(bytes : BytesView, offset : Int) -> Result[Int, VarError] {
let hi = read_u16(bytes, offset)
match hi {
Err(err) => Err(err)
Ok(value) => {
let v = value.reinterpret_as_int()
if v >= 0x8000 { Ok(v - 0x10000) } else { Ok(v) }
}
}
}
fn read_i32_be(bytes : BytesView, offset : Int) -> Result[Int, VarError] {
match read_u32(bytes, offset) {
Err(err) => Err(err)
Ok(value) => Ok(value.reinterpret_as_int())
}
}
fn VarData::get_delta(
self : VarData,
inner : Int,
coords : ArrayView[Int],
regions : VarRegionList,
) -> Double {
if inner < 0 || inner >= self.item_count {
return 0.0
}
let count = self.region_indices.length()
if count == 0 {
return 0.0
}
let row_size = self.row_size()
let row_offset = inner * row_size
if row_offset < 0 || row_offset + row_size > self.deltas.length() {
return 0.0
}
let row = self.deltas[row_offset:row_offset + row_size]
let mut delta = 0.0
let mut offset = 0
if self.long_words {
for i in 0.. return delta
Ok(v) => v
}
let scalar = regions.evaluate(self.region_indices[i], coords)
if scalar != 0.0 {
delta = delta + scalar * value.to_double()
}
offset = offset + 4
}
for i in self.word_count.. return delta
Ok(v) => v
}
let scalar = regions.evaluate(self.region_indices[i], coords)
if scalar != 0.0 {
delta = delta + scalar * value.to_double()
}
offset = offset + 2
}
return delta
}
for i in 0.. return delta
Ok(v) => v
}
let scalar = regions.evaluate(self.region_indices[i], coords)
if scalar != 0.0 {
delta = delta + scalar * value.to_double()
}
offset = offset + 2
}
for i in self.word_count.. return delta
Ok(v) => v
}
let scalar = regions.evaluate(self.region_indices[i], coords)
if scalar != 0.0 {
delta = delta + scalar * value.to_double()
}
offset = offset + 1
}
delta
}
fn parse_region_list(data : BytesView, offset : Int) -> Result[VarRegionList, VarError] {
let axis_count = read_u16_int(data, offset)
let region_count = read_u16_int(data, offset + 2)
match (axis_count, region_count) {
(Err(err), _) => Err(err)
(_, Err(err)) => Err(err)
(Ok(axis_count), Ok(region_count)) => {
if axis_count < 0 || region_count < 0 {
return Err(InvalidFormat)
}
let total_axes = axis_count * region_count
let mut axis_offset = offset + 4
let axes : Array[VarRegionAxis] = []
for _ in 0.. return Err(err)
(_, Err(err), _) => return Err(err)
(_, _, Err(err)) => return Err(err)
(Ok(start_coord), Ok(peak_coord), Ok(end_coord)) => axes.push(VarRegionAxis::{
start_coord,
peak_coord,
end_coord,
})
}
axis_offset = axis_offset + 6
}
Ok(VarRegionList::{ axis_count, region_count, axes })
}
}
}
fn parse_var_data(data : BytesView, offset : Int) -> Result[VarData, VarError] {
let item_count = read_u16_int(data, offset)
let word_size_count = read_u16_int(data, offset + 2)
let region_index_count = read_u16_int(data, offset + 4)
match (item_count, word_size_count, region_index_count) {
(Err(err), _, _) => return Err(err)
(_, Err(err), _) => return Err(err)
(_, _, Err(err)) => return Err(err)
(Ok(item_count), Ok(word_size_count), Ok(region_index_count)) => {
let long_words = (word_size_count & 0x8000) != 0
let word_count = word_size_count & 0x7FFF
if region_index_count < 0 || word_count < 0 || word_count > region_index_count {
return Err(InvalidFormat)
}
let region_indices : Array[Int] = []
let mut region_offset = offset + 6
for _ in 0.. return Err(err)
Ok(v) => region_indices.push(v)
}
region_offset = region_offset + 2
}
let row_size = (word_count + region_indices.length()) * (if long_words { 2 } else { 1 })
let total_bytes = item_count * row_size
let data_offset = region_offset
if data_offset < 0 || data_offset + total_bytes > data.length() {
return Err(UnexpectedEof)
}
let deltas = data[data_offset:data_offset + total_bytes].to_bytes()
Ok(VarData::{
item_count,
word_count,
long_words,
region_indices,
deltas,
})
}
}
}
///|
pub fn ItemVariationStore::parse(data : BytesView) -> Result[ItemVariationStore, VarError] {
let format = read_u16_int(data, 0)
let region_offset = read_u32_int(data, 2)
let data_count = read_u16_int(data, 6)
match (format, region_offset, data_count) {
(Err(err), _, _) => Err(err)
(_, Err(err), _) => Err(err)
(_, _, Err(err)) => Err(err)
(Ok(format), Ok(region_offset), Ok(data_count)) => {
if format != 1 {
return Err(InvalidFormat)
}
if region_offset < 0 || region_offset >= data.length() {
return Err(UnexpectedEof)
}
let region_list = match parse_region_list(data, region_offset) {
Err(err) => return Err(err)
Ok(value) => value
}
let data_sets : Array[VarData] = []
let mut offset = 8
for _ in 0.. return Err(err)
Ok(entry_offset) => {
if entry_offset < 0 || entry_offset >= data.length() {
return Err(UnexpectedEof)
}
let var_data = match parse_var_data(data, entry_offset) {
Err(err) => return Err(err)
Ok(value) => value
}
data_sets.push(var_data)
}
}
offset = offset + 4
}
Ok(ItemVariationStore::{ region_list, data_sets })
}
}
}
///|
pub fn ItemVariationStore::get_delta(
self : ItemVariationStore,
var_idx : UInt,
coords : Array[Int],
) -> Double {
let outer = ((var_idx >> 16) & 0xFFFFU).reinterpret_as_int()
let inner = (var_idx & 0xFFFFU).reinterpret_as_int()
if outer < 0 || outer >= self.data_sets.length() {
return 0.0
}
self.data_sets[outer].get_delta(inner, coords[:], self.region_list)
}
///|
pub fn ItemVariationStore::region_count(
self : ItemVariationStore,
outer : Int,
) -> Int? {
if outer < 0 || outer >= self.data_sets.length() {
return None
}
Some(self.data_sets[outer].region_indices.length())
}
///|
pub fn ItemVariationStore::region_scalars(
self : ItemVariationStore,
outer : Int,
coords : Array[Int],
) -> Array[Double]? {
if outer < 0 || outer >= self.data_sets.length() {
return None
}
let var_data = self.data_sets[outer]
let count = var_data.region_indices.length()
let scalars : Array[Double] = Array::make(count, 0.0)
for i in 0..