@flighthq/bitmap 0.3.0-edge.1458.0c01b63

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 (219) hide show
  1. package/dist/bitmap.d.ts +17 -0
  2. package/dist/bitmap.d.ts.map +1 -0
  3. package/dist/bitmap.js +87 -0
  4. package/dist/bitmap.js.map +1 -0
  5. package/dist/bitmapAffine.d.ts +27 -0
  6. package/dist/bitmapAffine.d.ts.map +1 -0
  7. package/dist/bitmapAffine.js +159 -0
  8. package/dist/bitmapAffine.js.map +1 -0
  9. package/dist/bitmapAlpha.d.ts +27 -0
  10. package/dist/bitmapAlpha.d.ts.map +1 -0
  11. package/dist/bitmapAlpha.js +83 -0
  12. package/dist/bitmapAlpha.js.map +1 -0
  13. package/dist/bitmapBevel.d.ts +24 -0
  14. package/dist/bitmapBevel.d.ts.map +1 -0
  15. package/dist/bitmapBevel.js +102 -0
  16. package/dist/bitmapBevel.js.map +1 -0
  17. package/dist/bitmapBlur.d.ts +57 -0
  18. package/dist/bitmapBlur.d.ts.map +1 -0
  19. package/dist/bitmapBlur.js +263 -0
  20. package/dist/bitmapBlur.js.map +1 -0
  21. package/dist/bitmapChannel.d.ts +24 -0
  22. package/dist/bitmapChannel.d.ts.map +1 -0
  23. package/dist/bitmapChannel.js +127 -0
  24. package/dist/bitmapChannel.js.map +1 -0
  25. package/dist/bitmapColorMatrix.d.ts +57 -0
  26. package/dist/bitmapColorMatrix.d.ts.map +1 -0
  27. package/dist/bitmapColorMatrix.js +127 -0
  28. package/dist/bitmapColorMatrix.js.map +1 -0
  29. package/dist/bitmapCompare.d.ts +18 -0
  30. package/dist/bitmapCompare.d.ts.map +1 -0
  31. package/dist/bitmapCompare.js +64 -0
  32. package/dist/bitmapCompare.js.map +1 -0
  33. package/dist/bitmapComposite.d.ts +54 -0
  34. package/dist/bitmapComposite.d.ts.map +1 -0
  35. package/dist/bitmapComposite.js +262 -0
  36. package/dist/bitmapComposite.js.map +1 -0
  37. package/dist/bitmapConvolution.d.ts +17 -0
  38. package/dist/bitmapConvolution.d.ts.map +1 -0
  39. package/dist/bitmapConvolution.js +103 -0
  40. package/dist/bitmapConvolution.js.map +1 -0
  41. package/dist/bitmapCopy.d.ts +23 -0
  42. package/dist/bitmapCopy.d.ts.map +1 -0
  43. package/dist/bitmapCopy.js +78 -0
  44. package/dist/bitmapCopy.js.map +1 -0
  45. package/dist/bitmapCoverage.d.ts +11 -0
  46. package/dist/bitmapCoverage.d.ts.map +1 -0
  47. package/dist/bitmapCoverage.js +29 -0
  48. package/dist/bitmapCoverage.js.map +1 -0
  49. package/dist/bitmapCrop.d.ts +33 -0
  50. package/dist/bitmapCrop.d.ts.map +1 -0
  51. package/dist/bitmapCrop.js +175 -0
  52. package/dist/bitmapCrop.js.map +1 -0
  53. package/dist/bitmapDisplacement.d.ts +22 -0
  54. package/dist/bitmapDisplacement.d.ts.map +1 -0
  55. package/dist/bitmapDisplacement.js +111 -0
  56. package/dist/bitmapDisplacement.js.map +1 -0
  57. package/dist/bitmapDissolve.d.ts +21 -0
  58. package/dist/bitmapDissolve.d.ts.map +1 -0
  59. package/dist/bitmapDissolve.js +97 -0
  60. package/dist/bitmapDissolve.js.map +1 -0
  61. package/dist/bitmapDraw.d.ts +8 -0
  62. package/dist/bitmapDraw.d.ts.map +1 -0
  63. package/dist/bitmapDraw.js +14 -0
  64. package/dist/bitmapDraw.js.map +1 -0
  65. package/dist/bitmapEncode.d.ts +3 -0
  66. package/dist/bitmapEncode.d.ts.map +1 -0
  67. package/dist/bitmapEncode.js +18 -0
  68. package/dist/bitmapEncode.js.map +1 -0
  69. package/dist/bitmapFill.d.ts +12 -0
  70. package/dist/bitmapFill.d.ts.map +1 -0
  71. package/dist/bitmapFill.js +85 -0
  72. package/dist/bitmapFill.js.map +1 -0
  73. package/dist/bitmapFingerprint.d.ts +26 -0
  74. package/dist/bitmapFingerprint.d.ts.map +1 -0
  75. package/dist/bitmapFingerprint.js +99 -0
  76. package/dist/bitmapFingerprint.js.map +1 -0
  77. package/dist/bitmapFlip.d.ts +16 -0
  78. package/dist/bitmapFlip.d.ts.map +1 -0
  79. package/dist/bitmapFlip.js +98 -0
  80. package/dist/bitmapFlip.js.map +1 -0
  81. package/dist/bitmapFormat.d.ts +26 -0
  82. package/dist/bitmapFormat.d.ts.map +1 -0
  83. package/dist/bitmapFormat.js +80 -0
  84. package/dist/bitmapFormat.js.map +1 -0
  85. package/dist/bitmapFrom.d.ts +23 -0
  86. package/dist/bitmapFrom.d.ts.map +1 -0
  87. package/dist/bitmapFrom.js +90 -0
  88. package/dist/bitmapFrom.js.map +1 -0
  89. package/dist/bitmapGradient.d.ts +36 -0
  90. package/dist/bitmapGradient.d.ts.map +1 -0
  91. package/dist/bitmapGradient.js +176 -0
  92. package/dist/bitmapGradient.js.map +1 -0
  93. package/dist/bitmapGradientFill.d.ts +32 -0
  94. package/dist/bitmapGradientFill.d.ts.map +1 -0
  95. package/dist/bitmapGradientFill.js +120 -0
  96. package/dist/bitmapGradientFill.js.map +1 -0
  97. package/dist/bitmapHistogram.d.ts +20 -0
  98. package/dist/bitmapHistogram.d.ts.map +1 -0
  99. package/dist/bitmapHistogram.js +61 -0
  100. package/dist/bitmapHistogram.js.map +1 -0
  101. package/dist/bitmapImageChannel.d.ts +2 -0
  102. package/dist/bitmapImageChannel.d.ts.map +1 -0
  103. package/dist/bitmapImageChannel.js +2 -0
  104. package/dist/bitmapImageChannel.js.map +1 -0
  105. package/dist/bitmapMedian.d.ts +14 -0
  106. package/dist/bitmapMedian.d.ts.map +1 -0
  107. package/dist/bitmapMedian.js +77 -0
  108. package/dist/bitmapMedian.js.map +1 -0
  109. package/dist/bitmapMorphological.d.ts +29 -0
  110. package/dist/bitmapMorphological.d.ts.map +1 -0
  111. package/dist/bitmapMorphological.js +81 -0
  112. package/dist/bitmapMorphological.js.map +1 -0
  113. package/dist/bitmapNoise.d.ts +48 -0
  114. package/dist/bitmapNoise.d.ts.map +1 -0
  115. package/dist/bitmapNoise.js +245 -0
  116. package/dist/bitmapNoise.js.map +1 -0
  117. package/dist/bitmapPaletteMap.d.ts +17 -0
  118. package/dist/bitmapPaletteMap.d.ts.map +1 -0
  119. package/dist/bitmapPaletteMap.js +45 -0
  120. package/dist/bitmapPaletteMap.js.map +1 -0
  121. package/dist/bitmapPixel.d.ts +9 -0
  122. package/dist/bitmapPixel.d.ts.map +1 -0
  123. package/dist/bitmapPixel.js +36 -0
  124. package/dist/bitmapPixel.js.map +1 -0
  125. package/dist/bitmapPixelate.d.ts +13 -0
  126. package/dist/bitmapPixelate.d.ts.map +1 -0
  127. package/dist/bitmapPixelate.js +61 -0
  128. package/dist/bitmapPixelate.js.map +1 -0
  129. package/dist/bitmapQuery.d.ts +13 -0
  130. package/dist/bitmapQuery.d.ts.map +1 -0
  131. package/dist/bitmapQuery.js +46 -0
  132. package/dist/bitmapQuery.js.map +1 -0
  133. package/dist/bitmapRegion.d.ts +20 -0
  134. package/dist/bitmapRegion.d.ts.map +1 -0
  135. package/dist/bitmapRegion.js +28 -0
  136. package/dist/bitmapRegion.js.map +1 -0
  137. package/dist/bitmapResize.d.ts +17 -0
  138. package/dist/bitmapResize.d.ts.map +1 -0
  139. package/dist/bitmapResize.js +191 -0
  140. package/dist/bitmapResize.js.map +1 -0
  141. package/dist/bitmapRotate.d.ts +32 -0
  142. package/dist/bitmapRotate.d.ts.map +1 -0
  143. package/dist/bitmapRotate.js +143 -0
  144. package/dist/bitmapRotate.js.map +1 -0
  145. package/dist/bitmapShadow.d.ts +72 -0
  146. package/dist/bitmapShadow.d.ts.map +1 -0
  147. package/dist/bitmapShadow.js +175 -0
  148. package/dist/bitmapShadow.js.map +1 -0
  149. package/dist/bitmapSharpen.d.ts +16 -0
  150. package/dist/bitmapSharpen.d.ts.map +1 -0
  151. package/dist/bitmapSharpen.js +47 -0
  152. package/dist/bitmapSharpen.js.map +1 -0
  153. package/dist/bitmapTone.d.ts +28 -0
  154. package/dist/bitmapTone.d.ts.map +1 -0
  155. package/dist/bitmapTone.js +69 -0
  156. package/dist/bitmapTone.js.map +1 -0
  157. package/dist/bitmapTransform.d.ts +40 -0
  158. package/dist/bitmapTransform.d.ts.map +1 -0
  159. package/dist/bitmapTransform.js +163 -0
  160. package/dist/bitmapTransform.js.map +1 -0
  161. package/dist/bitmapWarp.d.ts +48 -0
  162. package/dist/bitmapWarp.d.ts.map +1 -0
  163. package/dist/bitmapWarp.js +284 -0
  164. package/dist/bitmapWarp.js.map +1 -0
  165. package/dist/contract.d.ts +43 -0
  166. package/dist/contract.d.ts.map +1 -0
  167. package/dist/contract.js +43 -0
  168. package/dist/contract.js.map +1 -0
  169. package/dist/explainBitmapReadback.d.ts +3 -0
  170. package/dist/explainBitmapReadback.d.ts.map +1 -0
  171. package/dist/explainBitmapReadback.js +39 -0
  172. package/dist/explainBitmapReadback.js.map +1 -0
  173. package/dist/index.d.ts +2 -0
  174. package/dist/index.d.ts.map +1 -0
  175. package/dist/index.js +2 -0
  176. package/dist/index.js.map +1 -0
  177. package/package.json +48 -0
  178. package/src/bitmap.test.ts +88 -0
  179. package/src/bitmapAffine.test.ts +98 -0
  180. package/src/bitmapAlpha.test.ts +110 -0
  181. package/src/bitmapBevel.test.ts +61 -0
  182. package/src/bitmapBlur.test.ts +234 -0
  183. package/src/bitmapChannel.test.ts +97 -0
  184. package/src/bitmapColorMatrix.test.ts +214 -0
  185. package/src/bitmapCompare.test.ts +92 -0
  186. package/src/bitmapComposite.test.ts +259 -0
  187. package/src/bitmapConvolution.test.ts +130 -0
  188. package/src/bitmapCopy.test.ts +48 -0
  189. package/src/bitmapCoverage.test.ts +39 -0
  190. package/src/bitmapCrop.test.ts +116 -0
  191. package/src/bitmapDisplacement.test.ts +181 -0
  192. package/src/bitmapDissolve.test.ts +99 -0
  193. package/src/bitmapDraw.test.ts +68 -0
  194. package/src/bitmapEncode.test.ts +18 -0
  195. package/src/bitmapFill.test.ts +83 -0
  196. package/src/bitmapFingerprint.test.ts +103 -0
  197. package/src/bitmapFlip.test.ts +53 -0
  198. package/src/bitmapFormat.test.ts +124 -0
  199. package/src/bitmapFrom.test.ts +86 -0
  200. package/src/bitmapGradient.test.ts +85 -0
  201. package/src/bitmapGradientFill.test.ts +107 -0
  202. package/src/bitmapHistogram.test.ts +64 -0
  203. package/src/bitmapImageChannel.test.ts +19 -0
  204. package/src/bitmapMedian.test.ts +39 -0
  205. package/src/bitmapMorphological.test.ts +69 -0
  206. package/src/bitmapNoise.test.ts +163 -0
  207. package/src/bitmapPaletteMap.test.ts +49 -0
  208. package/src/bitmapPixel.test.ts +117 -0
  209. package/src/bitmapPixelate.test.ts +40 -0
  210. package/src/bitmapQuery.test.ts +42 -0
  211. package/src/bitmapRegion.test.ts +34 -0
  212. package/src/bitmapResize.test.ts +106 -0
  213. package/src/bitmapRotate.test.ts +108 -0
  214. package/src/bitmapShadow.test.ts +159 -0
  215. package/src/bitmapSharpen.test.ts +44 -0
  216. package/src/bitmapTone.test.ts +104 -0
  217. package/src/bitmapTransform.test.ts +128 -0
  218. package/src/bitmapWarp.test.ts +118 -0
  219. package/src/explainBitmapReadback.test.ts +84 -0
@@ -0,0 +1,78 @@
1
+ import { invalidateBitmap } from './bitmap';
2
+ /**
3
+ * Copies one channel of `source` into a channel of `dest`. The copied size is
4
+ * the overlap of the two regions; pixels outside either bitmap are skipped.
5
+ *
6
+ * Safe to pass the same bitmap in `dest` and `source` as long as `destChannel`
7
+ * and `sourceChannel` differ (each pixel writes a different byte than it reads).
8
+ * Copying a channel to itself is always a no-op regardless of aliasing.
9
+ */
10
+ export function copyBitmapChannel(dest, destChannel, source, sourceChannel) {
11
+ const w = Math.min(dest.width, source.width);
12
+ const h = Math.min(dest.height, source.height);
13
+ for (let py = 0; py < h; py++) {
14
+ const sy = source.y + py;
15
+ const dy = dest.y + py;
16
+ if (sy < 0 || sy >= source.bitmap.height || dy < 0 || dy >= dest.bitmap.height)
17
+ continue;
18
+ for (let px = 0; px < w; px++) {
19
+ const sx = source.x + px;
20
+ const dx = dest.x + px;
21
+ if (sx < 0 || sx >= source.bitmap.width || dx < 0 || dx >= dest.bitmap.width)
22
+ continue;
23
+ const si = (sy * source.bitmap.width + sx) * 4;
24
+ const di = (dy * dest.bitmap.width + dx) * 4;
25
+ dest.bitmap.data[di + destChannel] = source.bitmap.data[si + sourceChannel];
26
+ }
27
+ }
28
+ invalidateBitmap(dest.bitmap);
29
+ }
30
+ /**
31
+ * Copies `source` into `dest`. The copied size is the overlap of the two
32
+ * regions; pixels outside either bitmap are skipped. When `composite` is
33
+ * true, `source` is alpha-composited (Porter-Duff source-over) over `dest`
34
+ * instead of overwriting it.
35
+ *
36
+ * Safe to pass the same bitmap in `dest` and `source` when the regions do not
37
+ * overlap. Overlapping regions produce undefined results because pixels are
38
+ * written before all source reads are complete.
39
+ */
40
+ export function copyBitmapPixels(dest, source, composite = false) {
41
+ const w = Math.min(dest.width, source.width);
42
+ const h = Math.min(dest.height, source.height);
43
+ const sd = source.bitmap.data;
44
+ const dd = dest.bitmap.data;
45
+ for (let py = 0; py < h; py++) {
46
+ const sy = source.y + py;
47
+ const dy = dest.y + py;
48
+ if (sy < 0 || sy >= source.bitmap.height || dy < 0 || dy >= dest.bitmap.height)
49
+ continue;
50
+ for (let px = 0; px < w; px++) {
51
+ const sx = source.x + px;
52
+ const dx = dest.x + px;
53
+ if (sx < 0 || sx >= source.bitmap.width || dx < 0 || dx >= dest.bitmap.width)
54
+ continue;
55
+ const si = (sy * source.bitmap.width + sx) * 4;
56
+ const di = (dy * dest.bitmap.width + dx) * 4;
57
+ if (composite) {
58
+ const srcA = sd[si + 3] / 255;
59
+ const dstA = dd[di + 3] / 255;
60
+ const outA = srcA + dstA * (1 - srcA);
61
+ if (outA > 0) {
62
+ dd[di] = Math.round((sd[si] * srcA + dd[di] * dstA * (1 - srcA)) / outA);
63
+ dd[di + 1] = Math.round((sd[si + 1] * srcA + dd[di + 1] * dstA * (1 - srcA)) / outA);
64
+ dd[di + 2] = Math.round((sd[si + 2] * srcA + dd[di + 2] * dstA * (1 - srcA)) / outA);
65
+ dd[di + 3] = Math.round(outA * 255);
66
+ }
67
+ }
68
+ else {
69
+ dd[di] = sd[si];
70
+ dd[di + 1] = sd[si + 1];
71
+ dd[di + 2] = sd[si + 2];
72
+ dd[di + 3] = sd[si + 3];
73
+ }
74
+ }
75
+ }
76
+ invalidateBitmap(dest.bitmap);
77
+ }
78
+ //# sourceMappingURL=bitmapCopy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitmapCopy.js","sourceRoot":"","sources":["../src/bitmapCopy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Bitmap } from '@flighthq/types/contract';
2
+ /**
3
+ * Returns the fraction of pixels (0..1) that differ from `backgroundColor` by more than
4
+ * `channelTolerance` on at least one RGBA channel. This is the "did anything render" signal: a blank
5
+ * frame (the whole bitmap still the clear colour, or fully transparent) returns ~0; a populated
6
+ * frame returns a meaningful fraction. `backgroundColor` is a packed 0xRRGGBBAA value — pass the
7
+ * render state's clear colour. `channelTolerance` (0..255) absorbs antialiasing fringe around the
8
+ * cleared edges so a genuinely empty frame does not creep above zero.
9
+ */
10
+ export declare function getBitmapCoverage(source: Readonly<Bitmap>, backgroundColor: number, channelTolerance?: number): number;
11
+ //# sourceMappingURL=bitmapCoverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitmapCoverage.d.ts","sourceRoot":"","sources":["../src/bitmapCoverage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAEvD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,EACxB,eAAe,EAAE,MAAM,EACvB,gBAAgB,GAAE,MAAU,GAC3B,MAAM,CAqBR"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Returns the fraction of pixels (0..1) that differ from `backgroundColor` by more than
3
+ * `channelTolerance` on at least one RGBA channel. This is the "did anything render" signal: a blank
4
+ * frame (the whole bitmap still the clear colour, or fully transparent) returns ~0; a populated
5
+ * frame returns a meaningful fraction. `backgroundColor` is a packed 0xRRGGBBAA value — pass the
6
+ * render state's clear colour. `channelTolerance` (0..255) absorbs antialiasing fringe around the
7
+ * cleared edges so a genuinely empty frame does not creep above zero.
8
+ */
9
+ export function getBitmapCoverage(source, backgroundColor, channelTolerance = 0) {
10
+ const br = (backgroundColor >>> 24) & 0xff;
11
+ const bg = (backgroundColor >> 16) & 0xff;
12
+ const bb = (backgroundColor >> 8) & 0xff;
13
+ const ba = backgroundColor & 0xff;
14
+ const data = source.data;
15
+ const totalPixels = source.width * source.height;
16
+ if (totalPixels === 0)
17
+ return 0;
18
+ let covered = 0;
19
+ for (let i = 0; i < data.length; i += 4) {
20
+ if (Math.abs(data[i] - br) > channelTolerance ||
21
+ Math.abs(data[i + 1] - bg) > channelTolerance ||
22
+ Math.abs(data[i + 2] - bb) > channelTolerance ||
23
+ Math.abs(data[i + 3] - ba) > channelTolerance) {
24
+ covered++;
25
+ }
26
+ }
27
+ return covered / totalPixels;
28
+ }
29
+ //# sourceMappingURL=bitmapCoverage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitmapCoverage.js","sourceRoot":"","sources":["../src/bitmapCoverage.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAwB,EACxB,eAAuB,EACvB,mBAA2B,CAAC;IAE5B,MAAM,EAAE,GAAG,CAAC,eAAe,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAC3C,MAAM,EAAE,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IAC1C,MAAM,EAAE,GAAG,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IACzC,MAAM,EAAE,GAAG,eAAe,GAAG,IAAI,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;IACjD,IAAI,WAAW,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAEhC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,IACE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,gBAAgB;YACzC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,gBAAgB;YAC7C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,gBAAgB;YAC7C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,gBAAgB,EAC7C,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,OAAO,GAAG,WAAW,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { RectangleLike, Bitmap, BitmapEdgeMode } from '@flighthq/types/contract';
2
+ /**
3
+ * Allocates a new `Bitmap` containing the pixels of `source` cropped to
4
+ * `rect`. `rect` coordinates are relative to the `source` bitmap origin
5
+ * (not to a region offset). Pixels of `rect` that fall outside the bitmap
6
+ * are filled with transparent black.
7
+ *
8
+ * Returns a new `Bitmap` with the same `colorSpace`, `alphaType`, and
9
+ * `format` as `source`, with dimensions equal to `rect.width × rect.height`.
10
+ */
11
+ export declare function cropBitmap(source: Readonly<Bitmap>, rect: Readonly<RectangleLike>): Bitmap;
12
+ /**
13
+ * Allocates a new `Bitmap` with `source` padded by `left`, `top`, `right`,
14
+ * and `bottom` pixels on each side. Added pixels are filled according to
15
+ * `edgeMode`:
16
+ * - `'transparent'` (default): filled with transparent black.
17
+ * - `'clamp'`: border pixels of `source` are repeated.
18
+ * - `'wrap'`: `source` is tiled.
19
+ * - `'mirror'`: `source` is mirrored at the edges.
20
+ *
21
+ * When `edgeMode` is `'transparent'`, the optional `fillColor` (packed RGBA,
22
+ * e.g. `0xffffffff` for opaque white) overrides the default transparent fill.
23
+ * It is ignored for all other edge modes.
24
+ */
25
+ export declare function extendBitmap(source: Readonly<Bitmap>, left: number, top: number, right: number, bottom: number, edgeMode?: BitmapEdgeMode, fillColor?: number): Bitmap;
26
+ /**
27
+ * Allocates a new `Bitmap` with the transparent border of `source` removed.
28
+ * Finds the tightest bounding box of all pixels with alpha > 0 and returns a
29
+ * new bitmap cropped to that box. If the entire bitmap is transparent,
30
+ * returns a 1×1 transparent bitmap.
31
+ */
32
+ export declare function trimBitmap(source: Readonly<Bitmap>): Bitmap;
33
+ //# sourceMappingURL=bitmapCrop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitmapCrop.d.ts","sourceRoot":"","sources":["../src/bitmapCrop.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAGtF;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,GAAG,MAAM,CAiC1F;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,EACxB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,cAA8B,EACxC,SAAS,SAAI,GACZ,MAAM,CAkDR;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAgC3D"}
@@ -0,0 +1,175 @@
1
+ import { createEntity } from '@flighthq/entity/contract';
2
+ import { BitmapTextureSourceKind } from '@flighthq/types/contract';
3
+ /**
4
+ * Allocates a new `Bitmap` containing the pixels of `source` cropped to
5
+ * `rect`. `rect` coordinates are relative to the `source` bitmap origin
6
+ * (not to a region offset). Pixels of `rect` that fall outside the bitmap
7
+ * are filled with transparent black.
8
+ *
9
+ * Returns a new `Bitmap` with the same `colorSpace`, `alphaType`, and
10
+ * `format` as `source`, with dimensions equal to `rect.width × rect.height`.
11
+ */
12
+ export function cropBitmap(source, rect) {
13
+ const sw = source.width;
14
+ const sh = source.height;
15
+ const rx = Math.round(rect.x);
16
+ const ry = Math.round(rect.y);
17
+ const rw = Math.max(0, Math.round(rect.width));
18
+ const rh = Math.max(0, Math.round(rect.height));
19
+ const data = new Uint8ClampedArray(rw * rh * 4);
20
+ const sd = source.data;
21
+ for (let py = 0; py < rh; py++) {
22
+ const sy = ry + py;
23
+ if (sy < 0 || sy >= sh)
24
+ continue;
25
+ for (let px = 0; px < rw; px++) {
26
+ const sx = rx + px;
27
+ if (sx < 0 || sx >= sw)
28
+ continue;
29
+ const si = (sy * sw + sx) * 4;
30
+ const di = (py * rw + px) * 4;
31
+ data[di] = sd[si];
32
+ data[di + 1] = sd[si + 1];
33
+ data[di + 2] = sd[si + 2];
34
+ data[di + 3] = sd[si + 3];
35
+ }
36
+ }
37
+ return createEntity({
38
+ alphaType: source.alphaType,
39
+ colorSpace: source.colorSpace,
40
+ data,
41
+ format: source.format,
42
+ height: rh,
43
+ kind: BitmapTextureSourceKind,
44
+ version: 0,
45
+ width: rw,
46
+ });
47
+ }
48
+ /**
49
+ * Allocates a new `Bitmap` with `source` padded by `left`, `top`, `right`,
50
+ * and `bottom` pixels on each side. Added pixels are filled according to
51
+ * `edgeMode`:
52
+ * - `'transparent'` (default): filled with transparent black.
53
+ * - `'clamp'`: border pixels of `source` are repeated.
54
+ * - `'wrap'`: `source` is tiled.
55
+ * - `'mirror'`: `source` is mirrored at the edges.
56
+ *
57
+ * When `edgeMode` is `'transparent'`, the optional `fillColor` (packed RGBA,
58
+ * e.g. `0xffffffff` for opaque white) overrides the default transparent fill.
59
+ * It is ignored for all other edge modes.
60
+ */
61
+ export function extendBitmap(source, left, top, right, bottom, edgeMode = 'transparent', fillColor = 0) {
62
+ const sw = source.width;
63
+ const sh = source.height;
64
+ const dw = sw + left + right;
65
+ const dh = sh + top + bottom;
66
+ const data = new Uint8ClampedArray(dw * dh * 4);
67
+ const sd = source.data;
68
+ const fr = (fillColor >>> 24) & 0xff;
69
+ const fg = (fillColor >> 16) & 0xff;
70
+ const fb = (fillColor >> 8) & 0xff;
71
+ const fa = fillColor & 0xff;
72
+ for (let py = 0; py < dh; py++) {
73
+ for (let px = 0; px < dw; px++) {
74
+ const sx = px - left;
75
+ const sy = py - top;
76
+ const di = (py * dw + px) * 4;
77
+ if (sx >= 0 && sx < sw && sy >= 0 && sy < sh) {
78
+ const si = (sy * sw + sx) * 4;
79
+ data[di] = sd[si];
80
+ data[di + 1] = sd[si + 1];
81
+ data[di + 2] = sd[si + 2];
82
+ data[di + 3] = sd[si + 3];
83
+ }
84
+ else {
85
+ const cx = resolveEdge(sx, sw, edgeMode);
86
+ const cy = resolveEdge(sy, sh, edgeMode);
87
+ if (cx !== null && cy !== null) {
88
+ const si = (cy * sw + cx) * 4;
89
+ data[di] = sd[si];
90
+ data[di + 1] = sd[si + 1];
91
+ data[di + 2] = sd[si + 2];
92
+ data[di + 3] = sd[si + 3];
93
+ }
94
+ else {
95
+ data[di] = fr;
96
+ data[di + 1] = fg;
97
+ data[di + 2] = fb;
98
+ data[di + 3] = fa;
99
+ }
100
+ }
101
+ }
102
+ }
103
+ return createEntity({
104
+ alphaType: source.alphaType,
105
+ colorSpace: source.colorSpace,
106
+ data,
107
+ format: source.format,
108
+ height: dh,
109
+ kind: BitmapTextureSourceKind,
110
+ version: 0,
111
+ width: dw,
112
+ });
113
+ }
114
+ /**
115
+ * Allocates a new `Bitmap` with the transparent border of `source` removed.
116
+ * Finds the tightest bounding box of all pixels with alpha > 0 and returns a
117
+ * new bitmap cropped to that box. If the entire bitmap is transparent,
118
+ * returns a 1×1 transparent bitmap.
119
+ */
120
+ export function trimBitmap(source) {
121
+ const sw = source.width;
122
+ const sh = source.height;
123
+ const sd = source.data;
124
+ let minX = sw;
125
+ let minY = sh;
126
+ let maxX = -1;
127
+ let maxY = -1;
128
+ for (let py = 0; py < sh; py++) {
129
+ for (let px = 0; px < sw; px++) {
130
+ const a = sd[(py * sw + px) * 4 + 3];
131
+ if (a > 0) {
132
+ if (px < minX)
133
+ minX = px;
134
+ if (px > maxX)
135
+ maxX = px;
136
+ if (py < minY)
137
+ minY = py;
138
+ if (py > maxY)
139
+ maxY = py;
140
+ }
141
+ }
142
+ }
143
+ if (maxX < 0) {
144
+ return createEntity({
145
+ alphaType: source.alphaType,
146
+ colorSpace: source.colorSpace,
147
+ data: new Uint8ClampedArray(4),
148
+ format: source.format,
149
+ height: 1,
150
+ kind: BitmapTextureSourceKind,
151
+ version: 0,
152
+ width: 1,
153
+ });
154
+ }
155
+ return cropBitmap(source, { x: minX, y: minY, width: maxX - minX + 1, height: maxY - minY + 1 });
156
+ }
157
+ function resolveEdge(v, size, mode) {
158
+ if (v >= 0 && v < size)
159
+ return v;
160
+ switch (mode) {
161
+ case 'clamp':
162
+ return Math.max(0, Math.min(size - 1, v));
163
+ case 'wrap':
164
+ return ((v % size) + size) % size;
165
+ case 'mirror': {
166
+ const period = 2 * size;
167
+ const wrapped = ((v % period) + period) % period;
168
+ return wrapped < size ? wrapped : period - 1 - wrapped;
169
+ }
170
+ default:
171
+ // 'transparent'
172
+ return null;
173
+ }
174
+ }
175
+ //# sourceMappingURL=bitmapCrop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitmapCrop.js","sourceRoot":"","sources":["../src/bitmapCrop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { BitmapDisplacementMapOptions, BitmapRegion } from '@flighthq/types/contract';
2
+ /**
3
+ * Warps `source` by sampling each output pixel from a displaced source position,
4
+ * writing into `out`. The displacement for pixel (px, py) is read from `map` at
5
+ * the aligned position and scaled:
6
+ *
7
+ * dx = (mapValueX / 255 - 0.5) * scaleX
8
+ * dy = (mapValueY / 255 - 0.5) * scaleY
9
+ *
10
+ * A map value of 128 is approximately neutral (< 0.2px shift). Sampling uses
11
+ * bilinear interpolation.
12
+ *
13
+ * When `edgeMode` is set, it controls out-of-bounds behaviour using the standard
14
+ * `BitmapEdgeMode` values (`'clamp'`, `'wrap'`, `'mirror'`, `'transparent'`).
15
+ * Otherwise `mode` is used: `'wrap'` tiles, `'clamp'` holds the edge, `'ignore'`
16
+ * keeps the undisplaced source pixel, and `'color'` fills with `fillColor`.
17
+ *
18
+ * `out` must be at least `source.width * source.height * 4` bytes and must NOT
19
+ * alias `source.bitmap.data` — output pixels read arbitrary source positions.
20
+ */
21
+ export declare function displaceBitmap(out: Uint8ClampedArray, source: Readonly<BitmapRegion>, options: Readonly<BitmapDisplacementMapOptions>): void;
22
+ //# sourceMappingURL=bitmapDisplacement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitmapDisplacement.d.ts","sourceRoot":"","sources":["../src/bitmapDisplacement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAkB,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE3G;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,OAAO,EAAE,QAAQ,CAAC,4BAA4B,CAAC,GAC9C,IAAI,CAqEN"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Warps `source` by sampling each output pixel from a displaced source position,
3
+ * writing into `out`. The displacement for pixel (px, py) is read from `map` at
4
+ * the aligned position and scaled:
5
+ *
6
+ * dx = (mapValueX / 255 - 0.5) * scaleX
7
+ * dy = (mapValueY / 255 - 0.5) * scaleY
8
+ *
9
+ * A map value of 128 is approximately neutral (< 0.2px shift). Sampling uses
10
+ * bilinear interpolation.
11
+ *
12
+ * When `edgeMode` is set, it controls out-of-bounds behaviour using the standard
13
+ * `BitmapEdgeMode` values (`'clamp'`, `'wrap'`, `'mirror'`, `'transparent'`).
14
+ * Otherwise `mode` is used: `'wrap'` tiles, `'clamp'` holds the edge, `'ignore'`
15
+ * keeps the undisplaced source pixel, and `'color'` fills with `fillColor`.
16
+ *
17
+ * `out` must be at least `source.width * source.height * 4` bytes and must NOT
18
+ * alias `source.bitmap.data` — output pixels read arbitrary source positions.
19
+ */
20
+ export function displaceBitmap(out, source, options) {
21
+ const w = source.width;
22
+ const h = source.height;
23
+ const map = options.map;
24
+ const componentX = options.componentX ?? 0;
25
+ const componentY = options.componentY ?? 1;
26
+ const scaleX = options.scaleX ?? 0;
27
+ const scaleY = options.scaleY ?? 0;
28
+ const edgeMode = options.edgeMode;
29
+ const mode = options.mode ?? 'wrap';
30
+ const fillColor = options.fillColor ?? 0;
31
+ const fillR = (fillColor >>> 24) & 0xff;
32
+ const fillG = (fillColor >> 16) & 0xff;
33
+ const fillB = (fillColor >> 8) & 0xff;
34
+ const fillA = fillColor & 0xff;
35
+ for (let py = 0; py < h; py++) {
36
+ for (let px = 0; px < w; px++) {
37
+ const di = (py * w + px) * 4;
38
+ const mapVx = sampleMapChannel(map, px, py, componentX);
39
+ const mapVy = sampleMapChannel(map, px, py, componentY);
40
+ const rawSampleX = px + (mapVx / 255 - 0.5) * scaleX;
41
+ const rawSampleY = py + (mapVy / 255 - 0.5) * scaleY;
42
+ let sampleX = rawSampleX;
43
+ let sampleY = rawSampleY;
44
+ if (edgeMode === undefined && (rawSampleX < 0 || rawSampleX >= w || rawSampleY < 0 || rawSampleY >= h)) {
45
+ if (mode === 'wrap') {
46
+ sampleX = ((rawSampleX % w) + w) % w;
47
+ sampleY = ((rawSampleY % h) + h) % h;
48
+ }
49
+ else if (mode === 'clamp') {
50
+ sampleX = Math.max(0, Math.min(w - 1, rawSampleX));
51
+ sampleY = Math.max(0, Math.min(h - 1, rawSampleY));
52
+ }
53
+ else if (mode === 'ignore') {
54
+ sampleX = px;
55
+ sampleY = py;
56
+ }
57
+ else {
58
+ out[di] = fillR;
59
+ out[di + 1] = fillG;
60
+ out[di + 2] = fillB;
61
+ out[di + 3] = fillA;
62
+ continue;
63
+ }
64
+ }
65
+ const x0 = Math.floor(sampleX);
66
+ const y0 = Math.floor(sampleY);
67
+ const tx = sampleX - x0;
68
+ const ty = sampleY - y0;
69
+ const sStride = source.bitmap.width;
70
+ const sData = source.bitmap.data;
71
+ const rx0 = edgeMode === undefined ? Math.max(0, Math.min(w - 1, x0)) : resolveDisplacementEdge(x0, w, edgeMode);
72
+ const rx1 = edgeMode === undefined ? Math.max(0, Math.min(w - 1, x0 + 1)) : resolveDisplacementEdge(x0 + 1, w, edgeMode);
73
+ const ry0 = edgeMode === undefined ? Math.max(0, Math.min(h - 1, y0)) : resolveDisplacementEdge(y0, h, edgeMode);
74
+ const ry1 = edgeMode === undefined ? Math.max(0, Math.min(h - 1, y0 + 1)) : resolveDisplacementEdge(y0 + 1, h, edgeMode);
75
+ const i00 = rx0 === null || ry0 === null ? -1 : ((source.y + ry0) * sStride + source.x + rx0) * 4;
76
+ const i10 = rx1 === null || ry0 === null ? -1 : ((source.y + ry0) * sStride + source.x + rx1) * 4;
77
+ const i01 = rx0 === null || ry1 === null ? -1 : ((source.y + ry1) * sStride + source.x + rx0) * 4;
78
+ const i11 = rx1 === null || ry1 === null ? -1 : ((source.y + ry1) * sStride + source.x + rx1) * 4;
79
+ for (let c = 0; c < 4; c++) {
80
+ const top = (i00 < 0 ? 0 : sData[i00 + c]) * (1 - tx) + (i10 < 0 ? 0 : sData[i10 + c]) * tx;
81
+ const bottom = (i01 < 0 ? 0 : sData[i01 + c]) * (1 - tx) + (i11 < 0 ? 0 : sData[i11 + c]) * tx;
82
+ out[di + c] = Math.round(top * (1 - ty) + bottom * ty);
83
+ }
84
+ }
85
+ }
86
+ }
87
+ function resolveDisplacementEdge(v, size, mode) {
88
+ if (v >= 0 && v < size)
89
+ return v;
90
+ switch (mode) {
91
+ case 'clamp':
92
+ return Math.max(0, Math.min(size - 1, v));
93
+ case 'wrap':
94
+ return ((v % size) + size) % size;
95
+ case 'mirror': {
96
+ const period = 2 * size;
97
+ const wrapped = ((v % period) + period) % period;
98
+ return wrapped < size ? wrapped : period - 1 - wrapped;
99
+ }
100
+ default:
101
+ return null;
102
+ }
103
+ }
104
+ function sampleMapChannel(map, px, py, component) {
105
+ const mx = map.x + px;
106
+ const my = map.y + py;
107
+ if (mx < 0 || mx >= map.bitmap.width || my < 0 || my >= map.bitmap.height)
108
+ return 128;
109
+ return map.bitmap.data[(my * map.bitmap.width + mx) * 4 + component];
110
+ }
111
+ //# sourceMappingURL=bitmapDisplacement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitmapDisplacement.js","sourceRoot":"","sources":["../src/bitmapDisplacement.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { BitmapRegion } from '@flighthq/types/contract';
2
+ /**
3
+ * Transitions `dest` toward `source` one batch of pixels at a time, in a
4
+ * deterministic pseudo-random order — the classic dissolve wipe. Each call
5
+ * dissolves up to `pixelCount` not-yet-dissolved pixels and returns the next
6
+ * seed; pass that value back on the following call to continue the wipe without
7
+ * revisiting any pixel. Start a fresh dissolve with `seed = 0`. Once every pixel
8
+ * has dissolved the returned seed is terminal: further calls with it are no-ops.
9
+ *
10
+ * `seed` is an opaque progress cursor over a fixed permutation of the region's
11
+ * pixels, not a color or coordinate. The dissolve order is fully deterministic
12
+ * in the region's dimensions.
13
+ *
14
+ * When `source` is the same region as `dest` (same bitmap and identical
15
+ * bounds), dissolved pixels are set to `fillColor` (packed `0xRRGGBBAA`);
16
+ * otherwise each is copied from the matching pixel in
17
+ * `source` and `fillColor` is ignored. Pixels that fall outside the bitmap are
18
+ * clipped but still consume a step of the sequence.
19
+ */
20
+ export declare function dissolveBitmapPixels(dest: Readonly<BitmapRegion>, source: Readonly<BitmapRegion>, seed: number, pixelCount: number, fillColor?: number): number;
21
+ //# sourceMappingURL=bitmapDissolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitmapDissolve.d.ts","sourceRoot":"","sources":["../src/bitmapDissolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAI7D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC9B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAAU,GACpB,MAAM,CAkER"}
@@ -0,0 +1,97 @@
1
+ import { invalidateBitmap } from './bitmap';
2
+ /**
3
+ * Transitions `dest` toward `source` one batch of pixels at a time, in a
4
+ * deterministic pseudo-random order — the classic dissolve wipe. Each call
5
+ * dissolves up to `pixelCount` not-yet-dissolved pixels and returns the next
6
+ * seed; pass that value back on the following call to continue the wipe without
7
+ * revisiting any pixel. Start a fresh dissolve with `seed = 0`. Once every pixel
8
+ * has dissolved the returned seed is terminal: further calls with it are no-ops.
9
+ *
10
+ * `seed` is an opaque progress cursor over a fixed permutation of the region's
11
+ * pixels, not a color or coordinate. The dissolve order is fully deterministic
12
+ * in the region's dimensions.
13
+ *
14
+ * When `source` is the same region as `dest` (same bitmap and identical
15
+ * bounds), dissolved pixels are set to `fillColor` (packed `0xRRGGBBAA`);
16
+ * otherwise each is copied from the matching pixel in
17
+ * `source` and `fillColor` is ignored. Pixels that fall outside the bitmap are
18
+ * clipped but still consume a step of the sequence.
19
+ */
20
+ export function dissolveBitmapPixels(dest, source, seed, pixelCount, fillColor = 0) {
21
+ const width = dest.width;
22
+ const height = dest.height;
23
+ const total = width * height;
24
+ if (total <= 0)
25
+ return seed;
26
+ let bits = 0;
27
+ while (1 << bits < total)
28
+ bits++;
29
+ const period = 1 << bits;
30
+ const mask = period - 1;
31
+ let cursor = seed < 0 ? 0 : seed > period ? period : seed | 0;
32
+ if (pixelCount <= 0)
33
+ return cursor;
34
+ const toFill = source.bitmap === dest.bitmap &&
35
+ source.x === dest.x &&
36
+ source.y === dest.y &&
37
+ source.width === dest.width &&
38
+ source.height === dest.height;
39
+ const fillR = (fillColor >>> 24) & 0xff;
40
+ const fillG = (fillColor >> 16) & 0xff;
41
+ const fillB = (fillColor >> 8) & 0xff;
42
+ const fillA = fillColor & 0xff;
43
+ const destData = dest.bitmap.data;
44
+ const destStride = dest.bitmap.width;
45
+ const destBitmapHeight = dest.bitmap.height;
46
+ const sourceData = source.bitmap.data;
47
+ const sourceStride = source.bitmap.width;
48
+ const sourceBitmapHeight = source.bitmap.height;
49
+ let dissolved = 0;
50
+ while (dissolved < pixelCount && cursor < period) {
51
+ const pixelIndex = permutePixelIndex(cursor, bits, mask);
52
+ cursor++;
53
+ if (pixelIndex >= total)
54
+ continue;
55
+ dissolved++;
56
+ const px = pixelIndex % width;
57
+ const py = (pixelIndex / width) | 0;
58
+ const dx = dest.x + px;
59
+ const dy = dest.y + py;
60
+ if (dx < 0 || dx >= destStride || dy < 0 || dy >= destBitmapHeight)
61
+ continue;
62
+ const di = (dy * destStride + dx) * 4;
63
+ if (toFill) {
64
+ destData[di] = fillR;
65
+ destData[di + 1] = fillG;
66
+ destData[di + 2] = fillB;
67
+ destData[di + 3] = fillA;
68
+ continue;
69
+ }
70
+ const sx = source.x + px;
71
+ const sy = source.y + py;
72
+ if (sx < 0 || sx >= sourceStride || sy < 0 || sy >= sourceBitmapHeight)
73
+ continue;
74
+ const si = (sy * sourceStride + sx) * 4;
75
+ destData[di] = sourceData[si];
76
+ destData[di + 1] = sourceData[si + 1];
77
+ destData[di + 2] = sourceData[si + 2];
78
+ destData[di + 3] = sourceData[si + 3];
79
+ }
80
+ invalidateBitmap(dest.bitmap);
81
+ return cursor;
82
+ }
83
+ // Bijection on [0, 2^bits): a composition of multiply-by-odd (invertible mod
84
+ // 2^bits), xor-shift, and xor-constant, each individually reversible. Walking
85
+ // `cursor` across the full period therefore visits every index in [0, total)
86
+ // exactly once (cycle-walking skips the indices >= total), which is what
87
+ // guarantees a dissolve eventually covers the whole region without repeats.
88
+ function permutePixelIndex(cursor, bits, mask) {
89
+ let v = cursor & mask;
90
+ const shift = bits > 1 ? bits >> 1 : 1;
91
+ v = Math.imul(v, 0x9e3779b1) & mask;
92
+ v ^= v >>> shift;
93
+ v = Math.imul(v, 0x85ebca77) & mask;
94
+ v ^= 0x27d4eb2f & mask;
95
+ return v & mask;
96
+ }
97
+ //# sourceMappingURL=bitmapDissolve.js.map