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,9 @@
1
+ {
2
+ "name": "image",
3
+ "version": "0.1.0",
4
+ "entry": "ImageBuffer.rgr",
5
+ "license": "MIT",
6
+ "dependencies": {
7
+ "zip": { "path": "../zip" }
8
+ }
9
+ }
@@ -0,0 +1,33 @@
1
+ # name width height adler32(RGBA from libwebp via Pillow)
2
+ anim_2f_24x16.webp 24 16 c26083ae
3
+ ll_1x1.webp 1 1 04b201c1
4
+ ll_alpha_29x21.webp 29 21 0a9d7cbf
5
+ ll_gradient_64x64.webp 64 64 a4ce924a
6
+ ll_meta_32x32.webp 32 32 a70fb4ba
7
+ ll_noise_17x9.webp 17 9 3b092b39
8
+ ll_pal11_23x11.webp 23 11 e70c98d1
9
+ ll_pal2_19x7.webp 19 7 13216d6a
10
+ ll_pal40_16x16.webp 16 16 e84156f5
11
+ ll_pal4_13x5.webp 13 5 6a488968
12
+ ll_photo_40x30.webp 40 30 03ed2083
13
+ ll_predictors_64x32.webp 64 32 978be2eb
14
+ ly_1x1.webp 1 1 03cf01f8
15
+ ly_alph_raw_f0_21x13.webp 21 13 b5fe78ab
16
+ ly_alph_raw_f1_21x13.webp 21 13 b5fe78ab
17
+ ly_alph_raw_f2_21x13.webp 21 13 b5fe78ab
18
+ ly_alph_raw_f3_21x13.webp 21 13 b5fe78ab
19
+ ly_alph_vp8l_f0_21x13.webp 21 13 b5fe78ab
20
+ ly_alph_vp8l_f1_21x13.webp 21 13 b5fe78ab
21
+ ly_alph_vp8l_f2_21x13.webp 21 13 b5fe78ab
22
+ ly_alph_vp8l_f3_21x13.webp 21 13 b5fe78ab
23
+ ly_alpha_33x17.webp 33 17 cca2d0c4
24
+ ly_exif_15x11.webp 15 11 0e738309
25
+ ly_i16_96x80.webp 96 80 d161cded
26
+ ly_nofilter_24x20.webp 24 20 a5d1d21a
27
+ ly_odd_17x9.webp 17 9 70ed9b46
28
+ ly_photo_48x40.webp 48 40 d3366c1e
29
+ ly_q100_20x18.webp 20 18 5c901d0b
30
+ ly_sharp_40x36.webp 40 36 483a3d4e
31
+ ly_simple_filter_33x31.webp 33 31 8a5262c8
32
+ ly_vpx_parts8_37x45.webp 37 45 e10ae947
33
+ ly_vpx_skip_96x80.webp 96 80 771e527d
@@ -0,0 +1,261 @@
1
+ #!/usr/bin/env python3
2
+ # SPDX-License-Identifier: MIT
3
+ #
4
+ # Regenerates the WebP decoder fixtures in this folder and the expected
5
+ # checksums in fixtures.txt. Needs Pillow (built with libwebp) and the
6
+ # `webp` package (pip install pillow webp), and vpxenc (vpx-tools): Pillow is
7
+ # the reference decoder (libwebp); `webp` gives access to the encoder options
8
+ # Pillow hides (filter type, segments, alpha compression / filtering);
9
+ # libvpx writes the key frames libwebp's encoder never does (several token
10
+ # partitions, skipped macroblocks, loop filter deltas), wrapped here in a RIFF.
11
+ #
12
+ # python3 gen_fixtures.py [source-image]
13
+ #
14
+ # The ALPH chunks with a chosen filter method are written by hand below,
15
+ # because no encoder option forces one filter.
16
+ import os, struct, subprocess, sys, tempfile, zlib, random
17
+ import numpy as np
18
+ from PIL import Image
19
+ from webp import _webp, WebPConfig, WebPPicture
20
+
21
+ HERE = os.path.dirname(os.path.abspath(__file__))
22
+ ffi, lib = _webp.ffi, _webp.lib
23
+
24
+ def config(lossless=False, quality=75, method=4, **raw):
25
+ c = WebPConfig.new(lossless=lossless, quality=quality, method=method)
26
+ ints = ffi.cast('int*', c.ptr)
27
+ idx = dict(segments=6, sns_strength=7, filter_strength=8, filter_sharpness=9,
28
+ filter_type=10, autofilter=11, alpha_compression=12, alpha_filtering=13,
29
+ alpha_quality=14, preprocessing=17, partitions=18, near_lossless=23,
30
+ exact=24, use_delta_palette=25)
31
+ for k, v in raw.items():
32
+ ints[idx[k]] = v
33
+ assert c.validate(), raw
34
+ return c
35
+
36
+ def encode(img, cfg):
37
+ return bytes(WebPPicture.from_numpy(np.ascontiguousarray(np.asarray(img)),
38
+ pilmode=img.mode).encode(cfg).buffer())
39
+
40
+ def chunks(data):
41
+ out, p = [], 12
42
+ while p + 8 <= len(data):
43
+ t, n = data[p:p + 4], struct.unpack('<I', data[p + 4:p + 8])[0]
44
+ out.append((t, data[p + 8:p + 8 + n]))
45
+ p += 8 + n + (n & 1)
46
+ return out
47
+
48
+ def chunk(tag, payload):
49
+ b = tag + struct.pack('<I', len(payload)) + payload
50
+ return b + (b'\0' if len(payload) & 1 else b'')
51
+
52
+ def riff(body):
53
+ return b'RIFF' + struct.pack('<I', 4 + len(body)) + b'WEBP' + body
54
+
55
+ def vp8x(w, h, flags):
56
+ return chunk(b'VP8X', bytes([flags, 0, 0, 0]) + (w - 1).to_bytes(3, 'little') + (h - 1).to_bytes(3, 'little'))
57
+
58
+ def vpx_keyframe(img, *opts):
59
+ """A VP8 key frame from libvpx, as a WebP file."""
60
+ w, h = img.size
61
+ ycc = np.asarray(img.convert('YCbCr')).astype(np.float32)
62
+ cw, ch = (w + 1) // 2, (h + 1) // 2
63
+ pad = np.pad(ycc, ((0, ch * 2 - h), (0, cw * 2 - w), (0, 0)), mode='edge')
64
+ u = pad[:, :, 1].reshape(ch, 2, cw, 2).mean(axis=(1, 3)).round().astype(np.uint8)
65
+ v = pad[:, :, 2].reshape(ch, 2, cw, 2).mean(axis=(1, 3)).round().astype(np.uint8)
66
+ with tempfile.TemporaryDirectory() as tmp:
67
+ y4m, ivf = os.path.join(tmp, 'in.y4m'), os.path.join(tmp, 'out.ivf')
68
+ with open(y4m, 'wb') as f:
69
+ f.write(b'YUV4MPEG2 W%d H%d F25:1 Ip A1:1 C420jpeg\nFRAME\n' % (w, h))
70
+ f.write(ycc[:, :, 0].astype(np.uint8).tobytes() + u.tobytes() + v.tobytes())
71
+ subprocess.run(['vpxenc', '--codec=vp8', '--ivf', '--limit=1', '-q', '-o', ivf, y4m] + list(opts), check=True)
72
+ d = open(ivf, 'rb').read()
73
+ n = struct.unpack('<I', d[32:36])[0]
74
+ return riff(chunk(b'VP8 ', d[44:44 + n]))
75
+
76
+ def predictor_image(seed, w, h, tile):
77
+ """Tiles each built with one VP8L predictor, so the encoder picks those."""
78
+ avg = lambda a, b: (a + b) >> 1
79
+ clip = lambda v: max(0, min(255, v))
80
+ def half(a, b):
81
+ return clip(a + (a - b) // 2 if a >= b else a - (b - a) // 2)
82
+ pred = {
83
+ 3: lambda L, T, TL, TR: TR, 4: lambda L, T, TL, TR: TL,
84
+ 5: lambda L, T, TL, TR: avg(avg(L, TR), T), 8: lambda L, T, TL, TR: avg(TL, T),
85
+ 9: lambda L, T, TL, TR: avg(T, TR), 10: lambda L, T, TL, TR: avg(avg(L, TL), avg(T, TR)),
86
+ 12: lambda L, T, TL, TR: clip(L + T - TL), 13: lambda L, T, TL, TR: half(avg(L, T), TL),
87
+ }
88
+ modes = [8, 9, 10, 3, 4, 12, 13, 5]
89
+ rnd = random.Random(seed)
90
+ a = np.zeros((h, w), np.int32)
91
+ for y in range(h):
92
+ for x in range(w):
93
+ if y == 0 or x == 0 or x == w - 1:
94
+ a[y, x] = rnd.randrange(256)
95
+ continue
96
+ v = pred[modes[(x // tile + (y // tile) * (w // tile)) % len(modes)]](a[y, x - 1], a[y - 1, x], a[y - 1, x - 1], a[y - 1, x + 1])
97
+ if rnd.random() < 0.3:
98
+ v = clip(v + rnd.choice((-40, -9, 5, 33)))
99
+ a[y, x] = v
100
+ return Image.fromarray(np.stack([a, (a * 3) & 255, 255 - a], -1).astype(np.uint8), 'RGB')
101
+
102
+ def quadrants(size, seed):
103
+ """Four regions with unrelated statistics: meta prefix codes."""
104
+ rnd = random.Random(seed)
105
+ a = np.zeros((size, size, 3), np.uint8)
106
+ hs = size // 2
107
+ for y in range(size):
108
+ for x in range(size):
109
+ q = (x // hs) + 2 * (y // hs)
110
+ if q == 0:
111
+ a[y, x] = (rnd.randrange(0, 40), rnd.randrange(200, 256), rnd.randrange(0, 8))
112
+ elif q == 1:
113
+ a[y, x] = (rnd.randrange(200, 256), rnd.randrange(0, 16), rnd.randrange(100, 140))
114
+ elif q == 2:
115
+ a[y, x] = ((x * 3 + y * 5) % 256, (x * 7) % 256, (y * 9) % 256)
116
+ else:
117
+ a[y, x] = (rnd.randrange(0, 256) & 0xf0, 128, 0)
118
+ return Image.fromarray(a, 'RGB')
119
+
120
+ def stripes(w, h):
121
+ """Flat, horizontal and vertical stripes, a gradient: every 16x16 mode."""
122
+ a = np.zeros((h, w, 3), np.uint8)
123
+ for y in range(h):
124
+ for x in range(w):
125
+ r = y // 16
126
+ if r == 0:
127
+ c = (90, 140, 200)
128
+ elif r == 1:
129
+ c = ((y * 37) % 256, (y * 11) % 256, 60)
130
+ elif r in (2, 3):
131
+ c = ((x * 37) % 256, 80, (x * 23) % 256)
132
+ else:
133
+ c = (90, 140, 200) if x < w // 2 else (min(255, x * 2), y * 3, 100)
134
+ a[y, x] = c
135
+ return Image.fromarray(a, 'RGB')
136
+
137
+ def filter_alpha(a, method):
138
+ """Forward WebP alpha filter (the decoder's unfilter reverses it)."""
139
+ h, w = a.shape
140
+ a = a.astype(np.int32)
141
+ out = np.zeros_like(a)
142
+ for y in range(h):
143
+ for x in range(w):
144
+ if y == 0 and x == 0:
145
+ pred = 0
146
+ elif y == 0:
147
+ pred = a[y, x - 1]
148
+ elif x == 0:
149
+ pred = a[y - 1, x]
150
+ elif method == 1:
151
+ pred = a[y, x - 1]
152
+ elif method == 2:
153
+ pred = a[y - 1, x]
154
+ else:
155
+ pred = min(255, max(0, a[y, x - 1] + a[y - 1, x] - a[y - 1, x - 1]))
156
+ out[y, x] = (a[y, x] - pred) & 255
157
+ return out.astype(np.uint8)
158
+
159
+ def lossless_alpha_payload(plane):
160
+ """A VP8L stream for an alpha plane: green carries the value, and the
161
+ 5-byte VP8L header is dropped as the ALPH chunk wants."""
162
+ rgb = np.stack([np.zeros_like(plane), plane, np.zeros_like(plane)], axis=-1)
163
+ data = encode(Image.fromarray(rgb, 'RGB'), config(lossless=True, quality=100, method=6, exact=1))
164
+ (tag, payload), = [c for c in chunks(data) if c[0] == b'VP8L']
165
+ return payload[5:]
166
+
167
+ def lossy_with_alph(rgba, alph_header, alph_data, cfg):
168
+ w, h = rgba.size
169
+ data = encode(rgba.convert('RGB'), cfg)
170
+ (tag, vp8), = [c for c in chunks(data) if c[0] == b'VP8 ']
171
+ return riff(vp8x(w, h, 0x10) + chunk(b'ALPH', bytes([alph_header]) + alph_data) + chunk(b'VP8 ', vp8))
172
+
173
+ def main():
174
+ src = sys.argv[1] if len(sys.argv) > 1 else '/tmp/claude-0/sp/f/5-Kielo-kaarme.jpg.webp'
175
+ photo = Image.open(src).convert('RGB')
176
+ rnd = random.Random(7)
177
+ files = {}
178
+
179
+ def crop(x, y, w, h):
180
+ return photo.crop((x, y, x + w, y + h))
181
+
182
+ def alpha_disc(img):
183
+ w, h = img.size
184
+ a = np.zeros((h, w), np.uint8)
185
+ for y in range(h):
186
+ for x in range(w):
187
+ d = ((x - w / 2) ** 2 + (y - h / 2) ** 2) ** 0.5
188
+ a[y, x] = max(0, min(255, int(255 - 12 * max(0, d - min(w, h) / 3))))
189
+ rgba = img.convert('RGBA')
190
+ rgba.putalpha(Image.fromarray(a, 'L'))
191
+ return rgba
192
+
193
+ # --- VP8L lossless ------------------------------------------------------
194
+ files['ll_1x1.webp'] = encode(Image.new('RGBA', (1, 1), (200, 30, 90, 128)), config(True, 100, 6, exact=1))
195
+ noise = Image.frombytes('RGBA', (17, 9), bytes(rnd.randrange(256) for _ in range(17 * 9 * 4)))
196
+ files['ll_noise_17x9.webp'] = encode(noise, config(True, 100, 6, exact=1))
197
+ files['ll_photo_40x30.webp'] = encode(crop(120, 200, 40, 30), config(True, 100, 6))
198
+ files['ll_meta_32x32.webp'] = encode(quadrants(32, 3), config(True, 100, 4))
199
+ files['ll_predictors_64x32.webp'] = encode(predictor_image(3, 64, 32, 16), config(True, 100, 6))
200
+ files['ll_alpha_29x21.webp'] = encode(alpha_disc(crop(200, 100, 29, 21)), config(True, 90, 5))
201
+ for n, (w, h) in ((2, (19, 7)), (4, (13, 5)), (11, (23, 11)), (40, (16, 16))):
202
+ cols = [tuple(rnd.randrange(256) for _ in range(3)) + (255,) for _ in range(n)]
203
+ im = Image.new('RGBA', (w, h))
204
+ im.putdata([cols[rnd.randrange(n)] for y in range(h) for x in range(w)])
205
+ # method 4: at method 6 the encoder finds these too small for a palette
206
+ files['ll_pal%d_%dx%d.webp' % (n, w, h)] = encode(im, config(True, 100, 4, exact=1))
207
+ grad = Image.new('RGB', (64, 64))
208
+ grad.putdata([((x * 4) & 255, (y * 4) & 255, ((x + y) * 2) & 255) for y in range(64) for x in range(64)])
209
+ files['ll_gradient_64x64.webp'] = encode(grad, config(True, 100, 6))
210
+
211
+ # --- VP8 lossy -----------------------------------------------------------
212
+ files['ly_1x1.webp'] = encode(Image.new('RGB', (1, 1), (10, 200, 40)), config(False, 75, 4))
213
+ files['ly_odd_17x9.webp'] = encode(crop(120, 260, 17, 9), config(False, 80, 4))
214
+ files['ly_photo_48x40.webp'] = encode(crop(150, 250, 48, 40), config(False, 70, 4, segments=4))
215
+ files['ly_simple_filter_33x31.webp'] = encode(crop(60, 400, 33, 31), config(False, 40, 2, filter_type=0, filter_strength=60))
216
+ files['ly_sharp_40x36.webp'] = encode(crop(180, 380, 40, 36), config(False, 30, 4, filter_sharpness=6, filter_strength=80, segments=4))
217
+ files['ly_nofilter_24x20.webp'] = encode(crop(10, 10, 24, 20), config(False, 90, 3, filter_strength=0, segments=1))
218
+ files['ly_q100_20x18.webp'] = encode(crop(250, 480, 20, 18), config(False, 100, 6))
219
+ files['ly_i16_96x80.webp'] = encode(stripes(96, 80), config(False, 30, 4, segments=4, filter_strength=40))
220
+ files['ly_vpx_skip_96x80.webp'] = vpx_keyframe(stripes(96, 80), '--token-parts=1', '--end-usage=q', '--cq-level=40')
221
+ files['ly_vpx_parts8_37x45.webp'] = vpx_keyframe(crop(100, 200, 37, 45), '--token-parts=3', '--end-usage=q', '--cq-level=40')
222
+ # lossy + ALPH as the encoder writes it (VP8L-compressed, encoder's filter choice)
223
+ files['ly_alpha_33x17.webp'] = encode(alpha_disc(crop(90, 90, 33, 17)), config(False, 75, 4, alpha_filtering=2))
224
+ # lossy + ALPH written by hand: every filter, raw and VP8L-compressed, pre-processing flag
225
+ base = alpha_disc(crop(170, 330, 21, 13))
226
+ a = np.asarray(base)[:, :, 3]
227
+ for method in (0, 1, 2, 3):
228
+ filt = a if method == 0 else filter_alpha(a, method)
229
+ files['ly_alph_raw_f%d_21x13.webp' % method] = lossy_with_alph(base, (method << 2) | 0, filt.tobytes(), config(False, 75, 4))
230
+ files['ly_alph_vp8l_f%d_21x13.webp' % method] = lossy_with_alph(base, (1 << 4) | (method << 2) | 1, lossless_alpha_payload(filt), config(False, 75, 4))
231
+
232
+ # --- container ------------------------------------------------------------
233
+ # VP8X with EXIF metadata beside a simple VP8 frame
234
+ im = crop(400, 60, 15, 11)
235
+ exif = Image.Exif(); exif[0x010e] = 'fixture'
236
+ im.save(os.path.join(HERE, 'ly_exif_15x11.webp'), quality=70, exif=exif.tobytes())
237
+ files['ly_exif_15x11.webp'] = open(os.path.join(HERE, 'ly_exif_15x11.webp'), 'rb').read()
238
+ # animation: the decoder returns the first frame
239
+ fr = [alpha_disc(crop(20 + 30 * i, 20, 24, 16)) for i in range(2)]
240
+ p = os.path.join(HERE, 'anim_2f_24x16.webp')
241
+ fr[0].save(p, save_all=True, append_images=fr[1:], duration=100, loop=0, lossless=True)
242
+ files['anim_2f_24x16.webp'] = open(p, 'rb').read()
243
+
244
+ lines = []
245
+ total = 0
246
+ for name in sorted(files):
247
+ path = os.path.join(HERE, name)
248
+ with open(path, 'wb') as f:
249
+ f.write(files[name])
250
+ total += len(files[name])
251
+ im = Image.open(path)
252
+ im.seek(0)
253
+ rgba = im.convert('RGBA').tobytes()
254
+ lines.append('%s %d %d %08x' % (name, im.size[0], im.size[1], zlib.adler32(rgba) & 0xffffffff))
255
+ with open(os.path.join(HERE, 'fixtures.txt'), 'w') as f:
256
+ f.write('# name width height adler32(RGBA from libwebp via Pillow)\n')
257
+ f.write('\n'.join(lines) + '\n')
258
+ print('\n'.join(lines))
259
+ print('total bytes', total)
260
+
261
+ main()
@@ -0,0 +1,81 @@
1
+ ; SPDX-License-Identifier: MIT
2
+
3
+ ; WebPDecodeTool.rgr - decode WebP files, print "file width height adler32"
4
+ ; of the RGBA output (the format of testdata/webp/fixtures.txt), to compare
5
+ ; against another decoder. With -bench N as the first arguments each file is
6
+ ; decoded N more times inside a timer.
7
+ ;
8
+ ; node dist/rgrc.js -l=cpp lib/image/tests/WebPDecodeTool.rgr -d=/tmp/w -o=webp_tool.cpp
9
+ ; g++ -std=c++17 -O2 /tmp/w/webp_tool.cpp -o /tmp/w/webp_tool
10
+ ; /tmp/w/webp_tool -bench 20 photo.webp
11
+
12
+ Import "../WebPDecoder.rgr"
13
+
14
+ class WebPDecodeTool {
15
+ sfn hex8:string (hi:int lo:int) {
16
+ def digits:string "0123456789abcdef"
17
+ def s:string ""
18
+ def v:int (bit_or (bit_shl hi 16) lo)
19
+ def k:int 28
20
+ while (k >= 0) {
21
+ def d:int (bit_and (bit_ushr v k) 15)
22
+ s = s + (substring digits d (d + 1))
23
+ k = k - 4
24
+ }
25
+ return s
26
+ }
27
+
28
+ sfn adler32:string (b:buffer) {
29
+ def a:int 1
30
+ def s:int 0
31
+ def n:int (buffer_length b)
32
+ def i:int 0
33
+ while (i < n) {
34
+ a = (a + (buffer_get b i)) % 65521
35
+ s = (s + a) % 65521
36
+ i = i + 1
37
+ }
38
+ return (WebPDecodeTool.hex8(s a))
39
+ }
40
+
41
+ sfn m@(main):void () {
42
+ def n:int (shell_arg_cnt)
43
+ def first:int 0
44
+ def repeat:int 0
45
+ if (n >= 2) {
46
+ if ((shell_arg 0) == "-bench") {
47
+ repeat = (unwrap (to_int (shell_arg 1)))
48
+ first = 2
49
+ }
50
+ }
51
+ def i:int first
52
+ while (i < n) {
53
+ def path:string (shell_arg i)
54
+ def slash:int (lastIndexOf path "/")
55
+ def folder:string "."
56
+ def name:string path
57
+ if (slash >= 0) {
58
+ folder = (substring path 0 (slash + 1))
59
+ name = (substring path (slash + 1) (strlen path))
60
+ }
61
+ def bytes:buffer (buffer_read_file folder name)
62
+ def dec (new WebPDecoder())
63
+ def img:ImageBuffer (dec.decodeBytes(bytes))
64
+ if dec.ok {
65
+ print (path + " " + (to_string img.width) + " " + (to_string img.height) + " " + (WebPDecodeTool.adler32(img.pixels)))
66
+ } {
67
+ print (path + " ERROR " + dec.error)
68
+ }
69
+ if (repeat > 0) {
70
+ timer (" " + (to_string repeat) + " decodes, seconds") {
71
+ def r:int 0
72
+ while (r < repeat) {
73
+ dec.decodeBytes(bytes)
74
+ r = r + 1
75
+ }
76
+ }
77
+ }
78
+ i = i + 1
79
+ }
80
+ }
81
+ }