ranger-compiler 3.5.0 → 3.5.2

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 (338) hide show
  1. package/CHANGELOG.md +1160 -19
  2. package/LICENSE +3 -1
  3. package/README.md +124 -29
  4. package/dist/Lang.rgr +1188 -290
  5. package/dist/api.d.ts +2343 -879
  6. package/dist/api.js +79924 -56922
  7. package/dist/lib/JSON.rgr +102 -91
  8. package/dist/lib/Shell.rgr +4 -4
  9. package/dist/lib/apple/AppleToolchain.rgr +4 -4
  10. package/dist/lib/apple/README.md +5 -4
  11. package/dist/lib/apple/apple_test.rgr +1 -1
  12. package/dist/lib/core/README.md +1 -1
  13. package/dist/lib/evg/EVG.rgr +12 -0
  14. package/dist/lib/evg/EVGA11yFromTree.rgr +302 -0
  15. package/dist/lib/evg/EVGA11yTree.rgr +894 -0
  16. package/dist/lib/evg/EVGBox.rgr +267 -0
  17. package/dist/lib/evg/EVGBoxShorthandTest.rgr +220 -0
  18. package/dist/lib/evg/EVGCodepoint.rgr +316 -0
  19. package/dist/lib/evg/EVGColor.rgr +700 -0
  20. package/dist/lib/evg/EVGCommands.rgr +177 -0
  21. package/dist/lib/evg/EVGComponent.rgr +331 -0
  22. package/dist/lib/evg/EVGComponentTest.rgr +387 -0
  23. package/dist/lib/evg/EVGConnector.rgr +541 -0
  24. package/dist/lib/evg/EVGConnectorTest.rgr +306 -0
  25. package/dist/lib/evg/EVGDisplayList.rgr +4186 -0
  26. package/dist/lib/evg/EVGEasing.rgr +370 -0
  27. package/dist/lib/evg/EVGEffectTest.rgr +253 -0
  28. package/dist/lib/evg/EVGElement.rgr +4914 -0
  29. package/dist/lib/evg/EVGFixedTest.rgr +289 -0
  30. package/dist/lib/evg/EVGFlexRulesTest.rgr +317 -0
  31. package/dist/lib/evg/EVGFlexWrapTest.rgr +246 -0
  32. package/dist/lib/evg/EVGFling.rgr +244 -0
  33. package/dist/lib/evg/EVGFocus.rgr +400 -0
  34. package/dist/lib/evg/EVGFocusTest.rgr +399 -0
  35. package/dist/lib/evg/EVGGradient.rgr +322 -0
  36. package/dist/lib/evg/EVGGrapheme.rgr +190 -0
  37. package/dist/lib/evg/EVGGrid.rgr +975 -0
  38. package/dist/lib/evg/EVGHitTest.rgr +208 -0
  39. package/dist/lib/evg/EVGHoles.rgr +294 -0
  40. package/dist/lib/evg/EVGHostMeasurerTest.rgr +281 -0
  41. package/dist/lib/evg/EVGHostTextMeasurer.rgr +331 -0
  42. package/dist/lib/evg/EVGHostTree.rgr +834 -0
  43. package/dist/lib/evg/EVGHostTreeTest.rgr +447 -0
  44. package/dist/lib/evg/EVGImageDecode.rgr +117 -0
  45. package/dist/lib/evg/EVGImageMeasurer.rgr +86 -0
  46. package/dist/lib/evg/EVGInspect.rgr +883 -0
  47. package/dist/lib/evg/EVGInvalidateTest.rgr +432 -0
  48. package/dist/lib/evg/EVGJsonTest.rgr +535 -0
  49. package/dist/lib/evg/EVGLayout.rgr +4220 -0
  50. package/dist/lib/evg/EVGMeasure.rgr +1267 -0
  51. package/dist/lib/evg/EVGOverlayTest.rgr +626 -0
  52. package/dist/lib/evg/EVGPatch.rgr +1721 -0
  53. package/dist/lib/evg/EVGPatchTest.rgr +692 -0
  54. package/dist/lib/evg/EVGPopoverTest.rgr +395 -0
  55. package/dist/lib/evg/EVGReconcile.rgr +226 -0
  56. package/dist/lib/evg/EVGReconcileTest.rgr +421 -0
  57. package/dist/lib/evg/EVGReject.rgr +126 -0
  58. package/dist/lib/evg/EVGRelayoutTest.rgr +375 -0
  59. package/dist/lib/evg/EVGRtlLayoutTest.rgr +319 -0
  60. package/dist/lib/evg/EVGRuler.rgr +232 -0
  61. package/dist/lib/evg/EVGRulerTest.rgr +172 -0
  62. package/dist/lib/evg/EVGSelectChrome.rgr +178 -0
  63. package/dist/lib/evg/EVGStyleCacheTest.rgr +419 -0
  64. package/dist/lib/evg/EVGStyleSheet.rgr +2148 -0
  65. package/dist/lib/evg/EVGStyleStateTest.rgr +407 -0
  66. package/dist/lib/evg/EVGStyleVarTest.rgr +471 -0
  67. package/dist/lib/evg/EVGText.rgr +105 -0
  68. package/dist/lib/evg/EVGTextEngine.rgr +536 -0
  69. package/dist/lib/evg/EVGTextMeasurer.rgr +720 -0
  70. package/dist/lib/evg/EVGTimingTest.rgr +1417 -0
  71. package/dist/lib/evg/EVGToolbar.rgr +1369 -0
  72. package/dist/lib/evg/EVGTransition.rgr +728 -0
  73. package/dist/lib/evg/EVGTreeJson.rgr +721 -0
  74. package/dist/lib/evg/EVGUnit.rgr +554 -0
  75. package/dist/lib/evg/EVGViewportUnitTest.rgr +236 -0
  76. package/dist/lib/evg/EvgApp.rgr +189 -0
  77. package/dist/lib/evg/EvgBitmapTracer.rgr +4277 -0
  78. package/dist/lib/evg/EvgBitmapTracerTest.rgr +2119 -0
  79. package/dist/lib/evg/EvgHost.rgr +451 -0
  80. package/dist/lib/evg/EvgTest.rgr +91 -0
  81. package/dist/lib/evg/EvgTraceColor.rgr +236 -0
  82. package/dist/lib/evg/EvgTraceCurve.rgr +648 -0
  83. package/dist/lib/evg/EvgTraceFit.rgr +767 -0
  84. package/dist/lib/evg/EvgTracePath.rgr +435 -0
  85. package/dist/lib/evg/EvgTraceTypes.rgr +559 -0
  86. package/dist/lib/evg/EvgViewport.rgr +313 -0
  87. package/dist/lib/evg/FxDemoDoc.rgr +185 -0
  88. package/dist/lib/evg/HOSTS.md +227 -0
  89. package/dist/lib/evg/ISSUES.md +835 -0
  90. package/dist/lib/evg/PLAN_ACCESSIBILITY.md +650 -0
  91. package/dist/lib/evg/PLAN_CSS_LAYOUT_AND_FONTS.md +1124 -0
  92. package/dist/lib/evg/PLAN_EFFECTS.md +431 -0
  93. package/dist/lib/evg/PLAN_EVG.md +518 -0
  94. package/dist/lib/evg/PLAN_EVG_RENDERER.md +1674 -0
  95. package/dist/lib/evg/PLAN_INSPECTOR.md +788 -0
  96. package/dist/lib/evg/PLAN_LINKS_AND_FORMS.md +157 -0
  97. package/dist/lib/evg/PLAN_NATIVE_HOSTS.md +671 -0
  98. package/dist/lib/evg/PLAN_VECTOR_IR.md +664 -0
  99. package/dist/lib/evg/PLAN_VIEW_TRANSFORM.md +322 -0
  100. package/dist/lib/evg/PathBuilder.rgr +333 -0
  101. package/dist/lib/evg/README.md +1236 -0
  102. package/dist/lib/evg/SPEC.md +1252 -0
  103. package/dist/lib/evg/SVGPathParser.rgr +1199 -0
  104. package/dist/lib/evg/SvgParser.rgr +1736 -0
  105. package/dist/lib/evg/TODO_EVG_RENDERER.md +595 -0
  106. package/dist/lib/evg/VectorShapes.rgr +331 -0
  107. package/dist/lib/evg/VectorStroke.rgr +107 -0
  108. package/dist/lib/evg/VectorViewBox.rgr +380 -0
  109. package/dist/lib/evg/agent/README.md +290 -0
  110. package/dist/lib/evg/agent/evg_agent.rgr +899 -0
  111. package/dist/lib/evg/agent/fixtures/broken.evg.json +7 -0
  112. package/dist/lib/evg/agent/fixtures/card.evg.json +9 -0
  113. package/dist/lib/evg/agent/fixtures/connector.css +63 -0
  114. package/dist/lib/evg/agent/fixtures/connector.evg.json +14 -0
  115. package/dist/lib/evg/agent/fixtures/drawn.evg.json +129 -0
  116. package/dist/lib/evg/agent/fixtures/gradient.evg.json +4 -0
  117. package/dist/lib/evg/agent/fixtures/popover.css +99 -0
  118. package/dist/lib/evg/agent/fixtures/popover.evg.json +30 -0
  119. package/dist/lib/evg/agent/roundtrip.sh +74 -0
  120. package/dist/lib/evg/agent/smoke.sh +230 -0
  121. package/dist/lib/evg/android/README.md +97 -0
  122. package/dist/lib/evg/android/androidstubs/AndroidStubs.kt +175 -0
  123. package/dist/lib/evg/android/androidstubs/Annotation.kt +10 -0
  124. package/dist/lib/evg/android/androidstubs/App.kt +30 -0
  125. package/dist/lib/evg/android/androidstubs/Content.kt +41 -0
  126. package/dist/lib/evg/android/androidstubs/ContentRes.kt +12 -0
  127. package/dist/lib/evg/android/androidstubs/InputMethod.kt +46 -0
  128. package/dist/lib/evg/android/androidstubs/Net.kt +6 -0
  129. package/dist/lib/evg/android/androidstubs/Os.kt +30 -0
  130. package/dist/lib/evg/android/androidstubs/Util.kt +15 -0
  131. package/dist/lib/evg/android/androidstubs/View.kt +113 -0
  132. package/dist/lib/evg/android/androidstubs/Widget.kt +16 -0
  133. package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidEvgSurface.kt +323 -0
  134. package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/AndroidTextMeasurer.kt +56 -0
  135. package/dist/lib/evg/android/src/android/kotlin/fi/ranger/evg/RippleEffect.kt +262 -0
  136. package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtEvgSurface.kt +238 -0
  137. package/dist/lib/evg/android/src/awt/kotlin/fi/ranger/evg/AwtTextMeasurer.kt +85 -0
  138. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgEngineThread.kt +115 -0
  139. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgPainter.kt +231 -0
  140. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/EvgSurface.kt +117 -0
  141. package/dist/lib/evg/android/src/main/kotlin/fi/ranger/evg/RecordingSurface.kt +94 -0
  142. package/dist/lib/evg/apple/README.md +128 -0
  143. package/dist/lib/evg/apple/Sources/CoreGraphicsEvgSurface.swift +329 -0
  144. package/dist/lib/evg/apple/Sources/CoreTextMeasurer.swift +70 -0
  145. package/dist/lib/evg/apple/Sources/EvgEngineQueue.swift +105 -0
  146. package/dist/lib/evg/apple/Sources/EvgPainter.swift +225 -0
  147. package/dist/lib/evg/apple/Sources/EvgSurface.swift +163 -0
  148. package/dist/lib/evg/apple/Sources/RecordingSurface.swift +110 -0
  149. package/dist/lib/evg/bench/EvgLayoutBench.rgr +34 -0
  150. package/dist/lib/evg/bench/README.md +64 -0
  151. package/dist/lib/evg/bench/layout-bench.mjs +316 -0
  152. package/dist/lib/evg/bench/layout-cases.mjs +510 -0
  153. package/dist/lib/evg/bench/layout-conformance.mjs +254 -0
  154. package/dist/lib/evg/bin/.gitignore +17 -0
  155. package/dist/lib/evg/evg_test.rgr +313 -0
  156. package/dist/lib/evg/gl/README.md +198 -0
  157. package/dist/lib/evg/gl/a11y-paint-check.mjs +73 -0
  158. package/dist/lib/evg/gl/blur-check.mjs +399 -0
  159. package/dist/lib/evg/gl/boxmodel.json +1 -0
  160. package/dist/lib/evg/gl/demo.html +46 -0
  161. package/dist/lib/evg/gl/effect-presets.css +285 -0
  162. package/dist/lib/evg/gl/effect-presets.js +63 -0
  163. package/dist/lib/evg/gl/effect-shots.mjs +135 -0
  164. package/dist/lib/evg/gl/evg-a11y.js +566 -0
  165. package/dist/lib/evg/gl/evg-binary.js +160 -0
  166. package/dist/lib/evg/gl/evg-engine.js +296 -0
  167. package/dist/lib/evg/gl/evg-fx.js +237 -0
  168. package/dist/lib/evg/gl/evg-gestures.js +209 -0
  169. package/dist/lib/evg/gl/evg-list.js +167 -0
  170. package/dist/lib/evg/gl/evg-measure.js +186 -0
  171. package/dist/lib/evg/gl/evg-textinput.js +303 -0
  172. package/dist/lib/evg/gl/evg-view.js +144 -0
  173. package/dist/lib/evg/gl/evg-webgl.js +3942 -0
  174. package/dist/lib/evg/gl/fx-check.mjs +998 -0
  175. package/dist/lib/evg/gl/fx-demo.html +166 -0
  176. package/dist/lib/evg/gl/fx-demo.js +2 -0
  177. package/dist/lib/evg/gl/fx-serve.mjs +47 -0
  178. package/dist/lib/evg/gl/gestures-check.mjs +189 -0
  179. package/dist/lib/evg/gl/list-binary-check.mjs +152 -0
  180. package/dist/lib/evg/gl/measure-check.mjs +135 -0
  181. package/dist/lib/evg/gl/rotation-check.mjs +207 -0
  182. package/dist/lib/evg/gl/shift-check.mjs +113 -0
  183. package/dist/lib/evg/gl/stroke-check.mjs +168 -0
  184. package/dist/lib/evg/gl/text-snap-check.mjs +139 -0
  185. package/dist/lib/evg/gl/view-check.mjs +343 -0
  186. package/dist/lib/evg/gl/view-policy-check.mjs +184 -0
  187. package/dist/lib/evg/html/evg-dom.js +318 -0
  188. package/dist/lib/evg/html/evg-html.js +600 -0
  189. package/dist/lib/evg/inspect/README.md +415 -0
  190. package/dist/lib/evg/inspect/browser-smoke.mjs +115 -0
  191. package/dist/lib/evg/inspect/evg-inspect.js +947 -0
  192. package/dist/lib/evg/inspect/shots/css.png +0 -0
  193. package/dist/lib/evg/inspect/shots/dashboard.png +0 -0
  194. package/dist/lib/evg/inspect/shots/pptx-slide.png +0 -0
  195. package/dist/lib/evg/inspect/shots/state.png +0 -0
  196. package/dist/lib/evg/inspect/shots.mjs +226 -0
  197. package/dist/lib/evg/oracle/css-blur.json +576 -0
  198. package/dist/lib/evg/oracle/css-box.json +157 -0
  199. package/dist/lib/evg/oracle/css-timing.json +709 -0
  200. package/dist/lib/evg/oracle/css_blur_oracle.mjs +529 -0
  201. package/dist/lib/evg/oracle/css_box_oracle.mjs +106 -0
  202. package/dist/lib/evg/oracle/css_timing_oracle.mjs +389 -0
  203. package/dist/lib/evg/original/EVGColor.clj +310 -0
  204. package/dist/lib/evg/original/EVGColorContext.rgr +178 -0
  205. package/dist/lib/evg/original/SVGPath.rgr +627 -0
  206. package/dist/lib/evg/original/Vec2.crgr +103 -0
  207. package/dist/lib/evg/ranger.json +9 -0
  208. package/dist/lib/evg/showcase/README.md +246 -0
  209. package/dist/lib/evg/showcase/assets/emblem.svg +30 -0
  210. package/dist/lib/evg/showcase/assets/rosette.svg +22 -0
  211. package/dist/lib/evg/showcase/build.mjs +651 -0
  212. package/dist/lib/evg/showcase/pages/album.tsx +30 -0
  213. package/dist/lib/evg/showcase/pages/boxmodel.tsx +37 -0
  214. package/dist/lib/evg/showcase/pages/cards.tsx +41 -0
  215. package/dist/lib/evg/showcase/pages/chart_api.tsx +170 -0
  216. package/dist/lib/evg/showcase/pages/charts.tsx +219 -0
  217. package/dist/lib/evg/showcase/pages/drawing.tsx +160 -0
  218. package/dist/lib/evg/showcase/pages/emoji.tsx +91 -0
  219. package/dist/lib/evg/showcase/pages/flex.tsx +46 -0
  220. package/dist/lib/evg/showcase/pages/more.tsx +332 -0
  221. package/dist/lib/evg/showcase/pages/plots.tsx +262 -0
  222. package/dist/lib/evg/showcase/pages/svg.tsx +63 -0
  223. package/dist/lib/evg/showcase/pages/tables.tsx +209 -0
  224. package/dist/lib/evg/showcase/pages/typography.tsx +43 -0
  225. package/dist/lib/evg/showcase/pages/units.tsx +35 -0
  226. package/dist/lib/evg/showcase/pages/variants.tsx +233 -0
  227. package/dist/lib/evg/showcase/pages/vector.tsx +75 -0
  228. package/dist/lib/evg/showcase/pages/views.tsx +223 -0
  229. package/dist/lib/evg/showcase/tests/chart_api_smoke.mjs +339 -0
  230. package/dist/lib/evg/showcase/tests/gl_smoke.mjs +125 -0
  231. package/dist/lib/evg/showcase/themes/chart_api-default.css +15 -0
  232. package/dist/lib/evg/showcase/themes/charts-default.css +29 -0
  233. package/dist/lib/evg/showcase/themes/drawing-default.css +35 -0
  234. package/dist/lib/evg/showcase/themes/more-default.css +128 -0
  235. package/dist/lib/evg/showcase/themes/plots-default.css +18 -0
  236. package/dist/lib/evg/showcase/themes/showcase.css +508 -0
  237. package/dist/lib/evg/showcase/themes/tables-default.css +123 -0
  238. package/dist/lib/evg/showcase/themes/variants-default.css +15 -0
  239. package/dist/lib/evg/showcase/themes/views-default.css +15 -0
  240. package/dist/lib/evg/tools/bench_vs_potrace.mjs +290 -0
  241. package/dist/lib/evg/tools/evg_image_tool.rgr +488 -0
  242. package/dist/lib/evg/tools/evg_trace_bench.rgr +114 -0
  243. package/dist/lib/evg/tools/evg_trace_cli.rgr +662 -0
  244. package/dist/lib/evg/tools/evg_trace_cpp_bench.rgr +83 -0
  245. package/dist/lib/evg/tools/run_trace_bench.sh +74 -0
  246. package/dist/lib/evg/tools/run_trace_cli_smoke.sh +128 -0
  247. package/dist/lib/evg/web/responsive/EvgResponsiveCheck.rgr +271 -0
  248. package/dist/lib/evg/web/responsive/EvgResponsiveDemo.rgr +531 -0
  249. package/dist/lib/evg/web/responsive/README.md +97 -0
  250. package/dist/lib/evg/web/responsive/build.mjs +90 -0
  251. package/dist/lib/evg/web/responsive/dom-check.mjs +169 -0
  252. package/dist/lib/evg/web/responsive/index.html +177 -0
  253. package/dist/lib/evg/web/responsive/smoke.mjs +221 -0
  254. package/dist/lib/evg/web/tools/assets-client.mjs +95 -0
  255. package/dist/lib/evg/web/tools/boot-bench.mjs +189 -0
  256. package/dist/lib/evg/web/tools/inline-assets.mjs +119 -0
  257. package/dist/lib/evg/web/tools/minify.mjs +60 -0
  258. package/dist/lib/evg/web/tracer/build.mjs +87 -0
  259. package/dist/lib/evg/web/tracer/index.html +2805 -0
  260. package/dist/lib/evg/web/tracer/sample.png +0 -0
  261. package/dist/lib/evg/web/tracer/smoke.mjs +1162 -0
  262. package/dist/lib/evgr/Cargo.lock +21 -0
  263. package/dist/lib/evgr/Cargo.toml +19 -0
  264. package/dist/lib/evgr/README.md +140 -0
  265. package/dist/lib/evgr/bench/NativeBench.rgr +246 -0
  266. package/dist/lib/evgr/bench/compare.mjs +252 -0
  267. package/dist/lib/evgr/bench/speed.mjs +277 -0
  268. package/dist/lib/evgr/bin/.gitignore +3 -0
  269. package/dist/lib/evgr/src/bin/bench.rs +106 -0
  270. package/dist/lib/evgr/src/bin/smoke.rs +13 -0
  271. package/dist/lib/evgr/src/grid.rs +730 -0
  272. package/dist/lib/evgr/src/lib.rs +1003 -0
  273. package/dist/lib/evgr/src/style.rs +468 -0
  274. package/dist/lib/evgr/src/text.rs +83 -0
  275. package/dist/lib/image/BitReader.rgr +171 -0
  276. package/dist/lib/image/Buffer.rgr +173 -0
  277. package/dist/lib/image/DCT.rgr +283 -0
  278. package/dist/lib/image/Deflate.rgr +339 -0
  279. package/dist/lib/image/HuffmanDecoder.rgr +181 -0
  280. package/dist/lib/image/ImageBuffer.rgr +706 -0
  281. package/dist/lib/image/JPEGDecoder.rgr +808 -0
  282. package/dist/lib/image/PNGDecoder.rgr +544 -0
  283. package/dist/lib/image/PNGEncoder.rgr +388 -0
  284. package/dist/lib/image/PPMImage.rgr +224 -0
  285. package/dist/lib/image/ProgressiveJPEGDecoder.rgr +1154 -0
  286. package/dist/lib/image/README.md +33 -0
  287. package/dist/lib/image/RasterBuffer.rgr +294 -0
  288. package/dist/lib/image/VP8BoolDecoder.rgr +163 -0
  289. package/dist/lib/image/WebPDecoder.rgr +433 -0
  290. package/dist/lib/image/WebPLossless.rgr +1035 -0
  291. package/dist/lib/image/WebPLossy.rgr +1929 -0
  292. package/dist/lib/image/ranger.json +9 -0
  293. package/dist/lib/image/testdata/webp/anim_2f_24x16.webp +0 -0
  294. package/dist/lib/image/testdata/webp/fixtures.txt +33 -0
  295. package/dist/lib/image/testdata/webp/gen_fixtures.py +261 -0
  296. package/dist/lib/image/testdata/webp/ll_1x1.webp +0 -0
  297. package/dist/lib/image/testdata/webp/ll_alpha_29x21.webp +0 -0
  298. package/dist/lib/image/testdata/webp/ll_gradient_64x64.webp +0 -0
  299. package/dist/lib/image/testdata/webp/ll_meta_32x32.webp +0 -0
  300. package/dist/lib/image/testdata/webp/ll_noise_17x9.webp +0 -0
  301. package/dist/lib/image/testdata/webp/ll_pal11_23x11.webp +0 -0
  302. package/dist/lib/image/testdata/webp/ll_pal2_19x7.webp +0 -0
  303. package/dist/lib/image/testdata/webp/ll_pal40_16x16.webp +0 -0
  304. package/dist/lib/image/testdata/webp/ll_pal4_13x5.webp +0 -0
  305. package/dist/lib/image/testdata/webp/ll_photo_40x30.webp +0 -0
  306. package/dist/lib/image/testdata/webp/ll_predictors_64x32.webp +0 -0
  307. package/dist/lib/image/testdata/webp/ly_1x1.webp +0 -0
  308. package/dist/lib/image/testdata/webp/ly_alph_raw_f0_21x13.webp +0 -0
  309. package/dist/lib/image/testdata/webp/ly_alph_raw_f1_21x13.webp +0 -0
  310. package/dist/lib/image/testdata/webp/ly_alph_raw_f2_21x13.webp +0 -0
  311. package/dist/lib/image/testdata/webp/ly_alph_raw_f3_21x13.webp +0 -0
  312. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f0_21x13.webp +0 -0
  313. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f1_21x13.webp +0 -0
  314. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f2_21x13.webp +0 -0
  315. package/dist/lib/image/testdata/webp/ly_alph_vp8l_f3_21x13.webp +0 -0
  316. package/dist/lib/image/testdata/webp/ly_alpha_33x17.webp +0 -0
  317. package/dist/lib/image/testdata/webp/ly_exif_15x11.webp +0 -0
  318. package/dist/lib/image/testdata/webp/ly_i16_96x80.webp +0 -0
  319. package/dist/lib/image/testdata/webp/ly_nofilter_24x20.webp +0 -0
  320. package/dist/lib/image/testdata/webp/ly_odd_17x9.webp +0 -0
  321. package/dist/lib/image/testdata/webp/ly_photo_48x40.webp +0 -0
  322. package/dist/lib/image/testdata/webp/ly_q100_20x18.webp +0 -0
  323. package/dist/lib/image/testdata/webp/ly_sharp_40x36.webp +0 -0
  324. package/dist/lib/image/testdata/webp/ly_simple_filter_33x31.webp +0 -0
  325. package/dist/lib/image/testdata/webp/ly_vpx_parts8_37x45.webp +0 -0
  326. package/dist/lib/image/testdata/webp/ly_vpx_skip_96x80.webp +0 -0
  327. package/dist/lib/image/tests/WebPDecodeTool.rgr +81 -0
  328. package/dist/lib/image/tests/WebPDecoderTest.rgr +1162 -0
  329. package/dist/lib/image/tests/run_webp_tests.sh +39 -0
  330. package/dist/lib/rust/RsJson.rgr +468 -0
  331. package/dist/lib/rust/RsPrelude.rgr +1663 -0
  332. package/dist/lib/shell_test.rgr +7 -7
  333. package/dist/lib/stdlib.rgr +21 -5
  334. package/dist/lib/zip/ranger.json +6 -0
  335. package/dist/rgrc.js +87318 -67610
  336. package/package.json +1010 -1040
  337. package/dist/README.md +0 -117
  338. package/dist/package.json +0 -47
@@ -0,0 +1,1035 @@
1
+ ; SPDX-License-Identifier: MIT
2
+
3
+ ; WebPLossless.rgr - the VP8L lossless bitstream of WebP (RFC 9649 section 3).
4
+ ;
5
+ ; Prefix codes (simple and normal), the color cache, backward references
6
+ ; with the distance map, meta prefix codes and the four transforms
7
+ ; (predictor with its 14 modes, cross-color, subtract-green, color indexing
8
+ ; with pixel bundling). Also decodes the headerless VP8L stream that carries
9
+ ; a compressed ALPH chunk.
10
+ ;
11
+ ; The decoding logic follows libwebp (src/dec/vp8l_dec.c,
12
+ ; src/utils/huffman_utils.c, src/dsp/lossless.c), Copyright Google Inc.,
13
+ ; BSD-3-Clause; this port is MIT like the rest of lib/image.
14
+ ;
15
+ ; Pixels are packed ARGB in one int each: (a << 24) | (r << 16) | (g << 8) | b,
16
+ ; so a pixel with alpha >= 128 is negative. Every packed value is built and
17
+ ; taken apart with bit operations only, which agree between the 32-bit
18
+ ; integers of JavaScript and of the C++ target.
19
+
20
+ class VP8LDecoder {
21
+ ; ---- bit reader: least significant bit first, at most 24 bits buffered
22
+ def data:buffer (buffer_alloc 0)
23
+ def dataLen:int 0
24
+ def pos:int 0
25
+ def bitBuf:int 0
26
+ def bitCnt:int 0
27
+ def padBits:int 0
28
+ def eos:boolean false
29
+
30
+ ; ---- prefix code tables of the image level being decoded
31
+ ; Each code is a root table of 2^rootBits entries followed by its second
32
+ ; level tables. An entry is (length << 16) | symbol, or for a root entry
33
+ ; that continues in a second level table ((16 + subBits) << 16) | offset.
34
+ def tables:int_buffer (int_buffer_alloc 4096)
35
+ def tablesUsed:int 0
36
+ def maxTableEntries:int 16777216
37
+
38
+ def error:string ""
39
+ def width:int 0
40
+ def height:int 0
41
+ def hasAlpha:boolean false
42
+ def argb:int_buffer (int_buffer_alloc 0)
43
+ def maxPixels:int 100000000
44
+
45
+ ; ---- what the last stream used (read by the tests)
46
+ def statTransforms:int 0
47
+ def statPredModes:int 0
48
+ def statCacheBits:int 0
49
+ def statGroups:int 0
50
+ def statSimpleCodes:int 0
51
+ def statNormalCodes:int 0
52
+ def statBackRefs:int 0
53
+ def statCacheHits:int 0
54
+ def statBundleBits:int -1
55
+
56
+ Constructor () {
57
+ }
58
+
59
+ fn fail:boolean (msg:string) {
60
+ if ((strlen error) == 0) {
61
+ error = msg
62
+ }
63
+ return false
64
+ }
65
+
66
+ ; ======================================================================
67
+ ; Bit reader
68
+ ; ======================================================================
69
+
70
+ fn initBits:void (src:buffer start:int size:int) {
71
+ def srcLen:int (buffer_length src)
72
+ def s:int start
73
+ if (s < 0) {
74
+ s = 0
75
+ }
76
+ if (s > srcLen) {
77
+ s = srcLen
78
+ }
79
+ def e:int (s + size)
80
+ if (size < 0) {
81
+ e = s
82
+ }
83
+ if (e > srcLen) {
84
+ e = srcLen
85
+ }
86
+ data = (buffer_slice src s e)
87
+ dataLen = (e - s)
88
+ pos = 0
89
+ bitBuf = 0
90
+ bitCnt = 0
91
+ padBits = 0
92
+ eos = false
93
+ }
94
+
95
+ fn fill:void () {
96
+ while (bitCnt <= 16) {
97
+ def b:int 0
98
+ if (pos < dataLen) {
99
+ b = (buffer_get data pos)
100
+ pos = pos + 1
101
+ } {
102
+ padBits = padBits + 8
103
+ }
104
+ bitBuf = (bit_or bitBuf (bit_shl b bitCnt))
105
+ bitCnt = bitCnt + 8
106
+ }
107
+ }
108
+
109
+ fn readBits16:int (n:int) {
110
+ if (bitCnt < n) {
111
+ this.fill()
112
+ }
113
+ def v:int (bit_and bitBuf ((bit_shl 1 n) - 1))
114
+ bitBuf = (bit_shr bitBuf n)
115
+ bitCnt = bitCnt - n
116
+ if (bitCnt < padBits) {
117
+ eos = true
118
+ }
119
+ return v
120
+ }
121
+
122
+ ; n bits, 0 <= n <= 24
123
+ fn readBits:int (n:int) {
124
+ if (n <= 16) {
125
+ return (this.readBits16(n))
126
+ }
127
+ def lo:int (this.readBits16(16))
128
+ def hi:int (this.readBits16((n - 16)))
129
+ return (bit_or lo (bit_shl hi 16))
130
+ }
131
+
132
+ ; ======================================================================
133
+ ; Prefix codes
134
+ ; ======================================================================
135
+
136
+ fn reserveTables:boolean (n:int) {
137
+ def need:int (tablesUsed + n)
138
+ if (need > maxTableEntries) {
139
+ return (this.fail("prefix code tables too large"))
140
+ }
141
+ def cap:int (int_buffer_length tables)
142
+ if (need <= cap) {
143
+ return true
144
+ }
145
+ def newCap:int (cap * 2)
146
+ while (newCap < need) {
147
+ newCap = newCap * 2
148
+ }
149
+ def grown:int_buffer (int_buffer_alloc newCap)
150
+ int_buffer_copy grown 0 tables 0 tablesUsed
151
+ tables = grown
152
+ return true
153
+ }
154
+
155
+ sfn reverseBits:int (code:int len:int) {
156
+ def r:int 0
157
+ def i:int 0
158
+ def c:int code
159
+ while (i < len) {
160
+ r = (bit_or (bit_shl r 1) (bit_and c 1))
161
+ c = (bit_shr c 1)
162
+ i = i + 1
163
+ }
164
+ return r
165
+ }
166
+
167
+ ; Builds the decoding table for code lengths[0..n-1] and returns
168
+ ; (offset << 4) | rootBits, or -1 when the lengths do not form a complete
169
+ ; prefix code. A code with one used symbol reads zero bits.
170
+ fn buildCode:int (lengths:int_buffer n:int) {
171
+ def count:int_buffer (int_buffer_alloc 16)
172
+ def s:int 0
173
+ def used:int 0
174
+ def lastSym:int 0
175
+ def maxLen:int 0
176
+ while (s < n) {
177
+ def l:int (int_buffer_get lengths s)
178
+ if ((l < 0) || (l > 15)) {
179
+ return -1
180
+ }
181
+ if (l > 0) {
182
+ int_buffer_set count l ((int_buffer_get count l) + 1)
183
+ used = used + 1
184
+ lastSym = s
185
+ if (l > maxLen) {
186
+ maxLen = l
187
+ }
188
+ }
189
+ s = s + 1
190
+ }
191
+ if (used == 0) {
192
+ return -1
193
+ }
194
+ if (used == 1) {
195
+ if ((this.reserveTables(1)) == false) {
196
+ return -1
197
+ }
198
+ def one:int tablesUsed
199
+ int_buffer_set tables one lastSym
200
+ tablesUsed = tablesUsed + 1
201
+ return (bit_shl one 4)
202
+ }
203
+ ; complete and not over-subscribed
204
+ def open:int 1
205
+ def len:int 1
206
+ while (len <= 15) {
207
+ open = (open * 2) - (int_buffer_get count len)
208
+ if (open < 0) {
209
+ return -1
210
+ }
211
+ len = len + 1
212
+ }
213
+ if (open != 0) {
214
+ return -1
215
+ }
216
+ ; canonical first code of each length
217
+ def nextCode:int_buffer (int_buffer_alloc 16)
218
+ def code:int 0
219
+ len = 1
220
+ while (len <= 15) {
221
+ code = (bit_shl (code + (int_buffer_get count (len - 1))) 1)
222
+ if (len == 1) {
223
+ code = 0
224
+ }
225
+ int_buffer_set nextCode len code
226
+ len = len + 1
227
+ }
228
+ def rootBits:int maxLen
229
+ if (rootBits > 8) {
230
+ rootBits = 8
231
+ }
232
+ def rootSize:int (bit_shl 1 rootBits)
233
+ def rootMask:int (rootSize - 1)
234
+ ; bit-reversed code per symbol, and the depth of each second level table
235
+ def rev:int_buffer (int_buffer_alloc n)
236
+ def subBits:int_buffer (int_buffer_alloc rootSize)
237
+ s = 0
238
+ while (s < n) {
239
+ def l:int (int_buffer_get lengths s)
240
+ if (l > 0) {
241
+ def c:int (int_buffer_get nextCode l)
242
+ int_buffer_set nextCode l (c + 1)
243
+ def r:int (VP8LDecoder.reverseBits(c l))
244
+ int_buffer_set rev s r
245
+ if (l > rootBits) {
246
+ def p:int (bit_and r rootMask)
247
+ if ((l - rootBits) > (int_buffer_get subBits p)) {
248
+ int_buffer_set subBits p (l - rootBits)
249
+ }
250
+ }
251
+ }
252
+ s = s + 1
253
+ }
254
+ def total:int rootSize
255
+ def p:int 0
256
+ while (p < rootSize) {
257
+ def sb:int (int_buffer_get subBits p)
258
+ if (sb > 0) {
259
+ total = total + (bit_shl 1 sb)
260
+ }
261
+ p = p + 1
262
+ }
263
+ if ((this.reserveTables(total)) == false) {
264
+ return -1
265
+ }
266
+ def base:int tablesUsed
267
+ tablesUsed = tablesUsed + total
268
+ def subOffset:int_buffer (int_buffer_alloc rootSize)
269
+ def off:int rootSize
270
+ p = 0
271
+ while (p < rootSize) {
272
+ def sb:int (int_buffer_get subBits p)
273
+ if (sb > 0) {
274
+ int_buffer_set subOffset p off
275
+ int_buffer_set tables (base + p) (bit_or (bit_shl (16 + sb) 16) off)
276
+ off = off + (bit_shl 1 sb)
277
+ }
278
+ p = p + 1
279
+ }
280
+ s = 0
281
+ while (s < n) {
282
+ def l:int (int_buffer_get lengths s)
283
+ if (l > 0) {
284
+ def r:int (int_buffer_get rev s)
285
+ def entry:int (bit_or (bit_shl l 16) s)
286
+ if (l <= rootBits) {
287
+ def step:int (bit_shl 1 l)
288
+ def i:int r
289
+ while (i < rootSize) {
290
+ int_buffer_set tables (base + i) entry
291
+ i = i + step
292
+ }
293
+ } {
294
+ def pfx:int (bit_and r rootMask)
295
+ def sb:int (int_buffer_get subBits pfx)
296
+ def sub:int (base + (int_buffer_get subOffset pfx))
297
+ def step:int (bit_shl 1 (l - rootBits))
298
+ def subSize:int (bit_shl 1 sb)
299
+ def i:int (bit_shr r rootBits)
300
+ while (i < subSize) {
301
+ int_buffer_set tables (sub + i) entry
302
+ i = i + step
303
+ }
304
+ }
305
+ }
306
+ s = s + 1
307
+ }
308
+ return (bit_or (bit_shl base 4) rootBits)
309
+ }
310
+
311
+ ; Reads one symbol with the code built by buildCode.
312
+ fn readSymbol:int (code:int) {
313
+ def base:int (bit_shr code 4)
314
+ def rootBits:int (bit_and code 15)
315
+ if (rootBits == 0) {
316
+ return (int_buffer_get tables base)
317
+ }
318
+ if (bitCnt < 15) {
319
+ this.fill()
320
+ }
321
+ def e:int (int_buffer_get tables (base + (bit_and bitBuf ((bit_shl 1 rootBits) - 1))))
322
+ def l:int (bit_shr e 16)
323
+ if (l > 15) {
324
+ def sb:int (l - 16)
325
+ def idx:int (bit_and (bit_shr bitBuf rootBits) ((bit_shl 1 sb) - 1))
326
+ e = (int_buffer_get tables (base + (bit_and e 65535) + idx))
327
+ l = (bit_shr e 16)
328
+ }
329
+ bitBuf = (bit_shr bitBuf l)
330
+ bitCnt = bitCnt - l
331
+ if (bitCnt < padBits) {
332
+ eos = true
333
+ }
334
+ return (bit_and e 65535)
335
+ }
336
+
337
+ ; Reads one prefix code over an alphabet of alphabetSize symbols.
338
+ fn readCode:int (alphabetSize:int) {
339
+ def size:int alphabetSize
340
+ if (size < 256) {
341
+ size = 256
342
+ }
343
+ def lengths:int_buffer (int_buffer_alloc size)
344
+ def simple:int (this.readBits(1))
345
+ if (simple == 1) {
346
+ statSimpleCodes = statSimpleCodes + 1
347
+ def numSymbols:int ((this.readBits(1)) + 1)
348
+ def firstBits:int (this.readBits(1))
349
+ def s0:int 0
350
+ if (firstBits == 0) {
351
+ s0 = (this.readBits(1))
352
+ } {
353
+ s0 = (this.readBits(8))
354
+ }
355
+ int_buffer_set lengths s0 1
356
+ if (numSymbols == 2) {
357
+ def s1:int (this.readBits(8))
358
+ int_buffer_set lengths s1 1
359
+ }
360
+ } {
361
+ statNormalCodes = statNormalCodes + 1
362
+ if ((this.readCodeLengths(lengths alphabetSize)) == false) {
363
+ return -1
364
+ }
365
+ }
366
+ if eos {
367
+ this.fail("truncated prefix code")
368
+ return -1
369
+ }
370
+ def c:int (this.buildCode(lengths alphabetSize))
371
+ if (c < 0) {
372
+ this.fail("invalid prefix code")
373
+ }
374
+ return c
375
+ }
376
+
377
+ fn readCodeLengths:boolean (lengths:int_buffer numSymbols:int) {
378
+ def order:[int] ([] _:int (17 18 0 1 2 3 4 5 16 6 7 8 9 10 11 12 13 14 15))
379
+ def clen:int_buffer (int_buffer_alloc 19)
380
+ def numCodes:int ((this.readBits(4)) + 4)
381
+ def i:int 0
382
+ while (i < numCodes) {
383
+ int_buffer_set clen (itemAt order i) (this.readBits(3))
384
+ i = i + 1
385
+ }
386
+ def lenCode:int (this.buildCode(clen 19))
387
+ if (lenCode < 0) {
388
+ return (this.fail("invalid code length code"))
389
+ }
390
+ def maxSymbol:int numSymbols
391
+ if ((this.readBits(1)) == 1) {
392
+ def nbits:int (2 + (2 * (this.readBits(3))))
393
+ maxSymbol = 2 + (this.readBits(nbits))
394
+ if (maxSymbol > numSymbols) {
395
+ return (this.fail("code length count out of range"))
396
+ }
397
+ }
398
+ def prevLen:int 8
399
+ def symbol:int 0
400
+ while (symbol < numSymbols) {
401
+ if (maxSymbol == 0) {
402
+ break
403
+ }
404
+ maxSymbol = maxSymbol - 1
405
+ def codeLen:int (this.readSymbol(lenCode))
406
+ if eos {
407
+ return (this.fail("truncated code lengths"))
408
+ }
409
+ if (codeLen < 16) {
410
+ int_buffer_set lengths symbol codeLen
411
+ symbol = symbol + 1
412
+ if (codeLen != 0) {
413
+ prevLen = codeLen
414
+ }
415
+ } {
416
+ def repeat:int 0
417
+ def fillLen:int 0
418
+ if (codeLen == 16) {
419
+ repeat = (this.readBits(2)) + 3
420
+ fillLen = prevLen
421
+ }
422
+ if (codeLen == 17) {
423
+ repeat = (this.readBits(3)) + 3
424
+ }
425
+ if (codeLen == 18) {
426
+ repeat = (this.readBits(7)) + 11
427
+ }
428
+ if ((symbol + repeat) > numSymbols) {
429
+ return (this.fail("code length repeat out of range"))
430
+ }
431
+ while (repeat > 0) {
432
+ int_buffer_set lengths symbol fillLen
433
+ symbol = symbol + 1
434
+ repeat = repeat - 1
435
+ }
436
+ }
437
+ }
438
+ return true
439
+ }
440
+
441
+ ; ======================================================================
442
+ ; Entropy-coded image
443
+ ; ======================================================================
444
+
445
+ sfn subSampleSize:int (size:int bits:int) {
446
+ return (bit_shr (size + (bit_shl 1 bits) - 1) bits)
447
+ }
448
+
449
+ ; (0x1e35a7bd * argb) mod 2^32 >> (32 - bits), in pieces that stay
450
+ ; below 2^31 on a 32-bit int.
451
+ sfn hashPixel:int (argb:int bits:int) {
452
+ def lo:int (bit_and argb 65535)
453
+ def hi:int (bit_and (bit_ushr argb 16) 65535)
454
+ ; K = 0x1e35a7bd: high half 7733, low half 42941 = 167 * 256 + 189
455
+ def carry:int (bit_shr ((lo * 167) + (bit_shr (lo * 189) 8)) 8)
456
+ def mid:int ((bit_and (lo * 7733) 65535) + (bit_and ((bit_shl (bit_and (hi * 167) 255) 8) + (hi * 189)) 65535))
457
+ def top:int (bit_and (carry + mid) 65535)
458
+ return (bit_shr top (16 - bits))
459
+ }
460
+
461
+ ; distance / length prefix coding: symbol -> value (1-based)
462
+ fn copyDistance:int (sym:int) {
463
+ if (sym < 4) {
464
+ return (sym + 1)
465
+ }
466
+ def extra:int (bit_shr (sym - 2) 1)
467
+ def offset:int (bit_shl (2 + (bit_and sym 1)) extra)
468
+ return (offset + (this.readBits(extra)) + 1)
469
+ }
470
+
471
+ sfn planeCodeToDistance:int (xsize:int planeCode:int) {
472
+ if (planeCode > 120) {
473
+ return (planeCode - 120)
474
+ }
475
+ def codes:[int] ([] _:int (24 7 23 25 40 6 39 41 22 26 38 42 56 5 55 57 21 27 54 58 37 43 72 4 71 73 20 28 53 59 70 74 36 44 88 69 75 52 60 3 87 89 19 29 86 90 35 45 68 76 85 91 51 61 104 2 103 105 18 30 102 106 34 46 84 92 67 77 101 107 50 62 120 1 119 121 83 93 17 31 100 108 66 78 118 122 33 47 117 123 49 63 99 109 82 94 0 116 124 65 79 16 32 98 110 48 115 125 81 95 64 114 126 97 111 80 113 127 96 112))
476
+ def distCode:int (itemAt codes (planeCode - 1))
477
+ def yoffset:int (bit_shr distCode 4)
478
+ def xoffset:int (8 - (bit_and distCode 15))
479
+ def dist:int ((yoffset * xsize) + xoffset)
480
+ if (dist >= 1) {
481
+ return dist
482
+ }
483
+ return 1
484
+ }
485
+
486
+ ; Decodes one entropy-coded image of w x h pixels. The main image (the
487
+ ; last one of a level 0 stream) may carry meta prefix codes.
488
+ fn decodeImageData:int_buffer (w:int h:int isMain:boolean) {
489
+ def empty:int_buffer (int_buffer_alloc 0)
490
+ if ((w <= 0) || (h <= 0) || (((to_double w) * (to_double h)) > (to_double maxPixels))) {
491
+ this.fail("bad image size")
492
+ return empty
493
+ }
494
+ def total:int (w * h)
495
+ if (total <= 0) {
496
+ this.fail("bad image size")
497
+ return empty
498
+ }
499
+ ; color cache
500
+ def cacheBits:int 0
501
+ def cacheSize:int 0
502
+ if ((this.readBits(1)) == 1) {
503
+ cacheBits = (this.readBits(4))
504
+ if ((cacheBits < 1) || (cacheBits > 11)) {
505
+ this.fail("bad color cache size")
506
+ return empty
507
+ }
508
+ cacheSize = (bit_shl 1 cacheBits)
509
+ if (cacheBits > statCacheBits) {
510
+ statCacheBits = cacheBits
511
+ }
512
+ }
513
+ def cache:int_buffer (int_buffer_alloc (cacheSize + 1))
514
+ ; meta prefix codes
515
+ def metaBits:int 0
516
+ def metaW:int 0
517
+ def numGroups:int 1
518
+ def entropy:int_buffer (int_buffer_alloc 0)
519
+ if isMain {
520
+ if ((this.readBits(1)) == 1) {
521
+ metaBits = (this.readBits(3)) + 2
522
+ metaW = (VP8LDecoder.subSampleSize(w metaBits))
523
+ def metaH:int (VP8LDecoder.subSampleSize(h metaBits))
524
+ entropy = (this.decodeImageData(metaW metaH false))
525
+ if ((strlen error) > 0) {
526
+ return empty
527
+ }
528
+ def n:int (metaW * metaH)
529
+ def k:int 0
530
+ while (k < n) {
531
+ def g:int (bit_and (bit_shr (int_buffer_get entropy k) 8) 65535)
532
+ int_buffer_set entropy k g
533
+ if (g >= numGroups) {
534
+ numGroups = g + 1
535
+ }
536
+ k = k + 1
537
+ }
538
+ }
539
+ }
540
+ if eos {
541
+ this.fail("truncated image header")
542
+ return empty
543
+ }
544
+ if (numGroups > statGroups) {
545
+ statGroups = numGroups
546
+ }
547
+ ; the prefix codes of this image; earlier levels are done with theirs
548
+ tablesUsed = 0
549
+ def codes:int_buffer (int_buffer_alloc (numGroups * 5))
550
+ def gi:int 0
551
+ while (gi < numGroups) {
552
+ def k:int 0
553
+ while (k < 5) {
554
+ def alphabet:int 256
555
+ if (k == 0) {
556
+ alphabet = 280 + cacheSize
557
+ }
558
+ if (k == 4) {
559
+ alphabet = 40
560
+ }
561
+ def c:int (this.readCode(alphabet))
562
+ if (c < 0) {
563
+ return empty
564
+ }
565
+ int_buffer_set codes ((gi * 5) + k) c
566
+ k = k + 1
567
+ }
568
+ gi = gi + 1
569
+ }
570
+ ; pixels
571
+ def out:int_buffer (int_buffer_alloc total)
572
+ def i:int 0
573
+ def x:int 0
574
+ def y:int 0
575
+ def gbase:int 0
576
+ def colorLimit:int (280 + cacheSize)
577
+ def hasMeta:boolean (metaBits > 0)
578
+ while (i < total) {
579
+ if hasMeta {
580
+ gbase = (int_buffer_get entropy (((bit_shr y metaBits) * metaW) + (bit_shr x metaBits))) * 5
581
+ }
582
+ def code:int (this.readSymbol((int_buffer_get codes gbase)))
583
+ if (code < 256) {
584
+ def r:int (this.readSymbol((int_buffer_get codes (gbase + 1))))
585
+ def b:int (this.readSymbol((int_buffer_get codes (gbase + 2))))
586
+ def a:int (this.readSymbol((int_buffer_get codes (gbase + 3))))
587
+ def px:int (bit_or (bit_or (bit_shl a 24) (bit_shl r 16)) (bit_or (bit_shl code 8) b))
588
+ int_buffer_set out i px
589
+ if (cacheBits > 0) {
590
+ int_buffer_set cache (VP8LDecoder.hashPixel(px cacheBits)) px
591
+ }
592
+ i = i + 1
593
+ x = x + 1
594
+ if (x >= w) {
595
+ x = 0
596
+ y = y + 1
597
+ }
598
+ } {
599
+ if (code < 280) {
600
+ statBackRefs = statBackRefs + 1
601
+ def length:int (this.copyDistance((code - 256)))
602
+ def distSym:int (this.readSymbol((int_buffer_get codes (gbase + 4))))
603
+ def distCode:int (this.copyDistance(distSym))
604
+ def dist:int (VP8LDecoder.planeCodeToDistance(w distCode))
605
+ if eos {
606
+ this.fail("truncated image data")
607
+ return empty
608
+ }
609
+ if ((i < dist) || ((total - i) < length)) {
610
+ this.fail("backward reference out of range")
611
+ return empty
612
+ }
613
+ def k:int 0
614
+ while (k < length) {
615
+ def px:int (int_buffer_get out (i - dist))
616
+ int_buffer_set out i px
617
+ if (cacheBits > 0) {
618
+ int_buffer_set cache (VP8LDecoder.hashPixel(px cacheBits)) px
619
+ }
620
+ i = i + 1
621
+ k = k + 1
622
+ }
623
+ x = x + length
624
+ while (x >= w) {
625
+ x = x - w
626
+ y = y + 1
627
+ }
628
+ } {
629
+ if (code >= colorLimit) {
630
+ this.fail("bad symbol")
631
+ return empty
632
+ }
633
+ statCacheHits = statCacheHits + 1
634
+ int_buffer_set out i (int_buffer_get cache (code - 280))
635
+ i = i + 1
636
+ x = x + 1
637
+ if (x >= w) {
638
+ x = 0
639
+ y = y + 1
640
+ }
641
+ }
642
+ }
643
+ if eos {
644
+ this.fail("truncated image data")
645
+ return empty
646
+ }
647
+ }
648
+ return out
649
+ }
650
+
651
+ ; ======================================================================
652
+ ; Transforms
653
+ ; ======================================================================
654
+
655
+ sfn addPixels:int (a:int b:int) {
656
+ def ag:int ((bit_and (bit_ushr a 8) 16711935) + (bit_and (bit_ushr b 8) 16711935))
657
+ def rb:int ((bit_and a 16711935) + (bit_and b 16711935))
658
+ return (bit_or (bit_shl (bit_and ag 16711935) 8) (bit_and rb 16711935))
659
+ }
660
+
661
+ sfn average2:int (a:int b:int) {
662
+ def ag:int ((bit_and (bit_ushr a 8) 16711935) + (bit_and (bit_ushr b 8) 16711935))
663
+ def rb:int ((bit_and a 16711935) + (bit_and b 16711935))
664
+ return (bit_or (bit_shl (bit_and (bit_shr ag 1) 16711935) 8) (bit_and (bit_shr rb 1) 16711935))
665
+ }
666
+
667
+ sfn clip255:int (v:int) {
668
+ if (v < 0) {
669
+ return 0
670
+ }
671
+ if (v > 255) {
672
+ return 255
673
+ }
674
+ return v
675
+ }
676
+
677
+ sfn absInt:int (v:int) {
678
+ if (v < 0) {
679
+ return (0 - v)
680
+ }
681
+ return v
682
+ }
683
+
684
+ ; the channel of packed pixel p at bit offset sh
685
+ sfn ch:int (p:int sh:int) {
686
+ return (bit_and (bit_shr p sh) 255)
687
+ }
688
+
689
+ sfn pack:int (a:int r:int g:int b:int) {
690
+ return (bit_or (bit_or (bit_shl a 24) (bit_shl r 16)) (bit_or (bit_shl g 8) b))
691
+ }
692
+
693
+ sfn select:int (t:int l:int tl:int) {
694
+ def d:int 0
695
+ def sh:int 0
696
+ while (sh < 32) {
697
+ def ct:int (VP8LDecoder.ch(t sh))
698
+ def cl:int (VP8LDecoder.ch(l sh))
699
+ def ctl:int (VP8LDecoder.ch(tl sh))
700
+ d = d + ((VP8LDecoder.absInt((cl - ctl))) - (VP8LDecoder.absInt((ct - ctl))))
701
+ sh = sh + 8
702
+ }
703
+ if (d <= 0) {
704
+ return t
705
+ }
706
+ return l
707
+ }
708
+
709
+ sfn clampAddSubtractFull:int (a:int b:int c:int) {
710
+ def al:int (VP8LDecoder.clip255(((VP8LDecoder.ch(a 24)) + (VP8LDecoder.ch(b 24)) - (VP8LDecoder.ch(c 24)))))
711
+ def r:int (VP8LDecoder.clip255(((VP8LDecoder.ch(a 16)) + (VP8LDecoder.ch(b 16)) - (VP8LDecoder.ch(c 16)))))
712
+ def g:int (VP8LDecoder.clip255(((VP8LDecoder.ch(a 8)) + (VP8LDecoder.ch(b 8)) - (VP8LDecoder.ch(c 8)))))
713
+ def bl:int (VP8LDecoder.clip255(((VP8LDecoder.ch(a 0)) + (VP8LDecoder.ch(b 0)) - (VP8LDecoder.ch(c 0)))))
714
+ return (VP8LDecoder.pack(al r g bl))
715
+ }
716
+
717
+ sfn halfChannel:int (a:int b:int) {
718
+ return (VP8LDecoder.clip255((a + (idiv (a - b) 2))))
719
+ }
720
+
721
+ sfn clampAddSubtractHalf:int (a:int b:int) {
722
+ def al:int (VP8LDecoder.halfChannel((VP8LDecoder.ch(a 24)) (VP8LDecoder.ch(b 24))))
723
+ def r:int (VP8LDecoder.halfChannel((VP8LDecoder.ch(a 16)) (VP8LDecoder.ch(b 16))))
724
+ def g:int (VP8LDecoder.halfChannel((VP8LDecoder.ch(a 8)) (VP8LDecoder.ch(b 8))))
725
+ def bl:int (VP8LDecoder.halfChannel((VP8LDecoder.ch(a 0)) (VP8LDecoder.ch(b 0))))
726
+ return (VP8LDecoder.pack(al r g bl))
727
+ }
728
+
729
+ ; The 14 predictors of the predictor transform (14 and 15 predict black,
730
+ ; as in libwebp).
731
+ sfn predict:int (mode:int l:int t:int tl:int tr:int) {
732
+ if (mode == 1) {
733
+ return l
734
+ }
735
+ if (mode == 2) {
736
+ return t
737
+ }
738
+ if (mode == 3) {
739
+ return tr
740
+ }
741
+ if (mode == 4) {
742
+ return tl
743
+ }
744
+ if (mode == 5) {
745
+ return (VP8LDecoder.average2((VP8LDecoder.average2(l tr)) t))
746
+ }
747
+ if (mode == 6) {
748
+ return (VP8LDecoder.average2(l tl))
749
+ }
750
+ if (mode == 7) {
751
+ return (VP8LDecoder.average2(l t))
752
+ }
753
+ if (mode == 8) {
754
+ return (VP8LDecoder.average2(tl t))
755
+ }
756
+ if (mode == 9) {
757
+ return (VP8LDecoder.average2(t tr))
758
+ }
759
+ if (mode == 10) {
760
+ return (VP8LDecoder.average2((VP8LDecoder.average2(l tl)) (VP8LDecoder.average2(t tr))))
761
+ }
762
+ if (mode == 11) {
763
+ return (VP8LDecoder.select(t l tl))
764
+ }
765
+ if (mode == 12) {
766
+ return (VP8LDecoder.clampAddSubtractFull(l t tl))
767
+ }
768
+ if (mode == 13) {
769
+ return (VP8LDecoder.clampAddSubtractHalf((VP8LDecoder.average2(l t)) tl))
770
+ }
771
+ return -16777216
772
+ }
773
+
774
+ fn inversePredictor:void (px:int_buffer w:int h:int bits:int modes:int_buffer) {
775
+ def tilesPerRow:int (VP8LDecoder.subSampleSize(w bits))
776
+ def y:int 0
777
+ while (y < h) {
778
+ def row:int (y * w)
779
+ def x:int 0
780
+ while (x < w) {
781
+ def i:int (row + x)
782
+ def pred:int 0
783
+ if (y == 0) {
784
+ if (x == 0) {
785
+ pred = -16777216
786
+ } {
787
+ pred = (int_buffer_get px (i - 1))
788
+ }
789
+ } {
790
+ if (x == 0) {
791
+ pred = (int_buffer_get px (i - w))
792
+ } {
793
+ def mode:int (bit_and (bit_shr (int_buffer_get modes (((bit_shr y bits) * tilesPerRow) + (bit_shr x bits))) 8) 15)
794
+ statPredModes = (bit_or statPredModes (bit_shl 1 mode))
795
+ pred = (VP8LDecoder.predict(mode (int_buffer_get px (i - 1)) (int_buffer_get px (i - w)) (int_buffer_get px ((i - w) - 1)) (int_buffer_get px ((i - w) + 1))))
796
+ }
797
+ }
798
+ int_buffer_set px i (VP8LDecoder.addPixels((int_buffer_get px i) pred))
799
+ x = x + 1
800
+ }
801
+ y = y + 1
802
+ }
803
+ }
804
+
805
+ sfn toInt8:int (v:int) {
806
+ if (v >= 128) {
807
+ return (v - 256)
808
+ }
809
+ return v
810
+ }
811
+
812
+ sfn colorDelta:int (pred:int color:int) {
813
+ return (bit_shr ((VP8LDecoder.toInt8(pred)) * (VP8LDecoder.toInt8(color))) 5)
814
+ }
815
+
816
+ fn inverseCrossColor:void (px:int_buffer w:int h:int bits:int mult:int_buffer) {
817
+ def tilesPerRow:int (VP8LDecoder.subSampleSize(w bits))
818
+ def y:int 0
819
+ while (y < h) {
820
+ def row:int (y * w)
821
+ def tileRow:int ((bit_shr y bits) * tilesPerRow)
822
+ def x:int 0
823
+ while (x < w) {
824
+ def m:int (int_buffer_get mult (tileRow + (bit_shr x bits)))
825
+ def g2r:int (bit_and m 255)
826
+ def g2b:int (bit_and (bit_shr m 8) 255)
827
+ def r2b:int (bit_and (bit_shr m 16) 255)
828
+ def p:int (int_buffer_get px (row + x))
829
+ def green:int (bit_and (bit_shr p 8) 255)
830
+ def red:int (bit_and ((bit_and (bit_shr p 16) 255) + (VP8LDecoder.colorDelta(g2r green))) 255)
831
+ def blue:int (bit_and p 255)
832
+ blue = (bit_and (blue + (VP8LDecoder.colorDelta(g2b green)) + (VP8LDecoder.colorDelta(r2b red))) 255)
833
+ int_buffer_set px (row + x) (bit_or (bit_and p -16711936) (bit_or (bit_shl red 16) blue))
834
+ x = x + 1
835
+ }
836
+ y = y + 1
837
+ }
838
+ }
839
+
840
+ fn inverseSubtractGreen:void (px:int_buffer n:int) {
841
+ def i:int 0
842
+ while (i < n) {
843
+ def p:int (int_buffer_get px i)
844
+ def green:int (bit_and (bit_shr p 8) 255)
845
+ def red:int (bit_and ((bit_and (bit_shr p 16) 255) + green) 255)
846
+ def blue:int (bit_and ((bit_and p 255) + green) 255)
847
+ int_buffer_set px i (bit_or (bit_and p -16711936) (bit_or (bit_shl red 16) blue))
848
+ i = i + 1
849
+ }
850
+ }
851
+
852
+ ; packed indices (width packedW) -> colors (width w)
853
+ fn inverseColorIndex:int_buffer (px:int_buffer w:int h:int bits:int palette:int_buffer) {
854
+ def out:int_buffer (int_buffer_alloc (w * h))
855
+ def packedW:int (VP8LDecoder.subSampleSize(w bits))
856
+ def bitsPerPixel:int (bit_shr 8 bits)
857
+ def countMask:int ((bit_shl 1 bits) - 1)
858
+ def bitMask:int ((bit_shl 1 bitsPerPixel) - 1)
859
+ def y:int 0
860
+ while (y < h) {
861
+ def src:int (y * packedW)
862
+ def dst:int (y * w)
863
+ def packed:int 0
864
+ def x:int 0
865
+ while (x < w) {
866
+ if ((bit_and x countMask) == 0) {
867
+ packed = (bit_and (bit_shr (int_buffer_get px src) 8) 255)
868
+ src = src + 1
869
+ }
870
+ int_buffer_set out (dst + x) (int_buffer_get palette (bit_and packed bitMask))
871
+ packed = (bit_shr packed bitsPerPixel)
872
+ x = x + 1
873
+ }
874
+ y = y + 1
875
+ }
876
+ return out
877
+ }
878
+
879
+ ; ======================================================================
880
+ ; Streams
881
+ ; ======================================================================
882
+
883
+ ; A level 0 image: transforms, then the main entropy-coded image, then the
884
+ ; transforms undone in reverse order. Returns w * h ARGB pixels.
885
+ fn decodeLevel0:int_buffer (w:int h:int) {
886
+ def empty:int_buffer (int_buffer_alloc 0)
887
+ def types:int_buffer (int_buffer_alloc 4)
888
+ def tbits:int_buffer (int_buffer_alloc 4)
889
+ def widths:int_buffer (int_buffer_alloc 4)
890
+ def data0:int_buffer (int_buffer_alloc 0)
891
+ def data1:int_buffer (int_buffer_alloc 0)
892
+ def data3:int_buffer (int_buffer_alloc 0)
893
+ def seen:int 0
894
+ def count:int 0
895
+ def xsize:int w
896
+ while ((this.readBits(1)) == 1) {
897
+ def t:int (this.readBits(2))
898
+ if ((bit_and seen (bit_shl 1 t)) != 0) {
899
+ this.fail("transform repeated")
900
+ return empty
901
+ }
902
+ seen = (bit_or seen (bit_shl 1 t))
903
+ statTransforms = (bit_or statTransforms (bit_shl 1 t))
904
+ int_buffer_set types count t
905
+ int_buffer_set widths count xsize
906
+ if ((t == 0) || (t == 1)) {
907
+ def b:int ((this.readBits(3)) + 2)
908
+ int_buffer_set tbits count b
909
+ def sub:int_buffer (this.decodeImageData((VP8LDecoder.subSampleSize(xsize b)) (VP8LDecoder.subSampleSize(h b)) false))
910
+ if ((strlen error) > 0) {
911
+ return empty
912
+ }
913
+ if (t == 0) {
914
+ data0 = sub
915
+ } {
916
+ data1 = sub
917
+ }
918
+ }
919
+ if (t == 3) {
920
+ def numColors:int ((this.readBits(8)) + 1)
921
+ def b:int 0
922
+ if (numColors <= 16) {
923
+ b = 1
924
+ }
925
+ if (numColors <= 4) {
926
+ b = 2
927
+ }
928
+ if (numColors <= 2) {
929
+ b = 3
930
+ }
931
+ int_buffer_set tbits count b
932
+ statBundleBits = b
933
+ def pal:int_buffer (this.decodeImageData(numColors 1 false))
934
+ if ((strlen error) > 0) {
935
+ return empty
936
+ }
937
+ ; the palette is delta coded; entries past it are transparent black
938
+ def palSize:int (bit_shl 1 (bit_shr 8 b))
939
+ def full:int_buffer (int_buffer_alloc palSize)
940
+ def prev:int 0
941
+ def k:int 0
942
+ while (k < numColors) {
943
+ prev = (VP8LDecoder.addPixels(prev (int_buffer_get pal k)))
944
+ int_buffer_set full k prev
945
+ k = k + 1
946
+ }
947
+ data3 = full
948
+ xsize = (VP8LDecoder.subSampleSize(xsize b))
949
+ }
950
+ count = count + 1
951
+ }
952
+ if eos {
953
+ this.fail("truncated transforms")
954
+ return empty
955
+ }
956
+ def px:int_buffer (this.decodeImageData(xsize h true))
957
+ if ((strlen error) > 0) {
958
+ return empty
959
+ }
960
+ def j:int (count - 1)
961
+ while (j >= 0) {
962
+ def t:int (int_buffer_get types j)
963
+ def tw:int (int_buffer_get widths j)
964
+ if (t == 0) {
965
+ this.inversePredictor(px tw h (int_buffer_get tbits j) data0)
966
+ }
967
+ if (t == 1) {
968
+ this.inverseCrossColor(px tw h (int_buffer_get tbits j) data1)
969
+ }
970
+ if (t == 2) {
971
+ this.inverseSubtractGreen(px (tw * h))
972
+ }
973
+ if (t == 3) {
974
+ px = (this.inverseColorIndex(px tw h (int_buffer_get tbits j) data3))
975
+ }
976
+ j = j - 1
977
+ }
978
+ return px
979
+ }
980
+
981
+ fn resetStats:void () {
982
+ statTransforms = 0
983
+ statPredModes = 0
984
+ statCacheBits = 0
985
+ statGroups = 0
986
+ statSimpleCodes = 0
987
+ statNormalCodes = 0
988
+ statBackRefs = 0
989
+ statCacheHits = 0
990
+ statBundleBits = -1
991
+ }
992
+
993
+ ; Decodes a VP8L chunk payload (signature byte and header included).
994
+ ; On success `argb`, `width`, `height` and `hasAlpha` are set.
995
+ fn decode:boolean (src:buffer start:int size:int maxDim:int) {
996
+ error = ""
997
+ this.resetStats()
998
+ if (size < 5) {
999
+ return (this.fail("VP8L chunk too small"))
1000
+ }
1001
+ this.initBits(src start size)
1002
+ if ((this.readBits(8)) != 47) {
1003
+ return (this.fail("bad VP8L signature"))
1004
+ }
1005
+ width = (this.readBits(14)) + 1
1006
+ height = (this.readBits(14)) + 1
1007
+ hasAlpha = ((this.readBits(1)) == 1)
1008
+ if ((this.readBits(3)) != 0) {
1009
+ return (this.fail("unsupported VP8L version"))
1010
+ }
1011
+ if ((width > maxDim) || (height > maxDim) || (((to_double width) * (to_double height)) > (to_double maxPixels))) {
1012
+ return (this.fail("image too large"))
1013
+ }
1014
+ argb = (this.decodeLevel0(width height))
1015
+ if ((strlen error) > 0) {
1016
+ return false
1017
+ }
1018
+ return true
1019
+ }
1020
+
1021
+ ; Decodes the headerless VP8L stream of a compressed ALPH chunk; `argb`
1022
+ ; then holds w * h pixels whose green channel is the alpha value.
1023
+ fn decodeAlphaStream:boolean (src:buffer start:int size:int w:int h:int) {
1024
+ error = ""
1025
+ this.resetStats()
1026
+ this.initBits(src start size)
1027
+ width = w
1028
+ height = h
1029
+ argb = (this.decodeLevel0(w h))
1030
+ if ((strlen error) > 0) {
1031
+ return false
1032
+ }
1033
+ return true
1034
+ }
1035
+ }