@woosh/meep-engine 3.9.0 → 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (696) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/package.json +3 -2
  4. package/src/avif/encode_image_source.d.ts +70 -0
  5. package/src/avif/encode_image_source.d.ts.map +1 -0
  6. package/src/avif/encode_image_source.js +117 -0
  7. package/src/avif/encoder_worker.js +15 -126
  8. package/src/avif/index.d.ts +4 -2
  9. package/src/avif/index.js +21 -2
  10. package/src/avif/native/DECISIONS.md +537 -0
  11. package/src/avif/native/NOTICE.md +61 -0
  12. package/src/avif/native/api/AvifDecoder.d.ts +67 -0
  13. package/src/avif/native/api/AvifDecoder.d.ts.map +1 -0
  14. package/src/avif/native/api/AvifDecoder.js +121 -0
  15. package/src/avif/native/api/apply_transformations.d.ts +30 -0
  16. package/src/avif/native/api/apply_transformations.d.ts.map +1 -0
  17. package/src/avif/native/api/apply_transformations.js +120 -0
  18. package/src/avif/native/api/avif_to_sampler2d.d.ts +25 -0
  19. package/src/avif/native/api/avif_to_sampler2d.d.ts.map +1 -0
  20. package/src/avif/native/api/avif_to_sampler2d.js +42 -0
  21. package/src/avif/native/api/convert_to_rgba.d.ts +54 -0
  22. package/src/avif/native/api/convert_to_rgba.d.ts.map +1 -0
  23. package/src/avif/native/api/convert_to_rgba.js +204 -0
  24. package/src/avif/native/api/decode_avif.d.ts +24 -0
  25. package/src/avif/native/api/decode_avif.d.ts.map +1 -0
  26. package/src/avif/native/api/decode_avif.js +111 -0
  27. package/src/avif/native/api/decode_image_item.d.ts +18 -0
  28. package/src/avif/native/api/decode_image_item.d.ts.map +1 -0
  29. package/src/avif/native/api/decode_image_item.js +234 -0
  30. package/src/avif/native/api/encode_avif.d.ts +73 -0
  31. package/src/avif/native/api/encode_avif.d.ts.map +1 -0
  32. package/src/avif/native/api/encode_avif.js +488 -0
  33. package/src/avif/native/api/sampler2d_to_avif.d.ts +22 -0
  34. package/src/avif/native/api/sampler2d_to_avif.d.ts.map +1 -0
  35. package/src/avif/native/api/sampler2d_to_avif.js +108 -0
  36. package/src/avif/native/av1/decode/Av1FrameContext.d.ts +286 -0
  37. package/src/avif/native/av1/decode/Av1FrameContext.d.ts.map +1 -0
  38. package/src/avif/native/av1/decode/Av1FrameContext.js +622 -0
  39. package/src/avif/native/av1/decode/block_decoded.d.ts +27 -0
  40. package/src/avif/native/av1/decode/block_decoded.d.ts.map +1 -0
  41. package/src/avif/native/av1/decode/block_decoded.js +59 -0
  42. package/src/avif/native/av1/decode/decode_av1_still.d.ts +22 -0
  43. package/src/avif/native/av1/decode/decode_av1_still.d.ts.map +1 -0
  44. package/src/avif/native/av1/decode/decode_av1_still.js +309 -0
  45. package/src/avif/native/av1/decode/decode_coefficients.d.ts +20 -0
  46. package/src/avif/native/av1/decode/decode_coefficients.d.ts.map +1 -0
  47. package/src/avif/native/av1/decode/decode_coefficients.js +259 -0
  48. package/src/avif/native/av1/decode/decode_palette.d.ts +28 -0
  49. package/src/avif/native/av1/decode/decode_palette.d.ts.map +1 -0
  50. package/src/avif/native/av1/decode/decode_palette.js +442 -0
  51. package/src/avif/native/av1/decode/decode_tile.d.ts +14 -0
  52. package/src/avif/native/av1/decode/decode_tile.d.ts.map +1 -0
  53. package/src/avif/native/av1/decode/decode_tile.js +1213 -0
  54. package/src/avif/native/av1/decode/get_scan.d.ts +16 -0
  55. package/src/avif/native/av1/decode/get_scan.d.ts.map +1 -0
  56. package/src/avif/native/av1/decode/get_scan.js +138 -0
  57. package/src/avif/native/av1/decode/read_lr.d.ts +35 -0
  58. package/src/avif/native/av1/decode/read_lr.d.ts.map +1 -0
  59. package/src/avif/native/av1/decode/read_lr.js +277 -0
  60. package/src/avif/native/av1/decode/read_transform_type.d.ts +19 -0
  61. package/src/avif/native/av1/decode/read_transform_type.d.ts.map +1 -0
  62. package/src/avif/native/av1/decode/read_transform_type.js +92 -0
  63. package/src/avif/native/av1/decode/reconstruct.d.ts +36 -0
  64. package/src/avif/native/av1/decode/reconstruct.d.ts.map +1 -0
  65. package/src/avif/native/av1/decode/reconstruct.js +241 -0
  66. package/src/avif/native/av1/decode/transform_type.d.ts +49 -0
  67. package/src/avif/native/av1/decode/transform_type.d.ts.map +1 -0
  68. package/src/avif/native/av1/decode/transform_type.js +137 -0
  69. package/src/avif/native/av1/encode/Av1BlockSnapshot.d.ts +81 -0
  70. package/src/avif/native/av1/encode/Av1BlockSnapshot.d.ts.map +1 -0
  71. package/src/avif/native/av1/encode/Av1BlockSnapshot.js +299 -0
  72. package/src/avif/native/av1/encode/Av1EncodeContext.d.ts +384 -0
  73. package/src/avif/native/av1/encode/Av1EncodeContext.d.ts.map +1 -0
  74. package/src/avif/native/av1/encode/Av1EncodeContext.js +590 -0
  75. package/src/avif/native/av1/encode/build_headers.d.ts +50 -0
  76. package/src/avif/native/av1/encode/build_headers.d.ts.map +1 -0
  77. package/src/avif/native/av1/encode/build_headers.js +359 -0
  78. package/src/avif/native/av1/encode/choose_chroma_alpha.d.ts +26 -0
  79. package/src/avif/native/av1/encode/choose_chroma_alpha.d.ts.map +1 -0
  80. package/src/avif/native/av1/encode/choose_chroma_alpha.js +90 -0
  81. package/src/avif/native/av1/encode/choose_filters.d.ts +21 -0
  82. package/src/avif/native/av1/encode/choose_filters.d.ts.map +1 -0
  83. package/src/avif/native/av1/encode/choose_filters.js +318 -0
  84. package/src/avif/native/av1/encode/choose_restoration.d.ts +35 -0
  85. package/src/avif/native/av1/encode/choose_restoration.d.ts.map +1 -0
  86. package/src/avif/native/av1/encode/choose_restoration.js +616 -0
  87. package/src/avif/native/av1/encode/decode_effort.d.ts +57 -0
  88. package/src/avif/native/av1/encode/decode_effort.d.ts.map +1 -0
  89. package/src/avif/native/av1/encode/decode_effort.js +59 -0
  90. package/src/avif/native/av1/encode/encode_av1_still.d.ts +17 -0
  91. package/src/avif/native/av1/encode/encode_av1_still.d.ts.map +1 -0
  92. package/src/avif/native/av1/encode/encode_av1_still.js +194 -0
  93. package/src/avif/native/av1/encode/encode_effort.d.ts +56 -0
  94. package/src/avif/native/av1/encode/encode_effort.d.ts.map +1 -0
  95. package/src/avif/native/av1/encode/encode_effort.js +97 -0
  96. package/src/avif/native/av1/encode/encode_tile.d.ts +26 -0
  97. package/src/avif/native/av1/encode/encode_tile.d.ts.map +1 -0
  98. package/src/avif/native/av1/encode/encode_tile.js +2331 -0
  99. package/src/avif/native/av1/encode/quantise.d.ts +51 -0
  100. package/src/avif/native/av1/encode/quantise.d.ts.map +1 -0
  101. package/src/avif/native/av1/encode/quantise.js +212 -0
  102. package/src/avif/native/av1/encode/write_coefficients.d.ts +42 -0
  103. package/src/avif/native/av1/encode/write_coefficients.d.ts.map +1 -0
  104. package/src/avif/native/av1/encode/write_coefficients.js +367 -0
  105. package/src/avif/native/av1/encode/write_lr.d.ts +33 -0
  106. package/src/avif/native/av1/encode/write_lr.d.ts.map +1 -0
  107. package/src/avif/native/av1/encode/write_lr.js +174 -0
  108. package/src/avif/native/av1/encode/write_transform_type.d.ts +21 -0
  109. package/src/avif/native/av1/encode/write_transform_type.d.ts.map +1 -0
  110. package/src/avif/native/av1/encode/write_transform_type.js +70 -0
  111. package/src/avif/native/av1/entropy/CdfContext.d.ts +167 -0
  112. package/src/avif/native/av1/entropy/CdfContext.d.ts.map +1 -0
  113. package/src/avif/native/av1/entropy/CdfContext.js +433 -0
  114. package/src/avif/native/av1/entropy/SymbolReader.d.ts +103 -0
  115. package/src/avif/native/av1/entropy/SymbolReader.d.ts.map +1 -0
  116. package/src/avif/native/av1/entropy/SymbolReader.js +317 -0
  117. package/src/avif/native/av1/entropy/SymbolWriter.d.ts +107 -0
  118. package/src/avif/native/av1/entropy/SymbolWriter.d.ts.map +1 -0
  119. package/src/avif/native/av1/entropy/SymbolWriter.js +352 -0
  120. package/src/avif/native/av1/entropy/coefficient_context.d.ts +71 -0
  121. package/src/avif/native/av1/entropy/coefficient_context.d.ts.map +1 -0
  122. package/src/avif/native/av1/entropy/coefficient_context.js +325 -0
  123. package/src/avif/native/av1/entropy/partition_cdf.d.ts +54 -0
  124. package/src/avif/native/av1/entropy/partition_cdf.d.ts.map +1 -0
  125. package/src/avif/native/av1/entropy/partition_cdf.js +98 -0
  126. package/src/avif/native/av1/entropy/symbol_cost.d.ts +37 -0
  127. package/src/avif/native/av1/entropy/symbol_cost.d.ts.map +1 -0
  128. package/src/avif/native/av1/entropy/symbol_cost.js +76 -0
  129. package/src/avif/native/av1/filter/cdef.d.ts +15 -0
  130. package/src/avif/native/av1/filter/cdef.d.ts.map +1 -0
  131. package/src/avif/native/av1/filter/cdef.js +313 -0
  132. package/src/avif/native/av1/filter/loop_filter.d.ts +14 -0
  133. package/src/avif/native/av1/filter/loop_filter.d.ts.map +1 -0
  134. package/src/avif/native/av1/filter/loop_filter.js +377 -0
  135. package/src/avif/native/av1/filter/loop_restoration.d.ts +42 -0
  136. package/src/avif/native/av1/filter/loop_restoration.d.ts.map +1 -0
  137. package/src/avif/native/av1/filter/loop_restoration.js +451 -0
  138. package/src/avif/native/av1/filter/superres.d.ts +18 -0
  139. package/src/avif/native/av1/filter/superres.d.ts.map +1 -0
  140. package/src/avif/native/av1/filter/superres.js +86 -0
  141. package/src/avif/native/av1/grain/FilmGrainState.d.ts +62 -0
  142. package/src/avif/native/av1/grain/FilmGrainState.d.ts.map +1 -0
  143. package/src/avif/native/av1/grain/FilmGrainState.js +87 -0
  144. package/src/avif/native/av1/grain/film_grain.d.ts +16 -0
  145. package/src/avif/native/av1/grain/film_grain.d.ts.map +1 -0
  146. package/src/avif/native/av1/grain/film_grain.js +623 -0
  147. package/src/avif/native/av1/obu/FrameHeader.d.ts +248 -0
  148. package/src/avif/native/av1/obu/FrameHeader.d.ts.map +1 -0
  149. package/src/avif/native/av1/obu/FrameHeader.js +381 -0
  150. package/src/avif/native/av1/obu/ObuHeader.d.ts +53 -0
  151. package/src/avif/native/av1/obu/ObuHeader.d.ts.map +1 -0
  152. package/src/avif/native/av1/obu/ObuHeader.js +62 -0
  153. package/src/avif/native/av1/obu/SequenceHeader.d.ts +157 -0
  154. package/src/avif/native/av1/obu/SequenceHeader.d.ts.map +1 -0
  155. package/src/avif/native/av1/obu/SequenceHeader.js +225 -0
  156. package/src/avif/native/av1/obu/for_each_obu.d.ts +24 -0
  157. package/src/avif/native/av1/obu/for_each_obu.d.ts.map +1 -0
  158. package/src/avif/native/av1/obu/for_each_obu.js +50 -0
  159. package/src/avif/native/av1/obu/parse_frame_header.d.ts +18 -0
  160. package/src/avif/native/av1/obu/parse_frame_header.d.ts.map +1 -0
  161. package/src/avif/native/av1/obu/parse_frame_header.js +841 -0
  162. package/src/avif/native/av1/obu/parse_obu_header.d.ts +23 -0
  163. package/src/avif/native/av1/obu/parse_obu_header.d.ts.map +1 -0
  164. package/src/avif/native/av1/obu/parse_obu_header.js +69 -0
  165. package/src/avif/native/av1/obu/parse_sequence_header.d.ts +17 -0
  166. package/src/avif/native/av1/obu/parse_sequence_header.d.ts.map +1 -0
  167. package/src/avif/native/av1/obu/parse_sequence_header.js +263 -0
  168. package/src/avif/native/av1/obu/write_frame_header.d.ts +16 -0
  169. package/src/avif/native/av1/obu/write_frame_header.d.ts.map +1 -0
  170. package/src/avif/native/av1/obu/write_frame_header.js +579 -0
  171. package/src/avif/native/av1/obu/write_sequence_header.d.ts +17 -0
  172. package/src/avif/native/av1/obu/write_sequence_header.d.ts.map +1 -0
  173. package/src/avif/native/av1/obu/write_sequence_header.js +189 -0
  174. package/src/avif/native/av1/predict/IntraPredictionState.d.ts +49 -0
  175. package/src/avif/native/av1/predict/IntraPredictionState.d.ts.map +1 -0
  176. package/src/avif/native/av1/predict/IntraPredictionState.js +58 -0
  177. package/src/avif/native/av1/predict/intra_filter_type.d.ts +17 -0
  178. package/src/avif/native/av1/predict/intra_filter_type.d.ts.map +1 -0
  179. package/src/avif/native/av1/predict/intra_filter_type.js +79 -0
  180. package/src/avif/native/av1/predict/predict_chroma_from_luma.d.ts +50 -0
  181. package/src/avif/native/av1/predict/predict_chroma_from_luma.d.ts.map +1 -0
  182. package/src/avif/native/av1/predict/predict_chroma_from_luma.js +153 -0
  183. package/src/avif/native/av1/predict/predict_intra.d.ts +42 -0
  184. package/src/avif/native/av1/predict/predict_intra.d.ts.map +1 -0
  185. package/src/avif/native/av1/predict/predict_intra.js +803 -0
  186. package/src/avif/native/av1/predict/predict_palette.d.ts +23 -0
  187. package/src/avif/native/av1/predict/predict_palette.d.ts.map +1 -0
  188. package/src/avif/native/av1/predict/predict_palette.js +36 -0
  189. package/src/avif/native/av1/tables/av1_symbols.d.ts +411 -0
  190. package/src/avif/native/av1/tables/av1_symbols.d.ts.map +1 -0
  191. package/src/avif/native/av1/tables/av1_symbols.js +419 -0
  192. package/src/avif/native/av1/tables/block_tables.d.ts +181 -0
  193. package/src/avif/native/av1/tables/block_tables.d.ts.map +1 -0
  194. package/src/avif/native/av1/tables/block_tables.js +270 -0
  195. package/src/avif/native/av1/tables/cdf_tables.d.ts +961 -0
  196. package/src/avif/native/av1/tables/cdf_tables.d.ts.map +1 -0
  197. package/src/avif/native/av1/tables/cdf_tables.js +1893 -0
  198. package/src/avif/native/av1/tables/coefficient_tables.d.ts +41 -0
  199. package/src/avif/native/av1/tables/coefficient_tables.d.ts.map +1 -0
  200. package/src/avif/native/av1/tables/coefficient_tables.js +82 -0
  201. package/src/avif/native/av1/tables/derived_block_tables.d.ts +15 -0
  202. package/src/avif/native/av1/tables/derived_block_tables.d.ts.map +1 -0
  203. package/src/avif/native/av1/tables/derived_block_tables.js +23 -0
  204. package/src/avif/native/av1/tables/filter_tables.d.ts +171 -0
  205. package/src/avif/native/av1/tables/filter_tables.d.ts.map +1 -0
  206. package/src/avif/native/av1/tables/filter_tables.js +313 -0
  207. package/src/avif/native/av1/tables/grain_tables.d.ts +11 -0
  208. package/src/avif/native/av1/tables/grain_tables.d.ts.map +1 -0
  209. package/src/avif/native/av1/tables/grain_tables.js +190 -0
  210. package/src/avif/native/av1/tables/prediction_tables.d.ts +141 -0
  211. package/src/avif/native/av1/tables/prediction_tables.d.ts.map +1 -0
  212. package/src/avif/native/av1/tables/prediction_tables.js +223 -0
  213. package/src/avif/native/av1/tables/quantizer_matrix_tables.d.ts +21 -0
  214. package/src/avif/native/av1/tables/quantizer_matrix_tables.d.ts.map +1 -0
  215. package/src/avif/native/av1/tables/quantizer_matrix_tables.js +38 -0
  216. package/src/avif/native/av1/tables/quantizer_tables.d.ts +21 -0
  217. package/src/avif/native/av1/tables/quantizer_tables.d.ts.map +1 -0
  218. package/src/avif/native/av1/tables/quantizer_tables.js +160 -0
  219. package/src/avif/native/av1/tables/scan_tables.d.ts +321 -0
  220. package/src/avif/native/av1/tables/scan_tables.d.ts.map +1 -0
  221. package/src/avif/native/av1/tables/scan_tables.js +727 -0
  222. package/src/avif/native/av1/tables/segmentation_tables.d.ts +31 -0
  223. package/src/avif/native/av1/tables/segmentation_tables.d.ts.map +1 -0
  224. package/src/avif/native/av1/tables/segmentation_tables.js +48 -0
  225. package/src/avif/native/av1/tables/transform_tables.d.ts +91 -0
  226. package/src/avif/native/av1/tables/transform_tables.d.ts.map +1 -0
  227. package/src/avif/native/av1/tables/transform_tables.js +140 -0
  228. package/src/avif/native/av1/tables/unpack_table.d.ts +33 -0
  229. package/src/avif/native/av1/tables/unpack_table.d.ts.map +1 -0
  230. package/src/avif/native/av1/tables/unpack_table.js +73 -0
  231. package/src/avif/native/av1/transform/forward_transform_2d.d.ts +61 -0
  232. package/src/avif/native/av1/transform/forward_transform_2d.d.ts.map +1 -0
  233. package/src/avif/native/av1/transform/forward_transform_2d.js +574 -0
  234. package/src/avif/native/av1/transform/inverse_transform_1d.d.ts +76 -0
  235. package/src/avif/native/av1/transform/inverse_transform_1d.d.ts.map +1 -0
  236. package/src/avif/native/av1/transform/inverse_transform_1d.js +590 -0
  237. package/src/avif/native/av1/transform/inverse_transform_2d.d.ts +46 -0
  238. package/src/avif/native/av1/transform/inverse_transform_2d.d.ts.map +1 -0
  239. package/src/avif/native/av1/transform/inverse_transform_2d.js +180 -0
  240. package/src/avif/native/av1/util/ceil_log2.d.ts +13 -0
  241. package/src/avif/native/av1/util/ceil_log2.d.ts.map +1 -0
  242. package/src/avif/native/av1/util/ceil_log2.js +18 -0
  243. package/src/avif/native/av1/util/floor_log2.d.ts +20 -0
  244. package/src/avif/native/av1/util/floor_log2.d.ts.map +1 -0
  245. package/src/avif/native/av1/util/floor_log2.js +20 -0
  246. package/src/avif/native/av1/util/round2.d.ts +22 -0
  247. package/src/avif/native/av1/util/round2.d.ts.map +1 -0
  248. package/src/avif/native/av1/util/round2.js +27 -0
  249. package/src/avif/native/av1/util/round2_signed.d.ts +14 -0
  250. package/src/avif/native/av1/util/round2_signed.d.ts.map +1 -0
  251. package/src/avif/native/av1/util/round2_signed.js +17 -0
  252. package/src/avif/native/av1/util/tile_log2.d.ts +16 -0
  253. package/src/avif/native/av1/util/tile_log2.d.ts.map +1 -0
  254. package/src/avif/native/av1/util/tile_log2.js +23 -0
  255. package/src/avif/native/bitstream/BitReader.d.ts +174 -0
  256. package/src/avif/native/bitstream/BitReader.d.ts.map +1 -0
  257. package/src/avif/native/bitstream/BitReader.js +391 -0
  258. package/src/avif/native/bitstream/BitWriter.d.ts +122 -0
  259. package/src/avif/native/bitstream/BitWriter.d.ts.map +1 -0
  260. package/src/avif/native/bitstream/BitWriter.js +351 -0
  261. package/src/avif/native/color/ColourTransform.d.ts +62 -0
  262. package/src/avif/native/color/ColourTransform.d.ts.map +1 -0
  263. package/src/avif/native/color/ColourTransform.js +189 -0
  264. package/src/avif/native/color/YuvImage.d.ts +51 -0
  265. package/src/avif/native/color/YuvImage.d.ts.map +1 -0
  266. package/src/avif/native/color/YuvImage.js +66 -0
  267. package/src/avif/native/color/clamp_sample.d.ts +18 -0
  268. package/src/avif/native/color/clamp_sample.d.ts.map +1 -0
  269. package/src/avif/native/color/clamp_sample.js +25 -0
  270. package/src/avif/native/color/linear_to_transfer.d.ts +24 -0
  271. package/src/avif/native/color/linear_to_transfer.d.ts.map +1 -0
  272. package/src/avif/native/color/linear_to_transfer.js +126 -0
  273. package/src/avif/native/color/primaries.d.ts +20 -0
  274. package/src/avif/native/color/primaries.d.ts.map +1 -0
  275. package/src/avif/native/color/primaries.js +94 -0
  276. package/src/avif/native/color/rgb_row_to_ycbcr.d.ts +20 -0
  277. package/src/avif/native/color/rgb_row_to_ycbcr.d.ts.map +1 -0
  278. package/src/avif/native/color/rgb_row_to_ycbcr.js +78 -0
  279. package/src/avif/native/color/transfer_to_linear.d.ts +49 -0
  280. package/src/avif/native/color/transfer_to_linear.d.ts.map +1 -0
  281. package/src/avif/native/color/transfer_to_linear.js +171 -0
  282. package/src/avif/native/color/upsample_chroma_row.d.ts +35 -0
  283. package/src/avif/native/color/upsample_chroma_row.d.ts.map +1 -0
  284. package/src/avif/native/color/upsample_chroma_row.js +89 -0
  285. package/src/avif/native/color/ycbcr_row_to_rgb.d.ts +23 -0
  286. package/src/avif/native/color/ycbcr_row_to_rgb.d.ts.map +1 -0
  287. package/src/avif/native/color/ycbcr_row_to_rgb.js +78 -0
  288. package/src/avif/native/heif/AvifFile.d.ts +112 -0
  289. package/src/avif/native/heif/AvifFile.d.ts.map +1 -0
  290. package/src/avif/native/heif/AvifFile.js +142 -0
  291. package/src/avif/native/heif/ItemProperty.d.ts +244 -0
  292. package/src/avif/native/heif/ItemProperty.d.ts.map +1 -0
  293. package/src/avif/native/heif/ItemProperty.js +321 -0
  294. package/src/avif/native/heif/find_item_property.d.ts +17 -0
  295. package/src/avif/native/heif/find_item_property.d.ts.map +1 -0
  296. package/src/avif/native/heif/find_item_property.js +28 -0
  297. package/src/avif/native/heif/find_item_references.d.ts +16 -0
  298. package/src/avif/native/heif/find_item_references.d.ts.map +1 -0
  299. package/src/avif/native/heif/find_item_references.js +29 -0
  300. package/src/avif/native/heif/find_items_referencing.d.ts +17 -0
  301. package/src/avif/native/heif/find_items_referencing.d.ts.map +1 -0
  302. package/src/avif/native/heif/find_items_referencing.js +36 -0
  303. package/src/avif/native/heif/parse_avif_file.d.ts +15 -0
  304. package/src/avif/native/heif/parse_avif_file.d.ts.map +1 -0
  305. package/src/avif/native/heif/parse_avif_file.js +383 -0
  306. package/src/avif/native/heif/parse_image_grid.d.ts +18 -0
  307. package/src/avif/native/heif/parse_image_grid.d.ts.map +1 -0
  308. package/src/avif/native/heif/parse_image_grid.js +48 -0
  309. package/src/avif/native/heif/parse_item_property.d.ts +18 -0
  310. package/src/avif/native/heif/parse_item_property.d.ts.map +1 -0
  311. package/src/avif/native/heif/parse_item_property.js +243 -0
  312. package/src/avif/native/heif/read_item_data.d.ts +22 -0
  313. package/src/avif/native/heif/read_item_data.d.ts.map +1 -0
  314. package/src/avif/native/heif/read_item_data.js +97 -0
  315. package/src/avif/native/heif/write_avif_file.d.ts +50 -0
  316. package/src/avif/native/heif/write_avif_file.d.ts.map +1 -0
  317. package/src/avif/native/heif/write_avif_file.js +348 -0
  318. package/src/avif/native/heif/write_item_property.d.ts +16 -0
  319. package/src/avif/native/heif/write_item_property.d.ts.map +1 -0
  320. package/src/avif/native/heif/write_item_property.js +182 -0
  321. package/src/avif/native/index.d.ts +14 -0
  322. package/src/avif/native/index.d.ts.map +1 -0
  323. package/src/avif/native/index.js +56 -0
  324. package/src/avif/native/isobmff/BoxHeader.d.ts +50 -0
  325. package/src/avif/native/isobmff/BoxHeader.d.ts.map +1 -0
  326. package/src/avif/native/isobmff/BoxHeader.js +57 -0
  327. package/src/avif/native/isobmff/BoxWriter.d.ts +118 -0
  328. package/src/avif/native/isobmff/BoxWriter.d.ts.map +1 -0
  329. package/src/avif/native/isobmff/BoxWriter.js +264 -0
  330. package/src/avif/native/isobmff/ByteCursor.d.ts +125 -0
  331. package/src/avif/native/isobmff/ByteCursor.d.ts.map +1 -0
  332. package/src/avif/native/isobmff/ByteCursor.js +298 -0
  333. package/src/avif/native/isobmff/for_each_box.d.ts +23 -0
  334. package/src/avif/native/isobmff/for_each_box.d.ts.map +1 -0
  335. package/src/avif/native/isobmff/for_each_box.js +39 -0
  336. package/src/avif/native/isobmff/read_box_header.d.ts +22 -0
  337. package/src/avif/native/isobmff/read_box_header.d.ts.map +1 -0
  338. package/src/avif/native/isobmff/read_box_header.js +59 -0
  339. package/src/avif/native/isobmff/read_full_box_header.d.ts +26 -0
  340. package/src/avif/native/isobmff/read_full_box_header.d.ts.map +1 -0
  341. package/src/avif/native/isobmff/read_full_box_header.js +33 -0
  342. package/src/avif/threaded_image_encoder.d.ts +7 -2
  343. package/src/avif/threaded_image_encoder.d.ts.map +1 -1
  344. package/src/avif/threaded_image_encoder.js +107 -21
  345. package/src/core/binary/BinaryBuffer.d.ts +40 -0
  346. package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
  347. package/src/core/binary/BinaryBuffer.js +100 -0
  348. package/src/core/binary/hash/crc32.d.ts +16 -0
  349. package/src/core/binary/hash/crc32.d.ts.map +1 -0
  350. package/src/core/binary/hash/crc32.js +96 -0
  351. package/src/core/binary/utf8/utf8_decode.d.ts +21 -0
  352. package/src/core/binary/utf8/utf8_decode.d.ts.map +1 -0
  353. package/src/core/binary/utf8/utf8_decode.js +43 -0
  354. package/src/core/binary/utf8/utf8_encode_into.d.ts +20 -0
  355. package/src/core/binary/utf8/utf8_encode_into.d.ts.map +1 -0
  356. package/src/core/binary/utf8/utf8_encode_into.js +48 -0
  357. package/src/core/binary/utf8/utf8_encoded_length.d.ts +14 -0
  358. package/src/core/binary/utf8/utf8_encoded_length.d.ts.map +1 -0
  359. package/src/core/binary/utf8/utf8_encoded_length.js +36 -0
  360. package/src/core/color/COLOR_FIX_PLAN_2026_08_28.md +417 -0
  361. package/src/core/color/COLOR_REVIEW_2026_08_28.md +779 -0
  362. package/src/core/color/Color.d.ts +128 -20
  363. package/src/core/color/Color.d.ts.map +1 -1
  364. package/src/core/color/Color.js +959 -866
  365. package/src/core/color/PQ/PQ_constants.d.ts +10 -0
  366. package/src/core/color/PQ/PQ_constants.d.ts.map +1 -1
  367. package/src/core/color/PQ/PQ_constants.js +10 -0
  368. package/src/core/color/PQ/linear_to_PQ.d.ts.map +1 -1
  369. package/src/core/color/PQ/linear_to_PQ.js +6 -0
  370. package/src/core/color/REC709_PRIMARIES.d.ts +50 -0
  371. package/src/core/color/REC709_PRIMARIES.d.ts.map +1 -0
  372. package/src/core/color/REC709_PRIMARIES.js +53 -0
  373. package/src/core/color/construct/color_from_hex.d.ts +21 -0
  374. package/src/core/color/construct/color_from_hex.d.ts.map +1 -0
  375. package/src/core/color/construct/color_from_hex.js +33 -0
  376. package/src/core/color/construct/color_from_temperature.d.ts +22 -0
  377. package/src/core/color/construct/color_from_temperature.d.ts.map +1 -0
  378. package/src/core/color/construct/color_from_temperature.js +33 -0
  379. package/src/core/color/construct/color_from_uint24.d.ts +19 -0
  380. package/src/core/color/construct/color_from_uint24.d.ts.map +1 -0
  381. package/src/core/color/construct/color_from_uint24.js +26 -0
  382. package/src/core/color/construct/color_from_uint32.d.ts +20 -0
  383. package/src/core/color/construct/color_from_uint32.d.ts.map +1 -0
  384. package/src/core/color/construct/color_from_uint32.js +39 -0
  385. package/src/core/color/construct/color_gray.d.ts +17 -0
  386. package/src/core/color/construct/color_gray.d.ts.map +1 -0
  387. package/src/core/color/construct/color_gray.js +22 -0
  388. package/src/core/color/hex/hex2rgb.d.ts +1 -11
  389. package/src/core/color/hex/hex2rgb.d.ts.map +1 -1
  390. package/src/core/color/hex/hex2rgb.js +7 -24
  391. package/src/core/color/hex/hex_to_rgb.d.ts +18 -0
  392. package/src/core/color/hex/hex_to_rgb.d.ts.map +1 -0
  393. package/src/core/color/hex/hex_to_rgb.js +62 -0
  394. package/src/core/color/hex/rgb2hex.d.ts +1 -8
  395. package/src/core/color/hex/rgb2hex.d.ts.map +1 -1
  396. package/src/core/color/hex/rgb2hex.js +7 -13
  397. package/src/core/color/hex/rgb_to_hex.d.ts +9 -0
  398. package/src/core/color/hex/rgb_to_hex.d.ts.map +1 -0
  399. package/src/core/color/hex/rgb_to_hex.js +13 -0
  400. package/src/core/color/hex/rgba_to_hex.d.ts +19 -0
  401. package/src/core/color/hex/rgba_to_hex.d.ts.map +1 -0
  402. package/src/core/color/hex/rgba_to_hex.js +23 -0
  403. package/src/core/color/hsv/hsv2rgb.d.ts +1 -12
  404. package/src/core/color/hsv/hsv2rgb.d.ts.map +1 -1
  405. package/src/core/color/hsv/hsv2rgb.js +8 -21
  406. package/src/core/color/hsv/hsv2rgb_float.d.ts +1 -12
  407. package/src/core/color/hsv/hsv2rgb_float.d.ts.map +1 -1
  408. package/src/core/color/hsv/hsv2rgb_float.js +8 -56
  409. package/src/core/color/hsv/hsv_to_rgb.d.ts +13 -0
  410. package/src/core/color/hsv/hsv_to_rgb.d.ts.map +1 -0
  411. package/src/core/color/hsv/hsv_to_rgb.js +39 -0
  412. package/src/core/color/hsv/hsv_to_rgb_uint8.d.ts +13 -0
  413. package/src/core/color/hsv/hsv_to_rgb_uint8.d.ts.map +1 -0
  414. package/src/core/color/hsv/hsv_to_rgb_uint8.js +21 -0
  415. package/src/core/color/hsv/hue_to_rgb_sextant.d.ts +24 -0
  416. package/src/core/color/hsv/hue_to_rgb_sextant.d.ts.map +1 -0
  417. package/src/core/color/hsv/hue_to_rgb_sextant.js +67 -0
  418. package/src/core/color/hsv/rgb2hsv.d.ts +1 -12
  419. package/src/core/color/hsv/rgb2hsv.d.ts.map +1 -1
  420. package/src/core/color/hsv/rgb2hsv.js +7 -42
  421. package/src/core/color/hsv/rgb_to_hsv.d.ts +13 -0
  422. package/src/core/color/hsv/rgb_to_hsv.d.ts.map +1 -0
  423. package/src/core/color/hsv/rgb_to_hsv.js +42 -0
  424. package/src/core/color/hunt/hpe_to_xyz.d.ts +2 -0
  425. package/src/core/color/hunt/hpe_to_xyz.d.ts.map +1 -0
  426. package/src/core/color/hunt/hpe_to_xyz.js +4 -0
  427. package/src/core/color/hunt/xyz_to_hpe.d.ts +1 -6
  428. package/src/core/color/hunt/xyz_to_hpe.d.ts.map +1 -1
  429. package/src/core/color/hunt/xyz_to_hpe.js +12 -15
  430. package/src/core/color/illuminant/D65_spd_tabulated.d.ts.map +1 -1
  431. package/src/core/color/illuminant/D65_spd_tabulated.js +107 -104
  432. package/src/core/color/int2rgb.d.ts +1 -10
  433. package/src/core/color/int2rgb.d.ts.map +1 -1
  434. package/src/core/color/int2rgb.js +7 -12
  435. package/src/core/color/int_to_rgb.d.ts +21 -0
  436. package/src/core/color/int_to_rgb.d.ts.map +1 -0
  437. package/src/core/color/int_to_rgb.js +33 -0
  438. package/src/core/color/kelvin/kelvin_to_rgb.d.ts.map +1 -1
  439. package/src/core/color/kelvin/kelvin_to_rgb.js +22 -2
  440. package/src/core/color/kelvin/rgb_to_kelvin.d.ts +22 -2
  441. package/src/core/color/kelvin/rgb_to_kelvin.d.ts.map +1 -1
  442. package/src/core/color/kelvin/rgb_to_kelvin.js +22 -2
  443. package/src/core/color/lab/lab_to_xyz.d.ts +20 -0
  444. package/src/core/color/lab/lab_to_xyz.d.ts.map +1 -0
  445. package/src/core/color/lab/lab_to_xyz.js +69 -0
  446. package/src/core/color/oklab/gamut_clip_adaptive_l0.d.ts +34 -0
  447. package/src/core/color/oklab/gamut_clip_adaptive_l0.d.ts.map +1 -0
  448. package/src/core/color/oklab/gamut_clip_adaptive_l0.js +46 -0
  449. package/src/core/color/oklab/gamut_clip_at_l0.d.ts +33 -0
  450. package/src/core/color/oklab/gamut_clip_at_l0.d.ts.map +1 -0
  451. package/src/core/color/oklab/gamut_clip_at_l0.js +84 -0
  452. package/src/core/color/oklab/gamut_clip_preserve_chroma.d.ts +24 -0
  453. package/src/core/color/oklab/gamut_clip_preserve_chroma.d.ts.map +1 -0
  454. package/src/core/color/oklab/gamut_clip_preserve_chroma.js +37 -0
  455. package/src/core/color/oklab/gamut_clip_project_to_lcusp.d.ts +23 -0
  456. package/src/core/color/oklab/gamut_clip_project_to_lcusp.d.ts.map +1 -0
  457. package/src/core/color/oklab/gamut_clip_project_to_lcusp.js +46 -0
  458. package/src/core/color/oklab/linear_srgb_to_okhsl.d.ts +19 -0
  459. package/src/core/color/oklab/linear_srgb_to_okhsl.d.ts.map +1 -0
  460. package/src/core/color/oklab/linear_srgb_to_okhsl.js +93 -0
  461. package/src/core/color/oklab/linear_srgb_to_okhsv.d.ts +12 -4
  462. package/src/core/color/oklab/linear_srgb_to_okhsv.d.ts.map +1 -1
  463. package/src/core/color/oklab/linear_srgb_to_okhsv.js +108 -84
  464. package/src/core/color/oklab/linear_srgb_to_oklab.d.ts +13 -4
  465. package/src/core/color/oklab/linear_srgb_to_oklab.d.ts.map +1 -1
  466. package/src/core/color/oklab/linear_srgb_to_oklab.js +28 -19
  467. package/src/core/color/oklab/okhsl_chroma_bounds.d.ts +51 -0
  468. package/src/core/color/oklab/okhsl_chroma_bounds.d.ts.map +1 -0
  469. package/src/core/color/oklab/okhsl_chroma_bounds.js +128 -0
  470. package/src/core/color/oklab/okhsl_to_linear_srgb.d.ts +19 -0
  471. package/src/core/color/oklab/okhsl_to_linear_srgb.d.ts.map +1 -0
  472. package/src/core/color/oklab/okhsl_to_linear_srgb.js +85 -0
  473. package/src/core/color/oklab/oklab_to_oklch.d.ts +24 -0
  474. package/src/core/color/oklab/oklab_to_oklch.d.ts.map +1 -0
  475. package/src/core/color/oklab/oklab_to_oklch.js +35 -0
  476. package/src/core/color/oklab/oklch_to_oklab.d.ts +18 -0
  477. package/src/core/color/oklab/oklch_to_oklab.d.ts.map +1 -0
  478. package/src/core/color/oklab/oklch_to_oklab.js +26 -0
  479. package/src/core/color/oklab/toe.d.ts +12 -0
  480. package/src/core/color/oklab/toe.d.ts.map +1 -1
  481. package/src/core/color/oklab/toe.js +34 -22
  482. package/src/core/color/operations/color_add.d.ts +21 -0
  483. package/src/core/color/operations/color_add.d.ts.map +1 -0
  484. package/src/core/color/operations/color_add.js +23 -0
  485. package/src/core/color/operations/color_add_scaled.d.ts +20 -0
  486. package/src/core/color/operations/color_add_scaled.d.ts.map +1 -0
  487. package/src/core/color/operations/color_add_scaled.js +30 -0
  488. package/src/core/color/operations/color_clamp.d.ts +22 -0
  489. package/src/core/color/operations/color_clamp.d.ts.map +1 -0
  490. package/src/core/color/operations/color_clamp.js +25 -0
  491. package/src/core/color/operations/color_darken.d.ts +2 -1
  492. package/src/core/color/operations/color_darken.d.ts.map +1 -1
  493. package/src/core/color/operations/color_darken.js +25 -24
  494. package/src/core/color/operations/color_desaturate.d.ts +2 -1
  495. package/src/core/color/operations/color_desaturate.d.ts.map +1 -1
  496. package/src/core/color/operations/color_desaturate.js +25 -24
  497. package/src/core/color/operations/color_get_hsl.d.ts +18 -0
  498. package/src/core/color/operations/color_get_hsl.d.ts.map +1 -0
  499. package/src/core/color/operations/color_get_hsl.js +60 -0
  500. package/src/core/color/operations/color_is_in_gamut.d.ts +20 -0
  501. package/src/core/color/operations/color_is_in_gamut.d.ts.map +1 -0
  502. package/src/core/color/operations/color_is_in_gamut.js +30 -0
  503. package/src/core/color/operations/color_lerp.d.ts +12 -3
  504. package/src/core/color/operations/color_lerp.d.ts.map +1 -1
  505. package/src/core/color/operations/color_lerp.js +55 -46
  506. package/src/core/color/operations/color_lighten.d.ts +9 -5
  507. package/src/core/color/operations/color_lighten.d.ts.map +1 -1
  508. package/src/core/color/operations/color_lighten.js +29 -24
  509. package/src/core/color/operations/color_mix_okhsv_channel.d.ts +24 -0
  510. package/src/core/color/operations/color_mix_okhsv_channel.d.ts.map +1 -0
  511. package/src/core/color/operations/color_mix_okhsv_channel.js +48 -0
  512. package/src/core/color/operations/color_multiply_rgb.d.ts +21 -0
  513. package/src/core/color/operations/color_multiply_rgb.d.ts.map +1 -0
  514. package/src/core/color/operations/color_multiply_rgb.js +26 -0
  515. package/src/core/color/operations/color_saturate.d.ts +9 -5
  516. package/src/core/color/operations/color_saturate.d.ts.map +1 -1
  517. package/src/core/color/operations/color_saturate.js +29 -24
  518. package/src/core/color/operations/color_scale_okhsv_channel.d.ts +1 -1
  519. package/src/core/color/operations/color_scale_okhsv_channel.d.ts.map +1 -1
  520. package/src/core/color/operations/color_scale_okhsv_channel.js +58 -45
  521. package/src/core/color/operations/color_srgb_apply.d.ts +28 -0
  522. package/src/core/color/operations/color_srgb_apply.d.ts.map +1 -0
  523. package/src/core/color/operations/color_srgb_apply.js +40 -0
  524. package/src/core/color/operations/color_sub.d.ts +16 -0
  525. package/src/core/color/operations/color_sub.d.ts.map +1 -0
  526. package/src/core/color/operations/color_sub.js +18 -0
  527. package/src/core/color/parse_color.d.ts +10 -1
  528. package/src/core/color/parse_color.d.ts.map +1 -1
  529. package/src/core/color/parse_color.js +100 -84
  530. package/src/core/color/parse_color_normalized.d.ts +24 -0
  531. package/src/core/color/parse_color_normalized.d.ts.map +1 -0
  532. package/src/core/color/parse_color_normalized.js +38 -0
  533. package/src/core/color/rgb2uint24.d.ts +1 -8
  534. package/src/core/color/rgb2uint24.d.ts.map +1 -1
  535. package/src/core/color/rgb2uint24.js +7 -20
  536. package/src/core/color/rgb2uint32.d.ts +1 -9
  537. package/src/core/color/rgb2uint32.d.ts.map +1 -1
  538. package/src/core/color/rgb2uint32.js +7 -18
  539. package/src/core/color/rgb_to_luminance.d.ts +14 -5
  540. package/src/core/color/rgb_to_luminance.d.ts.map +1 -1
  541. package/src/core/color/rgb_to_luminance.js +24 -13
  542. package/src/core/color/rgb_to_uint24.d.ts +9 -0
  543. package/src/core/color/rgb_to_uint24.d.ts.map +1 -0
  544. package/src/core/color/rgb_to_uint24.js +20 -0
  545. package/src/core/color/rgb_to_uint32.d.ts +10 -0
  546. package/src/core/color/rgb_to_uint32.d.ts.map +1 -0
  547. package/src/core/color/rgb_to_uint32.js +21 -0
  548. package/src/core/color/sRGB/linear_to_sRGB.d.ts +7 -0
  549. package/src/core/color/sRGB/linear_to_sRGB.d.ts.map +1 -1
  550. package/src/core/color/sRGB/linear_to_sRGB.js +39 -32
  551. package/src/core/color/xyz/hpe_to_xyz.d.ts +24 -0
  552. package/src/core/color/xyz/hpe_to_xyz.d.ts.map +1 -0
  553. package/src/core/color/xyz/hpe_to_xyz.js +39 -0
  554. package/src/core/color/xyz/rgb_to_xyz.d.ts +17 -2
  555. package/src/core/color/xyz/rgb_to_xyz.d.ts.map +1 -1
  556. package/src/core/color/xyz/rgb_to_xyz.js +44 -18
  557. package/src/core/color/xyz/xyz_cmf_tabulated.d.ts.map +1 -1
  558. package/src/core/color/xyz/xyz_cmf_tabulated.js +217 -211
  559. package/src/core/color/xyz/xyz_cmf_wyman.d.ts +4 -0
  560. package/src/core/color/xyz/xyz_cmf_wyman.d.ts.map +1 -1
  561. package/src/core/color/xyz/xyz_cmf_wyman.js +74 -65
  562. package/src/core/color/xyz/xyz_to_hpe.d.ts +18 -0
  563. package/src/core/color/xyz/xyz_to_hpe.d.ts.map +1 -0
  564. package/src/core/color/xyz/xyz_to_hpe.js +33 -0
  565. package/src/core/color/xyz/xyz_to_rgb.d.ts +17 -2
  566. package/src/core/color/xyz/xyz_to_rgb.d.ts.map +1 -1
  567. package/src/core/color/xyz/xyz_to_rgb.js +39 -16
  568. package/src/core/color/ycxcz/xyz_to_ycxcz.d.ts +7 -2
  569. package/src/core/color/ycxcz/xyz_to_ycxcz.d.ts.map +1 -1
  570. package/src/core/color/ycxcz/xyz_to_ycxcz.js +33 -28
  571. package/src/core/events/signal/Signal.js +820 -820
  572. package/src/core/math/clamp_index.d.ts +18 -0
  573. package/src/core/math/clamp_index.d.ts.map +1 -0
  574. package/src/core/math/clamp_index.js +23 -0
  575. package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +803 -0
  576. package/src/engine/asset/loaders/image/jpeg/JpegFrame.d.ts +5 -3
  577. package/src/engine/asset/loaders/image/jpeg/JpegFrame.d.ts.map +1 -1
  578. package/src/engine/asset/loaders/image/jpeg/JpegFrame.js +5 -3
  579. package/src/engine/asset/loaders/image/jpeg/JpegFrameComponent.d.ts +2 -1
  580. package/src/engine/asset/loaders/image/jpeg/JpegFrameComponent.d.ts.map +1 -1
  581. package/src/engine/asset/loaders/image/jpeg/JpegFrameComponent.js +2 -1
  582. package/src/engine/asset/loaders/image/jpeg/JpegImage.d.ts +17 -0
  583. package/src/engine/asset/loaders/image/jpeg/JpegImage.d.ts.map +1 -1
  584. package/src/engine/asset/loaders/image/jpeg/JpegImage.js +197 -157
  585. package/src/engine/asset/loaders/image/jpeg/idct8x8_float.d.ts +0 -1
  586. package/src/engine/asset/loaders/image/jpeg/idct8x8_float.d.ts.map +1 -1
  587. package/src/engine/asset/loaders/image/jpeg/idct8x8_float.js +0 -1
  588. package/src/engine/asset/loaders/image/jpeg/jpeg_component_row.d.ts +28 -0
  589. package/src/engine/asset/loaders/image/jpeg/jpeg_component_row.d.ts.map +1 -0
  590. package/src/engine/asset/loaders/image/jpeg/jpeg_component_row.js +31 -0
  591. package/src/engine/asset/loaders/image/png/PNG.d.ts +3 -18
  592. package/src/engine/asset/loaders/image/png/PNG.d.ts.map +1 -1
  593. package/src/engine/asset/loaders/image/png/PNG.js +3 -139
  594. package/src/engine/asset/loaders/image/png/PNGReader.d.ts +16 -16
  595. package/src/engine/asset/loaders/image/png/PNGReader.d.ts.map +1 -1
  596. package/src/engine/asset/loaders/image/png/PNGReader.js +143 -160
  597. package/src/engine/asset/loaders/image/png/chunk/png_chunk_decode_iTXt.js +3 -3
  598. package/src/engine/asset/loaders/image/png/chunk/png_chunk_decode_zTXt.js +3 -3
  599. package/src/engine/asset/loaders/image/png/crc32.d.ts +1 -15
  600. package/src/engine/asset/loaders/image/png/crc32.d.ts.map +1 -1
  601. package/src/engine/asset/loaders/image/png/crc32.js +5 -89
  602. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterNone.d.ts +12 -10
  603. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterNone.d.ts.map +1 -1
  604. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterNone.js +20 -45
  605. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterSub.d.ts +2 -1
  606. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterSub.d.ts.map +1 -1
  607. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterSub.js +2 -0
  608. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterUp.d.ts +2 -1
  609. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterUp.d.ts.map +1 -1
  610. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterUp.js +2 -0
  611. package/src/engine/asset/loaders/image/png/filter/png_unfilter.d.ts +22 -0
  612. package/src/engine/asset/loaders/image/png/filter/png_unfilter.d.ts.map +1 -0
  613. package/src/engine/asset/loaders/image/png/filter/png_unfilter.js +68 -0
  614. package/src/engine/asset/loaders/image/png/png_inflate.d.ts +20 -0
  615. package/src/engine/asset/loaders/image/png/png_inflate.d.ts.map +1 -0
  616. package/src/engine/asset/loaders/image/png/png_inflate.js +85 -0
  617. package/src/engine/asset/loaders/image/png/png_unpack_samples.d.ts +22 -0
  618. package/src/engine/asset/loaders/image/png/png_unpack_samples.d.ts.map +1 -0
  619. package/src/engine/asset/loaders/image/png/png_unpack_samples.js +38 -0
  620. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.d.ts.map +1 -1
  621. package/src/engine/graphics/ecs/sprite/SpriteSystemPE.js +135 -132
  622. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts +16 -3
  623. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts.map +1 -1
  624. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1157 -1149
  625. package/src/engine/graphics/render/frame_graph/FrameGraph.js +900 -900
  626. package/src/engine/physics/ecs/PhysicsSystem.d.ts +72 -81
  627. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  628. package/src/engine/physics/ecs/PhysicsSystem.js +86 -77
  629. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  630. package/src/shade/device/IMMEDIATE_DATA_PLAN_2026_08_28.md +451 -0
  631. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +625 -0
  632. package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
  633. package/src/shade/renderer/scene/serialization/decode_image_source_hdr.d.ts +14 -3
  634. package/src/shade/renderer/scene/serialization/decode_image_source_hdr.d.ts.map +1 -1
  635. package/src/shade/renderer/scene/serialization/decode_image_source_hdr.js +50 -51
  636. package/src/shade/renderer/scene/serialization/deserialize_scene.d.ts.map +1 -1
  637. package/src/shade/renderer/scene/serialization/deserialize_scene.js +531 -521
  638. package/src/shade/renderer/scene/serialization/write_image_source.d.ts.map +1 -1
  639. package/src/shade/renderer/scene/serialization/write_image_source.js +6 -4
  640. package/src/shade/renderer/shader/chunk/color/chunk_rgb_to_luminance.d.ts.map +1 -1
  641. package/src/shade/renderer/shader/chunk/color/chunk_rgb_to_luminance.js +34 -32
  642. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_eotf_st2084.d.ts +31 -0
  643. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_eotf_st2084.d.ts.map +1 -1
  644. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_eotf_st2084.js +62 -31
  645. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_inverse_eotf_st2084.d.ts +10 -0
  646. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_inverse_eotf_st2084.d.ts.map +1 -1
  647. package/src/shade/renderer/shader/chunk/color/iCtCp/chunk_inverse_eotf_st2084.js +32 -22
  648. package/src/shade/renderer/shader/chunk/color/sRGB/chunk_sRGBTransferOETF.d.ts.map +1 -1
  649. package/src/shade/renderer/shader/chunk/color/sRGB/chunk_sRGBTransferOETF.js +22 -21
  650. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.d.ts +6 -0
  651. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.d.ts.map +1 -1
  652. package/src/shade/renderer/shader/chunk/color/tonemap/gt7/chunk_tonemap_gt7.js +110 -104
  653. package/src/shade/renderer/shader/chunk/color/xyz/chunk_rgb_to_xyz.d.ts.map +1 -1
  654. package/src/shade/renderer/shader/chunk/color/xyz/chunk_rgb_to_xyz.js +23 -21
  655. package/src/view/elements/ColorPickerView.js +296 -296
  656. package/src/avif/codec/dec/Readme.md +0 -14
  657. package/src/avif/codec/dec/avif_dec.cpp +0 -234
  658. package/src/avif/codec/dec/avif_dec.d.ts +0 -3
  659. package/src/avif/codec/dec/avif_dec.d.ts.map +0 -1
  660. package/src/avif/codec/dec/avif_dec.js +0 -16
  661. package/src/avif/codec/dec/avif_dec.wasm +0 -0
  662. package/src/avif/codec/enc/README.md +0 -37
  663. package/src/avif/codec/enc/avif_enc.cpp +0 -216
  664. package/src/avif/codec/enc/avif_enc.d.ts +0 -3
  665. package/src/avif/codec/enc/avif_enc.d.ts.map +0 -1
  666. package/src/avif/codec/enc/avif_enc.js +0 -6144
  667. package/src/avif/codec/enc/avif_enc.wasm +0 -0
  668. package/src/avif/codec/enc/avif_enc_mt.d.ts +0 -3
  669. package/src/avif/codec/enc/avif_enc_mt.d.ts.map +0 -1
  670. package/src/avif/codec/enc/avif_enc_mt.js +0 -6811
  671. package/src/avif/codec/enc/avif_enc_mt.wasm +0 -0
  672. package/src/avif/codec/enc/avif_enc_mt.worker.d.mts +0 -2
  673. package/src/avif/codec/enc/avif_enc_mt.worker.d.mts.map +0 -1
  674. package/src/avif/codec/enc/avif_enc_mt.worker.d.ts +0 -11
  675. package/src/avif/codec/enc/avif_enc_mt.worker.d.ts.map +0 -1
  676. package/src/avif/codec/enc/avif_enc_mt.worker.js +0 -171
  677. package/src/avif/codec/enc/avif_enc_mt.worker.mjs +0 -1
  678. package/src/avif/decode.d.ts +0 -3
  679. package/src/avif/decode.d.ts.map +0 -1
  680. package/src/avif/decode.js +0 -42
  681. package/src/avif/encode.d.ts +0 -3
  682. package/src/avif/encode.d.ts.map +0 -1
  683. package/src/avif/encode.js +0 -75
  684. package/src/avif/meta.d.ts +0 -24
  685. package/src/avif/meta.d.ts.map +0 -1
  686. package/src/avif/meta.js +0 -23
  687. package/src/avif/tsconfig.tsbuildinfo +0 -1
  688. package/src/avif/utils.d.ts +0 -17
  689. package/src/avif/utils.d.ts.map +0 -1
  690. package/src/avif/utils.js +0 -31
  691. package/src/engine/asset/loaders/image/jpeg/idct8x8_fixed.d.ts +0 -23
  692. package/src/engine/asset/loaders/image/jpeg/idct8x8_fixed.d.ts.map +0 -1
  693. package/src/engine/asset/loaders/image/jpeg/idct8x8_fixed.js +0 -214
  694. package/src/engine/asset/loaders/image/png/inflate.d.ts +0 -7
  695. package/src/engine/asset/loaders/image/png/inflate.d.ts.map +0 -1
  696. package/src/engine/asset/loaders/image/png/inflate.js +0 -20
@@ -0,0 +1,537 @@
1
+ # Native AVIF — decision log
2
+
3
+ Autonomous decisions taken while building `src/avif/native/`, with the reasoning that produced
4
+ them. Newest entries at the bottom of each section. A decision recorded here is settled; revisiting
5
+ one means adding a superseding entry, not editing the old one.
6
+
7
+ ---
8
+
9
+ ## Scope
10
+
11
+ ### D1 — Still images only; inter prediction is out of scope
12
+ AVIF still images are AV1 key frames. Inter prediction (motion vector prediction, compound modes,
13
+ OBMC, warped motion, masked compound, reference frame state) is roughly the same volume of code
14
+ again as everything else in the decoder, and no AVIF still image can use it. Animated AVIF (`avis`)
15
+ is rejected with an explicit error rather than half-decoded.
16
+
17
+ **Consequence:** meep cannot decode animated AVIF through this path. It does not today either — the
18
+ existing call sites decode single images.
19
+
20
+ ### D2 — Decoder implements every tool; encoder uses a subset
21
+ The decoder must handle whatever an arbitrary encoder emitted, so it implements deblocking, CDEF,
22
+ loop restoration, superres, film grain, palette, intra block copy and quantizer matrices. The
23
+ encoder signals the in-loop filters off and does not use palette or IBC. These are quality tools;
24
+ omitting them costs compression efficiency, not conformance, and each one omitted is a large body
25
+ of search code that would ship untested.
26
+
27
+ ### D3 — Large-scale tile (Annex D) and the decoder model (Annex E) are not implemented
28
+ Neither is reachable from an AVIF still image. Decoder-model fields in the sequence header are
29
+ parsed (they must be, to find the fields after them) and discarded.
30
+
31
+ ---
32
+
33
+ ## Data and tables
34
+
35
+ ### D4 — Normative tables are generated, never hand-written
36
+ All 156 constant tables come from the AOMedia AV1 specification's markdown sources via
37
+ `tools/generate_tables.mjs`. A single mistyped digit in a CDF desynchronises the arithmetic decoder
38
+ for the rest of the tile, and no test short of a full oracle comparison would catch it. Generation
39
+ makes the tables auditable against their source and regenerable.
40
+
41
+ Provenance and licensing: [NOTICE.md](NOTICE.md).
42
+
43
+ ### D5 — Large tables are base64-packed, small ones are literals
44
+ Tables above 4096 entries (the coefficient CDFs, the quantizer matrices) are emitted as base64
45
+ strings decoded once at module load into typed arrays. Below that they are plain typed-array
46
+ literals, which stay readable and greppable. The threshold trades source size against
47
+ debuggability; the quantizer matrices alone are ~130 KB of `uint8` and would dominate the module
48
+ otherwise.
49
+
50
+ ### D6 — CDFs are stored in specification form
51
+ The spec stores a CDF for `N` symbols as `N+1` values: `N-1` cumulative probabilities, then
52
+ `1 << 15`, then an update counter. Reference implementations store the complement (`32768 - p`) to
53
+ save an operation in their inner loop. We keep the spec form so the code reads as a direct
54
+ transliteration of §8.3 and the tables can be diffed against the specification text by eye. The
55
+ inner-loop cost is one subtraction.
56
+
57
+ ---
58
+
59
+ ## Representation
60
+
61
+ ### D7 — All samples are `Uint16Array`, regardless of bit depth
62
+ 8-bit content costs 2× the memory and forgoes any 8-bit-specific fast path. The alternative is
63
+ templating every sample-touching function over `Uint8Array`/`Uint16Array`, which in JavaScript
64
+ means either duplicated source or megamorphic call sites that deoptimise the whole pixel pipeline.
65
+ One uniform path is worth the constant factor; a specialised 8-bit path can be added later behind
66
+ the same tests if profiling justifies it.
67
+
68
+ ### D8 — Coefficients and residuals are `Int32Array`
69
+ The spec's intermediate precision for the larger transforms exceeds 16 bits, and `Int32Array` maps
70
+ onto JavaScript's native 32-bit integer semantics (`|0`, `>>`) without surprises.
71
+
72
+ ### D9 — Mode info is stored as parallel typed-array planes
73
+ Per-4×4 state (mode, tx size, skip, segment id, palette size, …) is stored one typed array per
74
+ field, indexed `mi_row * mi_stride + mi_col`. An array of objects would allocate per block and make
75
+ the neighbour lookups — which are the hottest reads in the tile decoder — pointer chases.
76
+
77
+ ---
78
+
79
+ ## Container
80
+
81
+ ### D10 — Read with a `DataView` cursor, write with `BinaryBuffer`
82
+ `core/binary/BinaryBuffer.js` is a growable stream, which is exactly right for writing and carries
83
+ the big-endian accessors ISOBMFF needs. For reading it is the wrong shape: box parsing wants
84
+ zero-copy random access into a buffer that already exists, and the growth machinery is dead weight.
85
+ A thin `DataView` cursor covers reading in a few dozen lines. Using the right tool in each direction
86
+ is not duplication.
87
+
88
+ ### D11 — `iloc` is written with fixed-width 32-bit offsets and a two-pass patch
89
+ Item offsets in `iloc` point into `mdat`, whose position depends on the size of the metadata that
90
+ precedes it — including `iloc` itself. Writing offsets as fixed-width fields makes the metadata size
91
+ invariant to the offset values, so a single measure-then-patch pass converges immediately instead of
92
+ iterating. 32-bit offsets cap a written file at 4 GiB, which is far beyond anything meep produces;
93
+ the writer throws if a payload would exceed it rather than silently truncating.
94
+
95
+ ### D12 — Written files use construction method 0 (file offsets)
96
+ Method 1 (`idat`) and method 2 (item references) are supported on read because real files use them,
97
+ but writing always uses plain file offsets into `mdat`. It is what every decoder handles best and it
98
+ keeps the writer's layout logic linear.
99
+
100
+ ---
101
+
102
+ ## Colour and HDR
103
+
104
+ ### D13 — The existing HDR convention is preserved exactly
105
+ `encoder_worker.js` encodes engine-linear float16 as PQ at 12 bits, 4:2:2, signalling BT.709
106
+ primaries / PQ transfer / BT.709 matrix, with engine linear scaled by `PQ_SDR_WHITE_LINEAR` before
107
+ `linear_to_PQ`. Alpha is mapped linearly to the full 12-bit range. Assets already written by meep
108
+ depend on this, so the native encoder reproduces it as its HDR default and the native decoder reads
109
+ it back to identical values.
110
+
111
+ Note on the existing convention: BT.709 primaries with PQ transfer is unusual — PQ content is
112
+ normally BT.2020 — but changing it would make already-written assets decode with wrong chromaticity.
113
+ The encoder therefore keeps BT.709 as the default and exposes primaries as an option.
114
+
115
+ ### D14 — Decoded HDR is returned in engine normalisation
116
+ `avif_to_sampler2d` returns linear float16 where `1.0` is SDR reference white (203 nits), matching
117
+ `PQ_SDR_WHITE_LINEAR`'s convention and the rest of the engine. The raw PQ-normalised values are
118
+ available from `decode_avif` for callers that want them.
119
+
120
+ ### D15 — Colour conversion is float, and its tolerances are stated
121
+ The codec layer is bit-exact (I4). The colour layer is not and cannot be: transfer functions are
122
+ transcendental. Each conversion function documents its expected round-trip error, and colour specs
123
+ assert against those tolerances rather than exact equality.
124
+
125
+ ---
126
+
127
+ ## API
128
+
129
+ ### D16 — The public API is synchronous with no initialisation step
130
+ No `init()`, no module instantiation, no promise. This is the main ergonomic gain over the WASM
131
+ path and it falls directly out of being pure JS. Callers needing responsiveness drive it from a
132
+ worker, exactly as `threaded_image_encoder.js` already does.
133
+
134
+ ### D17 — A step-wise encoder driver is offered alongside the one-shot call
135
+ `encode_avif` runs to completion synchronously. For callers that must stay responsive without
136
+ threads, the encoder also exposes a driver that advances one superblock row per call, so the work
137
+ can be spread across frames. Same code path, different pump.
138
+
139
+ ---
140
+
141
+ ## Testing
142
+
143
+ ### D18 — The WASM reference is used offline to mint fixtures, not called from specs
144
+ The libavif WASM glue is built for the web only: it asserts on the node environment and needs
145
+ `window`/`self`/`document` shims plus temporarily removing `globalThis.process` to load. Doing that
146
+ inside vitest is hostile to the runner. `tools/generate_fixtures.mjs` performs the shimming once,
147
+ offline, and commits small `.avif` files with pixel-dump sidecars. The committed suite stays pure,
148
+ deterministic and portable.
149
+
150
+ ### D19 — Fixture generation deliberately sweeps encoder settings
151
+ Default libaom settings exercise a narrow slice of the format. Fixtures are minted across bit
152
+ depths, subsamplings, lossless, tiling, CDEF/loop-restoration on and off, film grain and superres,
153
+ so the decode paths that only appear under unusual settings are covered rather than assumed.
154
+
155
+ ---
156
+
157
+ ## Implementation choices made while building
158
+
159
+ ### D20 — `BitReader` and `BitWriter` are classes with methods, not structs plus free functions
160
+ The rest of the codec follows C2 (structs carry fields, free functions carry behaviour). Stream
161
+ cursors are the exception, because a cursor's entire purpose is the coupling of a position to a
162
+ buffer, and because meep already spells that shape as a class in
163
+ `core/binary/BinaryBuffer.js`. Matching the existing precedent beats internal consistency with a
164
+ rule written for the pixel pipeline.
165
+
166
+ ### D21 — Item property structs live together in one file
167
+ `ItemProperty.js` holds all fifteen property structs. They are a family, each is a handful of
168
+ fields, and splitting them across fifteen files would make the set harder to read without making
169
+ anything more testable. Reading and writing stay in separate files, so the decoder tree can be
170
+ imported without the writer.
171
+
172
+ ### D22 — Tables are generated from the specification's markdown, not from a reference decoder
173
+ `tools/generate_tables.mjs` parses the published `av1-spec` markdown. That source is normative and
174
+ stores CDFs in specification form already, so no conversion is needed and the generated numbers can
175
+ be diffed against the specification text by eye. A reference implementation would have meant
176
+ translating from its own internal representation, which is one more place to be wrong.
177
+
178
+ ### D23 — The generator recovers from a defect in the published markdown
179
+ `Split_Tx_Size` in `10.additional.tables.md` is missing the comma between its thirteenth and
180
+ fourteenth entries. Rather than carrying a patch list against the source, the initialiser parser
181
+ falls back to treating whitespace as a separator when a token will not evaluate as a whole but each
182
+ of its words will, and reports every recovery it makes. `av1/tables/tables.spec.js` pins the
183
+ resulting values so the recovery cannot silently change.
184
+
185
+ ### D24 — Generated tables are validated structurally, not by transcription
186
+ `tables.spec.js` checks that every one of the 96 default CDF tables is a valid cumulative
187
+ distribution — strictly increasing, terminating at `1 << 15`, with a zeroed adaptation counter —
188
+ that every scan table is a permutation of its positions, that the transform and block geometry
189
+ tables agree with each other, and that the cosine lookup matches its closed form. These are
190
+ properties a mis-parse would violate, which is a far stronger check than spot-checking values
191
+ against the text.
192
+
193
+ ### D25 — The decoder tolerates non-zero byte-alignment padding; the reader does not
194
+ The specification says the padding `byte_alignment()` skips "shall be equal to 0". libaom does not
195
+ comply: it rounds a frame header up to a whole byte by advancing its write cursor, so inside an
196
+ `OBU_FRAME` those bits are whatever was already in its output buffer. `BitReader.byte_alignment`
197
+ keeps the strict check, because our own writer must satisfy it; the decoder calls
198
+ `skip_to_byte_boundary` instead. Refusing such files would reject a large share of the AVIFs that
199
+ exist over bits nothing reads.
200
+
201
+ ### D26 — Fixture properties are measured from the encoded file, never assumed
202
+ libavif silently overrides a requested identity matrix to BT.601 for anything but a lossless
203
+ encode. Fixtures generated with `matrixCoefficients: 0` at quality 90 are therefore *not* an
204
+ identity oracle, and comparing their planes to the reference RGBA as though they were produced a
205
+ convincing but entirely wrong failure. `tools/generate_fixtures.mjs` now parses each file it mints
206
+ and records what it actually contains — matrix, subsampling, and which post-processing filters the
207
+ frame header enables — and `exact` is derived from that.
208
+
209
+ Monochrome is the other exact shape, and the more useful one: with a single plane every output
210
+ channel is the luma, whatever the signalled matrix, so a monochrome fixture is an exact oracle for
211
+ the luma path at *any* quality. That is what makes lossy coefficient coding testable at all.
212
+
213
+ ## D27. Fixtures are synthesised where the reference encoder will not cooperate
214
+
215
+ CDEF and superres had no oracle: the libavif build here emits `enable_cdef = 0` in every sequence
216
+ header it writes, and never asks for superres. Lossy chroma had none either, because libavif
217
+ overrides identity matrix coefficients for anything that is not lossless, so every exact fixture was
218
+ monochrome or lossless.
219
+
220
+ Rather than ship three untested filters, `tools/synthesise_fixtures.mjs` rewrites the headers of an
221
+ already-encoded stream and leaves the tile data untouched. That is sound for exactly three changes:
222
+
223
+ - **Matrix coefficients** decide how the planes are interpreted, not how they are coded. Retargeting
224
+ a lossy 4:4:4 stream to the identity matrix makes the reference decoder hand back the planes
225
+ themselves, which turns it into an exact oracle for chroma.
226
+ - **CDEF parameters** live in the uncompressed frame header. With `cdef_bits` at zero the
227
+ per-superblock `cdef_idx` is a zero-bit read, so the tile data is bit-identical.
228
+ - **Superres** signals the *upscaled* width and derives the coded width from it. Choosing an
229
+ upscaled width that derives back to the width the encoder used leaves the coded frame — and so the
230
+ tile data — exactly as it was.
231
+
232
+ This is not a self-consistency check. The reference decoder still produces the expected samples, and
233
+ it has never seen this decoder's output. What it cannot cover is a bug that lives in the tile data
234
+ for those configurations, which is why the encoder phase will cross-check the other direction.
235
+
236
+ ## D28. Intra block copy is refused rather than half-supported
237
+
238
+ `allow_intrabc` predicts a block from elsewhere in the same frame with a block vector, which needs
239
+ the motion vector machinery this decoder otherwise has no use for. Screen-content AVIF that uses it
240
+ is rare, and a decoder that silently mis-predicted would be worse than one that says so. The stream
241
+ is refused by name; if a real file turns up that needs it, the vector reading is a contained
242
+ addition to the tile decoder.
243
+
244
+ ## D29. The forward transform is measured from the inverse, not transliterated
245
+
246
+ AV1 specifies only the *inverse* transform. Every encoder invents a forward one, and the only
247
+ property that matters is that the normative inverse turns its output back into the picture.
248
+
249
+ Rather than transliterate libaom's integer butterflies — several hundred lines, and correct only if
250
+ every one of them is — `forward_transform_2d.js` probes the specification's own inverse with unit
251
+ impulses and inverts the resulting matrix. It is a dozen lines, it gives the ADST for free, and it
252
+ is exactly as correct as the inverse it was measured from.
253
+
254
+ The measured map is very slightly non-linear, because the integer butterfly rounds internally, so
255
+ the round trip is exact to within one step rather than exactly. Quantisation swallows that. At
256
+ quantizer index zero, where nothing may be lost, the lossless path uses the Walsh-Hadamard pair,
257
+ which is exactly invertible — and is tested to be.
258
+
259
+ ## D30. The encoder mirrors a subset of the decoder's syntax, and shares its contexts
260
+
261
+ An encoder has to make the same decisions a decoder makes, in the same order, from the same state.
262
+ Where that state is *derived* — coefficient contexts, partition CDF selection, the intra edge filter
263
+ type, the block decoded flags — the derivation is now in a module both sides import, rather than
264
+ written twice. A context that drifted by one would desynchronise the arithmetic coder several blocks
265
+ later, somewhere that looks nothing like the mistake.
266
+
267
+ The traversal itself is written twice, because the encoder interleaves decisions with coding and
268
+ inverting the decoder's control flow to serve both would be worse than a mirror. What keeps the two
269
+ honest is that the encoder reconstructs through the decoder's own `reconstruct`, so its picture of
270
+ what it has coded is the decoder's picture by construction, and that every test decodes what the
271
+ encoder wrote.
272
+
273
+ The syntax the encoder emits is deliberately narrow: one tile group, no palette, no filter intra, no
274
+ segmentation, no delta quantisers, no deblocking, largest-transform mode, blocks from 8x8 to 32x32,
275
+ five intra modes. Everything it does emit, the decoder reads — and so does libavif.
276
+
277
+ ## D31. Compression is within about 1.5x of libavif, and that is a separate piece of work
278
+
279
+ At matched quality this encoder produces files around 1.4 to 1.6 times the size of libavif's. The
280
+ gap is decisions, not correctness: no rate-distortion search over modes, transform types or
281
+ partitions, no trellis over coefficient levels, no rectangular partitions, and a fixed dead zone
282
+ rather than a tuned one. Each of those is an addition that changes no interface and breaks no test —
283
+ which is why the first version is the one that is provably correct rather than the one that is
284
+ nearly as small.
285
+
286
+ ## D32. Two normalisations, one boundary, and each layer says which it speaks
287
+
288
+ There are two defensible meanings for a linear `1.0` here and the module needs both, so the question
289
+ is not which one wins but where they meet.
290
+
291
+ **The colour layer keeps a hundred nits.** `transfer_to_linear` and `linear_to_transfer` implement
292
+ H.273 table 3, and the SDR curves in it — BT.709, sRGB, gamma 2.2, gamma 2.8 — are defined against a
293
+ hundred nit reference display. Signal `1.0` decoding to linear `1.0` is those curves' own fixed
294
+ point, not a convention this module picks. Renaming `LINEAR_REFERENCE_NITS` to `SDR_WHITE_NITS`
295
+ would land sRGB white at 0.4926 and turn a statement about a standard into a statement about meep,
296
+ so it stays at 100 and says why in its own doc comment.
297
+
298
+ **The renderer-facing pair speaks the renderer's white.** meep's `1.0` is SDR reference white, 203
299
+ nits per BT.2408, which is what `PQ_constants.js` documents and what every sampler in the engine
300
+ counts in. `sampler2d_to_avif` and `avif_to_sampler2d` are the boundary, and each names its white to
301
+ the codec through `linear_reference_nits` — an option on `encode_avif` and on `convert_to_rgba` that
302
+ says what a linear `1.0` on *the caller's* side stands for. Both pass `SDR_WHITE_NITS`, so the pair
303
+ is an exact inverse in renderer units and visibly so: the two calls read the same. It is tested in
304
+ `api/sampler2d_round_trip.spec.js`, which also pins the file itself down to 203 nits so a later
305
+ "simplification" cannot make the two ends agree on the wrong white.
306
+
307
+ Naming the white rather than multiplying at the call site is what buys the symmetry. It also keeps
308
+ the scaling in the one loop that already touches every sample, so the decode side costs a multiply
309
+ rather than a second pass through half float.
310
+
311
+ ### What this changes, and for whom
312
+
313
+ Encoding is byte-for-byte what it was: the factor moved from `sampler2d_to_avif`'s pixel loop into
314
+ `encode_avif`'s, and the file still carries renderer `1.0` as 203 nits. Decoding is the fix, and it
315
+ is a real behaviour change — `avif_to_sampler2d` now returns 2.03 times less than it did.
316
+
317
+ That 2.03 was not a convention anybody chose. It predates this module: the WebAssembly pair had it
318
+ too, because the old `encoder_worker.js` multiplied by `PQ_SDR_WHITE_LINEAR` before `linear_to_PQ`
319
+ while libavif's "PQ to linear" normalises to a hundred nits. The native codec reproduced it
320
+ deliberately so that swapping the codec changed no picture; this is the follow-up that was owed.
321
+
322
+ Nothing downstream was compensating for it. `decode_image_source_hdr` and `deserialize_scene` pass
323
+ the sampler straight through; `texture_write_to_gpu`'s note about Uint16 samplers is about half
324
+ float *bit patterns*, not about normalisation, and its premultiply is unaffected; there is no
325
+ exposure or scale anywhere in `src/shade` carrying a reciprocal. Auto-exposure would have absorbed
326
+ some of it on an environment map, which is probably why it survived — but an albedo map has no such
327
+ cover, and 2.03 there is simply blown out.
328
+
329
+ **No migration.** Scenes on disk are correct as written: their PQ AVIFs say 203 nits and mean it,
330
+ and it was only the reader that misread them. Rewriting the files would preserve the bug rather than
331
+ fix it. The visible change is a one-off darkening of HDR image sources back to the brightness they
332
+ were authored at, and content tuned by eye against the old reader will want re-checking. The
333
+ compounding is the argument that little was: a scene saved and reloaded got 2.03 times brighter each
334
+ round, so nothing can have been held to the old behaviour for long without blowing out.
335
+
336
+ ## D33. Orientation is applied on request; a gain map falls back to its base picture
337
+
338
+ Two things a real file carries that the coded picture does not:
339
+
340
+ - **`irot` and `imir`** say the picture is stored one way round and meant to be seen another, which
341
+ is what a camera writes rather than rotating the samples. libavif hands them to its caller instead
342
+ of applying them, so applying them unconditionally would rotate twice for any caller that already
343
+ honours orientation. `decode_avif` takes `apply_transformations` and defaults it off, which keeps
344
+ the behaviour of the decoder being replaced and makes the capability available to anything that
345
+ wants it. `clap`, the clean aperture, is left alone: it is a crop expressed as four rationals, it
346
+ is rare, and cropping by a misread fraction is worse than not cropping.
347
+ - **A `tmap` primary item** is a base picture plus a gain map — increasingly what a phone writes for
348
+ HDR. Reading the gain map is a piece of work in its own right; falling back to the base picture is
349
+ what the format expects of a decoder that does not, and it produces a correct picture rather than
350
+ a broken one. That fallback is here; the gain map is not.
351
+
352
+ ## D34. The compression gap is closed to about 1.08x, by searching rather than by guessing
353
+
354
+ Supersedes D31, and the clauses of D2 and D30 that describe what the encoder does not do.
355
+
356
+ D31 recorded the gap as "around 1.4 to 1.6 times libavif at matched quality". That number was
357
+ measured by encoding both at the same quality setting and comparing two sizes, which understates it:
358
+ two encoders' quality scales are not the same scale, and at quality 75 this encoder was 1.4 times
359
+ the size *and* 2.7 dB worse. Swept properly — size against fidelity, compared where the curves
360
+ overlap — the gap on photographic content was nearer **2.2 times**. `tools/measure_encoder.mjs` is
361
+ that measurement, and it takes real photographs on the command line since none can be committed here.
362
+
363
+ It now stands at about **1.08 times** when the file is allowed to ask the reader for everything,
364
+ and at **1.13 times** as this codec ships — which asks for as little as possible, for the reasons in
365
+ D36. At the thorough setting two of the eight pictures come out smaller than libavif's. What closed it, in the order it was closed and with what each was worth:
366
+
367
+ | | rate for the same fidelity |
368
+ |---|---|
369
+ | where D31 left it | +112% |
370
+ | rate-distortion mode decision, over all thirteen intra modes | +79% |
371
+ | rate-distortion partition decision | +38% |
372
+ | transform type search | +33% |
373
+ | trailing coefficients trimmed against their cost — *withdrawn, see D35* | +31.7% |
374
+ | a deblocking level chosen after coding | +29.5% |
375
+ | a directional filter strength chosen after coding | +24.0% |
376
+ | blocks cut in half as well as in quarters | +21.1% |
377
+ | the trim withdrawn, and the search stripped of work it did not need | +20.8% |
378
+ | a transform size chosen per block rather than always the largest | +18.5% |
379
+ | chroma predicted from the luma already coded | +9.7% |
380
+ | blocks down to four by four, sharing their chroma in pairs | +8.6% |
381
+ | a loop restoration filter fitted to the finished picture | +7.9% |
382
+
383
+ The four T-shaped partitions and the two quarterings are implemented and are *not* on by default:
384
+ they are worth 1.2 and 0.6 points respectively and cost two thirds of the encoder's time between
385
+ them, so the balanced setting offers the two halves and the thorough setting offers all eight.
386
+
387
+ ### The one idea the rest are applications of
388
+
389
+ An encoder cannot choose on rate without knowing the rate, and the only thing that knows the rate is
390
+ the syntax. So a `SymbolWriter` has a costing mode: `reset_costing` puts it into one where writing a
391
+ symbol adds up what writing it would have cost and emits nothing. `write_coefficients`, and every
392
+ other piece of syntax the encoder emits, takes a writer and does not know which kind it has. Every
393
+ rate any decision here is made on is the rate of exactly the symbols that decision would emit,
394
+ through exactly the contexts they would meet, because it is the same function that emits them. A
395
+ cost model written alongside the syntax would be a second implementation of it, and would drift.
396
+
397
+ It was two classes before it was a mode. One writer with a branch measured faster than two writers
398
+ with a shared interface, because a call site that sees one class stays monomorphic and a call site
399
+ that sees two does not — which is a fact about how JavaScript is run rather than about codecs, and
400
+ it is worth the mode.
401
+
402
+ The partition decision needs more than that: it has to price answers that have not been made, and a
403
+ block's price depends on the reconstruction and the contexts the block before it left. So the
404
+ search *makes* each answer — predicts, quantises, reconstructs, advances the contexts — measures it,
405
+ and puts the state back. `Av1BlockSnapshot` is what "puts the state back" means. Each superblock is
406
+ therefore coded twice, once to decide and once to write, and the two agree because the second starts
407
+ from exactly the state the first did and replays what the first recorded.
408
+
409
+ Loop restoration then made the *frame* work that way as well. Its filters can only be fitted to the
410
+ finished picture, and the format codes them inside the tile — so the decisions of a whole frame are
411
+ kept and the tile is written a second time from them. That is why the record of what the search
412
+ chose is frame-wide rather than a superblock at a time.
413
+
414
+ ### What is measured rather than derived
415
+
416
+ Three constants that could have been guessed and are not:
417
+
418
+ - **Lambda is 0.0016 of the squared quantiser step.** Encode at two quantisers, divide the change in
419
+ squared error over the coded planes by the change in coded bits. It comes out within a sixth of
420
+ that across synthetic and photographic pictures and three decades of quantiser, because it is a
421
+ property of the format's quantiser tables rather than of any picture.
422
+ - **A sixty-fourth of the coefficient domain's squared error is the sample domain's.** The
423
+ specification's inverse transform is orthonormal up to a scale, and the scale is the same for
424
+ every size and type this encoder emits. That is what lets a coefficient be priced without running
425
+ the inverse transform to find out what it was worth.
426
+ - **Ranking by squared error beats ranking by SATD** at every equal-time point, which is the
427
+ opposite of the usual advice. A Hadamard transform does rank better — one priced mode with it is
428
+ worth about two without — but it costs more per candidate than it saves in trials. Measured, and
429
+ then removed.
430
+
431
+ ### What this costs, and where the decision about that lives
432
+
433
+ Encoding is an order of magnitude slower than it was: 260 ms/MP became about 6 s/MP at the balanced
434
+ setting, or eleven times the WebAssembly libavif build at speed 6 measured beside it. That is what
435
+ searching costs in JavaScript, and it is a knob rather than a fact — `effort` on `encode_avif`
436
+ selects between +15.7% at about 2.5 s/MP and +2.4% at about 25 s/MP, and the eight settings behind
437
+ it are on the encode context for anything finer.
438
+
439
+ Two thirds of what is left is the forward transform, the coefficient syntax, and the *inverse*
440
+ transform the search runs to reconstruct what it is pricing. None of those is waste; each trial
441
+ needs all three. The transform has since been folded along the symmetry of its own basis, which took
442
+ `n * n` multiplies to a little over `n * n / 3` — and moved the whole encoder by four per cent,
443
+ because the work is spread across twenty functions rather than concentrated in one.
444
+
445
+ Decoding is where the *reader* pays, and what it pays is not the same axis. See D36: it is
446
+ `decode_effort`, it defaults to asking for as little as possible, and the numbers are there.
447
+
448
+ ### What is still not done
449
+
450
+ The self-guided restoration filter, which fits noise rather than ringing and would cost a three-way
451
+ symbol on every unit whether either filter wins or not. Palette mode and intra block copy, which are
452
+ screen-content tools this decoder does not implement either (see D28). Angle deltas on directional
453
+ modes, and filter-intra. Each is worth low single digits on photographs and none of them changes an
454
+ interface.
455
+
456
+ The trellis is not on that list. It was built, measured, and removed: see D35.
457
+
458
+ ## D35. A trellis over coefficient levels measured worse than rounding, and is not there
459
+
460
+ Quantisation rounds at 0.45 of a step rather than 0.5, which is `ec.rounding`, and that is the whole
461
+ of what this encoder does about coefficient levels. It is not for want of trying the other thing.
462
+
463
+ The obvious next move from a rate-distortion mode decision is a rate-distortion *coefficient*
464
+ decision: walk the transform block's levels, and for each one ask whether coding it is worth what it
465
+ costs. The cheap form of it — trim the trailing coefficients, since dropping a tail also moves the
466
+ end-of-block position and saves the symbols that would have carried it — was implemented, measured
467
+ at the time as worth 1.3 points, and shipped.
468
+
469
+ Measured again, more carefully, it was worth **less than nothing**: +20.7% without it against +21.4%
470
+ with, and five times as many calls into the coefficient syntax to reach that. Two things had hidden
471
+ it. The first measurement priced a trial by what the quantiser said it lost rather than by
472
+ reconstructing it and subtracting the source, and the two differ by eight per cent on a partition
473
+ decision — enough to reverse a result this size. And the trim had been landing before the
474
+ rate-distortion partition search, which then made a *different* set of partitions, so the two
475
+ measurements were not of the same encoder.
476
+
477
+ A full trellis — every level, not just the tail, with the contexts each choice leaves for the next —
478
+ would be a better answer than the trim was. It would also be several times the coefficient syntax's
479
+ current cost, which is already a fifth of the encoder, to chase something the 0.45 rounding is
480
+ already collecting most of. libaom's own trellis is off below its speed 4 for the same reason.
481
+
482
+ The number that matters is the one in the table in D34: the row for the trim reads +31.7%, and the
483
+ row for withdrawing it reads +20.8%. It was not a wash. It was a loss both ways.
484
+
485
+ ## D36. What the file asks of the reader is a separate dial, and it defaults to asking for little
486
+
487
+ AV1's three in-loop filters are the only coding tools whose cost lands on the decoder rather than
488
+ the encoder. They are chosen after the picture is coded, they change no block's decisions, and each
489
+ one is a pass over the whole frame that whoever opens the file has to run. Measured over eight
490
+ pictures against libavif at speed 6, at the balanced encode setting, with decode times on one
491
+ megapixel of the same picture:
492
+
493
+ | | rate | decode |
494
+ |---|---|---|
495
+ | no in-loop filters at all | +15.7% | 100 ms |
496
+ | deblocking — `DECODE_FAST` | +13.1% | 115 ms |
497
+ | and the directional filter — `DECODE_BALANCED` | +8.6% | 294 ms |
498
+ | and loop restoration — `DECODE_THOROUGH` | +7.9% | 350 ms |
499
+
500
+ Deblocking is nearly free and worth two and a half points, so it is in all three. The directional
501
+ filter is 4.5 points for **172 ms a megapixel** — its direction search runs over every 8x8 block of
502
+ the frame — and restoration is another 0.7 points for 56 ms.
503
+
504
+ ### Why the default is the cheap end
505
+
506
+ This codec exists to move textures into a renderer. A texture is decoded on the machine that will
507
+ draw with it, once per load, competing for CPU with everything else that machine is doing at the
508
+ moment it is needed. A megapixel texture five per cent larger costs a few kilobytes of transfer —
509
+ tens of milliseconds on a slow connection, and nothing at all after the first time, because it is
510
+ cached. The filters cost a fifth of a second of that machine's CPU on *every* read. The two are two
511
+ orders of magnitude apart, and they point the same way for anything decoded more often than it is
512
+ transferred.
513
+
514
+ Reverse it for anything whose bytes are the scarce thing — an image served to many readers over a
515
+ network someone pays for by the gigabyte, where a fifth of a second on each of their machines is not
516
+ your cost and five per cent of every transfer is. `decode_effort` on `encode_avif` is that reversal,
517
+ and `DECODE_THOROUGH` is the smallest file this encoder makes.
518
+
519
+ ### Why it is not `effort`
520
+
521
+ Encode effort spends this machine's time; decode effort spends the reader's. They are independent —
522
+ a slow, careful search can produce a file that is cheap to read, and a hasty one can produce a file
523
+ that is expensive to read — so conflating them would mean neither could be chosen. They were
524
+ conflated once, and it showed: the fast encode setting turned the directional filter *on*, which is
525
+ the opposite of what anything asking for speed wants.
526
+
527
+ The finer knobs stay where they were. `cdef_trials` and `restoration_trials` are how hard the
528
+ *encoder* looks once a filter is in play — twelve directional strengths rather than three is worth
529
+ 0.8 points for a fifth more encode time — so they belong to effort, and zero on either still turns
530
+ its filter off outright.
531
+
532
+ ### What it does not change
533
+
534
+ Fidelity at a given quality setting. What the filters buy is rate at matched fidelity: the same
535
+ picture in fewer bytes, not a better picture. And nothing about conformance — `verify_encoder`
536
+ carries a case at each of the three settings, and libavif decodes all sixteen to the same samples
537
+ this decoder produces.
@@ -0,0 +1,61 @@
1
+ # Native AVIF — third-party notices and provenance
2
+
3
+ ## Normative constant tables
4
+
5
+ The constant tables under [`av1/tables/`](av1/tables/) are normative values from the
6
+
7
+ > **AV1 Bitstream & Decoding Process Specification**, version 1.0.0 with Errata 1,
8
+ > The Alliance for Open Media.
9
+ > <https://aomediacodec.github.io/av1-spec/>
10
+
11
+ They were generated from the specification's published markdown sources
12
+ (<https://github.com/AOMediaCodec/av1-spec>) by a script that is no longer in the tree — see
13
+ [Where the development tools went](#where-the-development-tools-went) — which carry the following
14
+ notice:
15
+
16
+ > Copyright (c) 2017–2021, Alliance for Open Media. All rights reserved.
17
+ >
18
+ > This Bitstream Specification is licensed under the Alliance for Open Media Patent License 1.0
19
+ > and the accompanying BSD 2-Clause license for the reference software. Redistribution and use in
20
+ > source and binary forms, with or without modification, are permitted provided that the above
21
+ > copyright notice and this permission notice appear in all copies.
22
+
23
+ The tables are the bitstream format itself — the values that any conformant implementation must
24
+ use. They are reproduced here for that purpose and for no other.
25
+
26
+ ## Decoding and encoding processes
27
+
28
+ The processes in `av1/` are written from the specification's pseudocode. Section references appear
29
+ in the JSDoc of each function that implements a normative process, in the form
30
+ `@see AV1 spec 7.11.2`, so any function can be checked against its source.
31
+
32
+ No source code from libaom, dav1d, libgav1 or libavif is copied into this module.
33
+
34
+ ## Test oracle
35
+
36
+ The fixtures under `__fixtures__/` were minted by a development-only script that drove libavif's
37
+ WebAssembly builds. Those builds are libavif with libaom and are covered by their own licences, as
38
+ is their output — which is what those fixtures are. Nothing in the shipped `native/` code path ever
39
+ imported them, and no code from them is reproduced here.
40
+
41
+ ## Where the development tools went
42
+
43
+ Neither the reference builds nor the scripts that drove them are in the tree any more. They were
44
+ development artefacts: they shipped to nobody, and the things they produced — the constant tables,
45
+ the fixtures — are committed and read directly. One command brings all of them back:
46
+
47
+ git checkout ba1e2de5f -- src/avif/codec src/avif/native/tools
48
+
49
+ That commit is the last one carrying both. What needs them is re-deriving something rather than
50
+ running anything: regenerating `av1/tables/*.js` from the specification, minting a fixture,
51
+ re-checking that libavif decodes what this encoder writes, or measuring this encoder's rate against
52
+ libavif's. The test suite needs none of it.
53
+
54
+ `DECISIONS.md` still refers to those scripts by name, and should: it is the record of how the
55
+ fixtures were minted and how the interop claims were checked. Both remain true.
56
+
57
+ ## AV1 patent licence
58
+
59
+ Use of the AV1 format is governed by the Alliance for Open Media Patent License 1.0
60
+ (<https://aomedia.org/license/patent-license/>). This implementation makes no change to the
61
+ licensing position that already applied to meep's use of AVIF through the WebAssembly builds.
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Somewhere to assemble a grid of tiles, or to hold a frame that outlives the context that decoded
3
+ * it.
4
+ *
5
+ * @author Alex Goldring
6
+ * @copyright Company Named Limited (c) 2026
7
+ */
8
+ export class PlaneStore {
9
+ /** @type {Uint16Array[]} */
10
+ planes: Uint16Array[];
11
+ /** @type {Int32Array} */
12
+ stride: Int32Array;
13
+ /** @type {number} */
14
+ width: number;
15
+ /** @type {number} */
16
+ height: number;
17
+ /**
18
+ * @param {number} width
19
+ * @param {number} height
20
+ * @param {number} subsampling_x
21
+ * @param {number} subsampling_y
22
+ * @param {number} num_planes
23
+ */
24
+ resize(width: number, height: number, subsampling_x: number, subsampling_y: number, num_planes: number): void;
25
+ }
26
+ /**
27
+ * Everything a decode needs beyond the file itself, allocated once and reused.
28
+ *
29
+ * Colour and alpha get a frame context each. They could share one, but then decoding the alpha
30
+ * would overwrite the picture, and every caller would have to copy the picture out first — which is
31
+ * exactly the allocation this is here to avoid.
32
+ *
33
+ * @author Alex Goldring
34
+ * @copyright Company Named Limited (c) 2026
35
+ */
36
+ export class AvifDecoder {
37
+ /** @type {Av1FrameContext} */
38
+ colour_frame: Av1FrameContext;
39
+ /** @type {Av1FrameContext} */
40
+ alpha_frame: Av1FrameContext;
41
+ /** @type {PlaneStore} */
42
+ colour_store: PlaneStore;
43
+ /** @type {PlaneStore} */
44
+ alpha_store: PlaneStore;
45
+ /** @type {YuvImage} the picture */
46
+ image: YuvImage;
47
+ /** @type {YuvImage} the alpha plane, which AVIF codes as an image in its own right */
48
+ alpha_image: YuvImage;
49
+ /** @type {ColourTransform} */
50
+ transform: ColourTransform;
51
+ /** @type {Float32Array} one row of Cb, at full width */
52
+ cb_row: Float32Array;
53
+ /** @type {Float32Array} */
54
+ cr_row: Float32Array;
55
+ /** @type {Float32Array} one row of interleaved R, G, B */
56
+ rgb_row: Float32Array;
57
+ /** @type {number} */
58
+ row_width: number;
59
+ /**
60
+ * @param {number} width
61
+ */
62
+ resize_rows(width: number): void;
63
+ }
64
+ import { Av1FrameContext } from "../av1/decode/Av1FrameContext.js";
65
+ import { YuvImage } from "../color/YuvImage.js";
66
+ import { ColourTransform } from "../color/ColourTransform.js";
67
+ //# sourceMappingURL=AvifDecoder.d.ts.map