pixel-data-js 0.26.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +12 -2
  2. package/dist/index.prod.cjs +2227 -1050
  3. package/dist/index.prod.cjs.map +1 -1
  4. package/dist/index.prod.d.ts +549 -424
  5. package/dist/index.prod.js +2171 -1028
  6. package/dist/index.prod.js.map +1 -1
  7. package/package.json +11 -11
  8. package/src/Algorithm/floodFillSelection.ts +8 -6
  9. package/src/Algorithm/forEachLinePoint.ts +6 -6
  10. package/src/{Internal/resample32.ts → Algorithm/resampleUint32Array.ts} +11 -21
  11. package/src/BlendModes/blend-modes-fast.ts +169 -0
  12. package/src/BlendModes/blend-modes-perfect.ts +207 -0
  13. package/src/BlendModes/blend-modes.ts +9 -0
  14. package/src/Canvas/CanvasFrameRenderer.ts +20 -28
  15. package/src/Canvas/CanvasPixelDataRenderer.ts +23 -0
  16. package/src/Canvas/PixelCanvas.ts +2 -7
  17. package/src/Canvas/ReusableCanvas.ts +4 -12
  18. package/src/Canvas/_canvas-types.ts +26 -0
  19. package/src/History/PixelAccumulator.ts +17 -17
  20. package/src/History/PixelEngineConfig.ts +3 -3
  21. package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +4 -3
  22. package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +4 -3
  23. package/src/History/PixelMutator/mutatorApplyMask.ts +4 -3
  24. package/src/History/PixelMutator/mutatorBlendAlphaMask.ts +6 -4
  25. package/src/History/PixelMutator/mutatorBlendBinaryMask.ts +6 -4
  26. package/src/History/PixelMutator/mutatorBlendColor.ts +2 -2
  27. package/src/History/PixelMutator/mutatorBlendColorPaintAlphaMask.ts +2 -1
  28. package/src/History/PixelMutator/mutatorBlendColorPaintBinaryMask.ts +2 -1
  29. package/src/History/PixelMutator/mutatorBlendColorPaintMask.ts +3 -1
  30. package/src/History/PixelMutator/{mutatorBlendPaintRect.ts → mutatorBlendColorPaintRect.ts} +5 -5
  31. package/src/History/PixelMutator/mutatorBlendMask.ts +6 -4
  32. package/src/History/PixelMutator/mutatorBlendPixelData.ts +5 -4
  33. package/src/History/PixelMutator/mutatorClear.ts +4 -3
  34. package/src/History/PixelMutator/mutatorFill.ts +5 -4
  35. package/src/History/PixelMutator/mutatorFillBinaryMask.ts +2 -1
  36. package/src/History/PixelMutator/mutatorInvert.ts +2 -2
  37. package/src/History/PixelMutator.ts +2 -2
  38. package/src/History/PixelPatchTiles.ts +7 -7
  39. package/src/History/PixelWriter.ts +12 -63
  40. package/src/ImageData/ImageDataLike.ts +1 -1
  41. package/src/ImageData/_ImageData-types.ts +13 -0
  42. package/src/ImageData/copyImageData.ts +1 -1
  43. package/src/ImageData/extractImageDataBuffer.ts +3 -2
  44. package/src/ImageData/imageDataToUint32Array.ts +18 -0
  45. package/src/ImageData/resampleImageData.ts +3 -3
  46. package/src/ImageData/resizeImageData.ts +1 -1
  47. package/src/ImageData/serialization.ts +1 -1
  48. package/src/ImageData/uInt32ArrayToImageData.ts +1 -1
  49. package/src/ImageData/writeImageData.ts +2 -2
  50. package/src/ImageData/writeImageDataBuffer.ts +2 -2
  51. package/src/IndexedImage/IndexedImage.ts +56 -98
  52. package/src/IndexedImage/_indexedImage-types.ts +18 -0
  53. package/src/IndexedImage/getIndexedImageColorCounts.ts +3 -3
  54. package/src/IndexedImage/indexedImageToAverageColor.ts +1 -1
  55. package/src/IndexedImage/indexedImageToImageData.ts +4 -6
  56. package/src/IndexedImage/resampleIndexedImage.ts +7 -15
  57. package/src/Input/fileToImageData.ts +1 -1
  58. package/src/Internal/_errors.ts +2 -0
  59. package/src/Internal/macros.ts +14 -0
  60. package/src/Mask/AlphaMask.ts +1 -1
  61. package/src/Mask/BinaryMask/makeBinaryMaskFromAlphaMask.ts +23 -0
  62. package/src/Mask/BinaryMask/makeBinaryMaskOutline.ts +88 -0
  63. package/src/Mask/BinaryMask/makeCircleBinaryMaskOutline.ts +104 -0
  64. package/src/Mask/BinaryMask/makeRectBinaryMaskOutline.ts +34 -0
  65. package/src/Mask/BinaryMask.ts +1 -1
  66. package/src/Mask/_mask-types.ts +73 -0
  67. package/src/Mask/applyBinaryMaskToAlphaMask.ts +2 -1
  68. package/src/Mask/copyMask.ts +1 -1
  69. package/src/Mask/extractMask.ts +2 -1
  70. package/src/Mask/extractMaskBuffer.ts +1 -1
  71. package/src/Mask/mergeAlphaMasks.ts +6 -3
  72. package/src/Mask/mergeBinaryMasks.ts +2 -1
  73. package/src/Mask/setMaskData.ts +1 -1
  74. package/src/MaskRect/merge2BinaryMaskRects.ts +2 -2
  75. package/src/MaskRect/mergeBinaryMaskRects.ts +1 -1
  76. package/src/MaskRect/subtractBinaryMaskRects.ts +1 -1
  77. package/src/Paint/AlphaMaskPaintBuffer.ts +339 -0
  78. package/src/Paint/AlphaMaskPaintBufferCanvasRenderer.ts +78 -0
  79. package/src/Paint/BinaryMaskPaintBuffer.ts +254 -0
  80. package/src/Paint/BinaryMaskPaintBufferCanvasRenderer.ts +67 -0
  81. package/src/Paint/{PaintBuffer.ts → ColorPaintBuffer.ts} +148 -77
  82. package/src/Paint/{PaintBufferCanvasRenderer.ts → ColorPaintBufferCanvasRenderer.ts} +6 -5
  83. package/src/Paint/PaintCursorRenderer.ts +117 -0
  84. package/src/Paint/_paint-types.ts +22 -0
  85. package/src/Paint/eachTileInBounds.ts +45 -0
  86. package/src/Paint/makeCirclePaintMask.ts +74 -0
  87. package/src/Paint/makePaintMask.ts +5 -2
  88. package/src/Paint/makeRectFalloffPaintAlphaMask.ts +4 -2
  89. package/src/PixelData/PixelData.ts +15 -19
  90. package/src/PixelData/ReusablePixelData.ts +36 -0
  91. package/src/PixelData/_pixelData-types.ts +17 -0
  92. package/src/PixelData/applyAlphaMaskToPixelData.ts +80 -43
  93. package/src/PixelData/applyBinaryMaskToPixelData.ts +10 -8
  94. package/src/PixelData/applyMaskToPixelData.ts +4 -9
  95. package/src/PixelData/blendColorPixelData.ts +9 -8
  96. package/src/PixelData/blendColorPixelDataAlphaMask.ts +9 -7
  97. package/src/PixelData/blendColorPixelDataBinaryMask.ts +9 -7
  98. package/src/PixelData/blendColorPixelDataMask.ts +4 -2
  99. package/src/PixelData/blendColorPixelDataPaintAlphaMask.ts +4 -2
  100. package/src/PixelData/blendColorPixelDataPaintBinaryMask.ts +4 -2
  101. package/src/PixelData/blendColorPixelDataPaintMask.ts +5 -2
  102. package/src/PixelData/blendPixel.ts +6 -5
  103. package/src/PixelData/blendPixelData.ts +14 -13
  104. package/src/PixelData/blendPixelDataAlphaMask.ts +15 -13
  105. package/src/PixelData/blendPixelDataBinaryMask.ts +15 -13
  106. package/src/PixelData/blendPixelDataMask.ts +5 -3
  107. package/src/PixelData/blendPixelDataPaintBuffer.ts +5 -4
  108. package/src/PixelData/clearPixelDataFast.ts +4 -2
  109. package/src/PixelData/copyPixelData.ts +14 -0
  110. package/src/PixelData/extractPixelData.ts +8 -7
  111. package/src/PixelData/extractPixelDataBuffer.ts +9 -8
  112. package/src/PixelData/fillPixelData.ts +16 -14
  113. package/src/PixelData/fillPixelDataBinaryMask.ts +10 -8
  114. package/src/PixelData/fillPixelDataFast.ts +16 -14
  115. package/src/PixelData/invertPixelData.ts +9 -8
  116. package/src/PixelData/pixelDataToAlphaMask.ts +9 -8
  117. package/src/PixelData/reflectPixelData.ts +9 -9
  118. package/src/PixelData/resamplePixelData.ts +20 -9
  119. package/src/PixelData/rotatePixelData.ts +8 -7
  120. package/src/PixelData/uInt32ArrayToPixelData.ts +15 -0
  121. package/src/PixelData/writePaintBufferToPixelData.ts +5 -5
  122. package/src/PixelData/writePixelDataBuffer.ts +10 -9
  123. package/src/Rect/_rect-types.ts +7 -0
  124. package/src/Rect/getRectsBounds.ts +1 -1
  125. package/src/Rect/trimMaskRectBounds.ts +2 -1
  126. package/src/Rect/trimRectBounds.ts +1 -1
  127. package/src/Tile/MaskTile.ts +40 -0
  128. package/src/Tile/PixelTile.ts +23 -0
  129. package/src/{PixelTile/PixelTilePool.ts → Tile/TilePool.ts} +9 -9
  130. package/src/Tile/_tile-types.ts +33 -0
  131. package/src/_errors.ts +1 -0
  132. package/src/_types.ts +2 -118
  133. package/src/index.ts +47 -22
  134. package/src/ImageData/imageDataToUInt32Array.ts +0 -13
  135. package/src/Internal/helpers.ts +0 -5
  136. package/src/Paint/makeCirclePaintAlphaMask.ts +0 -41
  137. package/src/Paint/makeCirclePaintBinaryMask.ts +0 -29
  138. package/src/PixelTile/PixelTile.ts +0 -21
  139. /package/src/{Internal → Rect}/resolveClipping.ts +0 -0
@@ -1,23 +1,19 @@
1
- import type { ImageDataLike, IPixelData } from '../_types'
2
- import { imageDataToUInt32Array } from '../ImageData/imageDataToUInt32Array'
1
+ import type { ImageDataLike } from '../ImageData/_ImageData-types'
2
+ import { _macro_imageDataToUint32Array } from '../ImageData/imageDataToUint32Array'
3
+ import type { PixelData } from './_pixelData-types'
3
4
 
4
- export class PixelData<T extends ImageDataLike = ImageData> implements IPixelData<T> {
5
- readonly data32: Uint32Array
6
- readonly imageData: T
7
- readonly width: number
8
- readonly height: number
9
-
10
- constructor(imageData: T) {
11
- this.data32 = imageDataToUInt32Array(imageData)
12
- this.imageData = imageData
13
- this.width = imageData.width
14
- this.height = imageData.height
5
+ export function makePixelData<T extends ImageDataLike = ImageData>(imageData: T): PixelData<T> {
6
+ return {
7
+ data: _macro_imageDataToUint32Array(imageData),
8
+ imageData,
9
+ w: imageData.width,
10
+ h: imageData.height,
15
11
  }
12
+ }
16
13
 
17
- set(imageData: T): void {
18
- ;(this as any).imageData = imageData
19
- ;(this as any).data32 = imageDataToUInt32Array(imageData)
20
- ;(this as any).width = imageData.width
21
- ;(this as any).height = imageData.height
22
- }
14
+ export function setPixelData(target: PixelData, imageData: ImageData) {
15
+ ;(target as any).data = _macro_imageDataToUint32Array(imageData)
16
+ ;(target as any).imageData = imageData
17
+ ;(target as any).w = imageData.width
18
+ ;(target as any).h = imageData.height
23
19
  }
@@ -0,0 +1,36 @@
1
+ import type { PixelData } from './_pixelData-types'
2
+ import { setPixelData } from './PixelData'
3
+
4
+ export type ReusablePixelData = ReturnType<typeof makeReusablePixelData>
5
+
6
+ /**
7
+ * Creates a factory function that manages a single, reusable PixelData instance.
8
+ * This is used to minimize garbage collection overhead by recycling the
9
+ * underlying pixel buffer across multiple operations.
10
+ * @returns A function that takes width and height and returns a pooled PixelData instance.
11
+ */
12
+ export function makeReusablePixelData() {
13
+ const pixelData = {
14
+ w: 0,
15
+ h: 0,
16
+ data: null as unknown as Uint32Array,
17
+ imageData: null as unknown as ImageData,
18
+ }
19
+
20
+ /**
21
+ * Retrieves a PixelData instance of the requested dimensions.
22
+ * If the requested dimensions differ from the cached instance, a new one is allocated.
23
+ * @param width - The desired width in pixels.
24
+ * @param height - The desired height in pixels.
25
+ * @returns The cached PixelData object.
26
+ */
27
+ return function getReusablePixelData(width: number, height: number): PixelData {
28
+ if (pixelData.w !== width || pixelData.h !== height) {
29
+ setPixelData(pixelData, new ImageData(width, height))
30
+ } else {
31
+ pixelData.data.fill(0)
32
+ }
33
+
34
+ return pixelData
35
+ }
36
+ }
@@ -0,0 +1,17 @@
1
+ import type { ImageDataLike } from '../ImageData/_ImageData-types'
2
+
3
+ export interface PixelData32 {
4
+ readonly data: Uint32Array
5
+ readonly w: number
6
+ readonly h: number
7
+ }
8
+
9
+ export interface MutablePixelData32 {
10
+ data: Uint32Array
11
+ w: number
12
+ h: number
13
+ }
14
+
15
+ export interface PixelData<T extends ImageDataLike = ImageData> extends PixelData32 {
16
+ readonly imageData: T
17
+ }
@@ -1,4 +1,6 @@
1
- import { type AlphaMask, type ApplyMaskToPixelDataOptions, type Color32, type IPixelData32 } from '../_types'
1
+ import { type ApplyMaskToPixelDataOptions } from '../_types'
2
+ import type { AlphaMask } from '../Mask/_mask-types'
3
+ import type { PixelData32 } from './_pixelData-types'
2
4
 
3
5
  /**
4
6
  * Directly applies a mask to a region of PixelData,
@@ -6,14 +8,14 @@ import { type AlphaMask, type ApplyMaskToPixelDataOptions, type Color32, type IP
6
8
  * @returns true if any pixels were actually modified.
7
9
  */
8
10
  export function applyAlphaMaskToPixelData(
9
- target: IPixelData32,
11
+ target: PixelData32,
10
12
  mask: AlphaMask,
11
13
  opts?: ApplyMaskToPixelDataOptions,
12
14
  ): boolean {
13
15
  const targetX = opts?.x ?? 0
14
16
  const targetY = opts?.y ?? 0
15
- const width = opts?.w ?? target.width
16
- const height = opts?.h ?? target.height
17
+ const width = opts?.w ?? target.w
18
+ const height = opts?.h ?? target.h
17
19
  const globalAlpha = opts?.alpha ?? 255
18
20
  const mx = opts?.mx ?? 0
19
21
  const my = opts?.my ?? 0
@@ -37,8 +39,8 @@ export function applyAlphaMaskToPixelData(
37
39
  y = 0
38
40
  }
39
41
 
40
- w = Math.min(w, target.width - x)
41
- h = Math.min(h, target.height - y)
42
+ w = Math.min(w, target.w - x)
43
+ h = Math.min(h, target.h - y)
42
44
 
43
45
  if (w <= 0) return false
44
46
  if (h <= 0) return false
@@ -70,8 +72,8 @@ export function applyAlphaMaskToPixelData(
70
72
  const xShift = sX0 - startX
71
73
  const yShift = sY0 - startY
72
74
 
73
- const dst32 = target.data32
74
- const dw = target.width
75
+ const dst32 = target.data
76
+ const dw = target.w
75
77
  const dStride = dw - finalW
76
78
  const mStride = mPitch - finalW
77
79
  const maskData = mask.data
@@ -80,51 +82,86 @@ export function applyAlphaMaskToPixelData(
80
82
  let mIdx = sY0 * mPitch + sX0
81
83
 
82
84
  let didChange = false
83
- for (let iy = 0; iy < h; iy++) {
84
- for (let ix = 0; ix < w; ix++) {
85
- const mVal = maskData[mIdx]
86
- // Unified logic branch inside the hot path
87
- const effectiveM = invertMask ? 255 - mVal : mVal
88
-
89
- let weight = 0
90
-
91
- if (effectiveM === 0) {
92
- weight = 0
93
- } else if (effectiveM === 255) {
94
- weight = globalAlpha
95
- } else if (globalAlpha === 255) {
96
- weight = effectiveM
97
- } else {
98
- weight = (effectiveM * globalAlpha + 128) >> 8
99
- }
100
-
101
- if (weight === 0) {
102
- // Clear alpha channel
103
- dst32[dIdx] = (dst32[dIdx] & 0x00ffffff) >>> 0
104
- didChange = true
105
- } else if (weight !== 255) {
106
- // Merge alpha channel
107
- const d = dst32[dIdx]
108
- const da = d >>> 24
85
+ if (invertMask) {
86
+ for (let iy = 0; iy < finalH; iy++) {
87
+ for (let ix = 0; ix < finalW; ix++) {
88
+ const effectiveM = 255 - maskData[mIdx]
109
89
 
110
- if (da !== 0) {
111
- const finalAlpha = da === 255 ? weight : (da * weight + 128) >> 8
90
+ if (effectiveM === 0) {
91
+ const current = dst32[dIdx]
92
+ const next = (current & 0x00ffffff) >>> 0
112
93
 
113
- const current = dst32[dIdx] as Color32
114
- const next = ((d & 0x00ffffff) | (finalAlpha << 24)) >>> 0
115
94
  if (current !== next) {
116
95
  dst32[dIdx] = next
117
96
  didChange = true
118
97
  }
98
+ } else {
99
+ const t1 = effectiveM * globalAlpha + 128
100
+ const weight = (t1 + (t1 >> 8)) >> 8
101
+
102
+ if (weight < 255) {
103
+ const current = dst32[dIdx]
104
+ const da = current >>> 24
105
+
106
+ if (da !== 0) {
107
+ const t2 = da * weight + 128
108
+ const finalAlpha = (t2 + (t2 >> 8)) >> 8
109
+ const next = ((current & 0x00ffffff) | (finalAlpha << 24)) >>> 0
110
+
111
+ if (current !== next) {
112
+ dst32[dIdx] = next
113
+ didChange = true
114
+ }
115
+ }
116
+ }
119
117
  }
120
- }
121
118
 
122
- dIdx++
123
- mIdx++
119
+ dIdx++
120
+ mIdx++
121
+ }
122
+ dIdx += dStride
123
+ mIdx += mStride
124
124
  }
125
+ } else {
126
+ for (let iy = 0; iy < finalH; iy++) {
127
+ for (let ix = 0; ix < finalW; ix++) {
128
+ const effectiveM = maskData[mIdx]
129
+
130
+ if (effectiveM === 0) {
131
+ const current = dst32[dIdx]
132
+ const next = (current & 0x00ffffff) >>> 0
125
133
 
126
- dIdx += dStride
127
- mIdx += mStride
134
+ if (current !== next) {
135
+ dst32[dIdx] = next
136
+ didChange = true
137
+ }
138
+ } else {
139
+ const t1 = effectiveM * globalAlpha + 128
140
+ const weight = (t1 + (t1 >> 8)) >> 8
141
+
142
+ if (weight < 255) {
143
+ const current = dst32[dIdx]
144
+ const da = current >>> 24
145
+
146
+ if (da !== 0) {
147
+ const t2 = da * weight + 128
148
+ const finalAlpha = (t2 + (t2 >> 8)) >> 8
149
+ const next = ((current & 0x00ffffff) | (finalAlpha << 24)) >>> 0
150
+
151
+ if (current !== next) {
152
+ dst32[dIdx] = next
153
+ didChange = true
154
+ }
155
+ }
156
+ }
157
+ }
158
+
159
+ dIdx++
160
+ mIdx++
161
+ }
162
+ dIdx += dStride
163
+ mIdx += mStride
164
+ }
128
165
  }
129
166
  return didChange
130
167
  }
@@ -1,4 +1,6 @@
1
- import { type ApplyMaskToPixelDataOptions, type BinaryMask, type IPixelData32 } from '../_types'
1
+ import { type ApplyMaskToPixelDataOptions } from '../_types'
2
+ import type { BinaryMask } from '../Mask/_mask-types'
3
+ import type { PixelData32 } from './_pixelData-types'
2
4
 
3
5
  /**
4
6
  * Directly applies a mask to a region of PixelData,
@@ -6,14 +8,14 @@ import { type ApplyMaskToPixelDataOptions, type BinaryMask, type IPixelData32 }
6
8
  * @returns true if any pixels were actually modified.
7
9
  */
8
10
  export function applyBinaryMaskToPixelData(
9
- target: IPixelData32,
11
+ target: PixelData32,
10
12
  mask: BinaryMask,
11
13
  opts?: ApplyMaskToPixelDataOptions,
12
14
  ): boolean {
13
15
  const targetX = opts?.x ?? 0
14
16
  const targetY = opts?.y ?? 0
15
- const width = opts?.w ?? target.width
16
- const height = opts?.h ?? target.height
17
+ const width = opts?.w ?? target.w
18
+ const height = opts?.h ?? target.h
17
19
  const globalAlpha = opts?.alpha ?? 255
18
20
  const mx = opts?.mx ?? 0
19
21
  const my = opts?.my ?? 0
@@ -36,8 +38,8 @@ export function applyBinaryMaskToPixelData(
36
38
  y = 0
37
39
  }
38
40
 
39
- w = Math.min(w, target.width - x)
40
- h = Math.min(h, target.height - y)
41
+ w = Math.min(w, target.w - x)
42
+ h = Math.min(h, target.h - y)
41
43
 
42
44
  if (w <= 0 || h <= 0) return false
43
45
 
@@ -67,8 +69,8 @@ export function applyBinaryMaskToPixelData(
67
69
  const xShift = sX0 - startX
68
70
  const yShift = sY0 - startY
69
71
 
70
- const dst32 = target.data32
71
- const dw = target.width
72
+ const dst32 = target.data
73
+ const dw = target.w
72
74
  const dStride = dw - finalW
73
75
  const mStride = mPitch - finalW
74
76
  const maskData = mask.data
@@ -1,16 +1,11 @@
1
- import {
2
- type AlphaMask,
3
- type ApplyMaskToPixelDataOptions,
4
- type BinaryMask,
5
- type IPixelData32,
6
- type Mask,
7
- MaskType,
8
- } from '../_types'
1
+ import { type ApplyMaskToPixelDataOptions } from '../_types'
2
+ import { type AlphaMask, type BinaryMask, type Mask, MaskType } from '../Mask/_mask-types'
3
+ import type { PixelData32 } from './_pixelData-types'
9
4
  import { applyAlphaMaskToPixelData } from './applyAlphaMaskToPixelData'
10
5
  import { applyBinaryMaskToPixelData } from './applyBinaryMaskToPixelData'
11
6
 
12
7
  export function applyMaskToPixelData(
13
- dst: IPixelData32,
8
+ dst: PixelData32,
14
9
  mask: Mask,
15
10
  opts?: ApplyMaskToPixelDataOptions,
16
11
  ): boolean {
@@ -1,19 +1,20 @@
1
- import { type Color32, type ColorBlendOptions, type IPixelData32 } from '../_types'
1
+ import { type Color32, type ColorBlendOptions } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
+ import type { PixelData32 } from './_pixelData-types'
3
4
 
4
5
  /**
5
6
  * Blends a solid color into a target pixel buffer.
6
7
  * @returns true if any pixels were actually modified.
7
8
  */
8
9
  export function blendColorPixelData(
9
- target: IPixelData32,
10
+ target: PixelData32,
10
11
  color: Color32,
11
12
  opts?: ColorBlendOptions,
12
13
  ): boolean {
13
14
  const targetX = opts?.x ?? 0
14
15
  const targetY = opts?.y ?? 0
15
- const width = opts?.w ?? target.width
16
- const height = opts?.h ?? target.height
16
+ const width = opts?.w ?? target.w
17
+ const height = opts?.h ?? target.h
17
18
  const globalAlpha = opts?.alpha ?? 255
18
19
  const blendFn = opts?.blendFn ?? sourceOverPerfect
19
20
  if (globalAlpha === 0) return false
@@ -39,8 +40,8 @@ export function blendColorPixelData(
39
40
  y = 0
40
41
  }
41
42
 
42
- const actualW = Math.min(w, target.width - x)
43
- const actualH = Math.min(h, target.height - y)
43
+ const actualW = Math.min(w, target.w - x)
44
+ const actualH = Math.min(h, target.h - y)
44
45
 
45
46
  if (actualW <= 0 || actualH <= 0) return false
46
47
 
@@ -53,8 +54,8 @@ export function blendColorPixelData(
53
54
  finalSrcColor = ((color & 0x00ffffff) | (a << 24)) >>> 0 as Color32
54
55
  }
55
56
 
56
- const dst32 = target.data32
57
- const dw = target.width
57
+ const dst32 = target.data
58
+ const dw = target.w
58
59
  let dIdx = (y * dw + x) | 0
59
60
  const dStride = (dw - actualW) | 0
60
61
  let didChange = false
@@ -1,5 +1,7 @@
1
- import type { AlphaMask, Color32, ColorBlendMaskOptions, IPixelData32 } from '../_types'
1
+ import type { Color32, ColorBlendMaskOptions } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
+ import type { AlphaMask } from '../Mask/_mask-types'
4
+ import type { PixelData32 } from './_pixelData-types'
3
5
 
4
6
  /**
5
7
  * Blends a solid color into a target pixel buffer using an alpha mask.
@@ -8,14 +10,14 @@ import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
8
10
  * If the width (`w`) or height (`h`) are omitted from the options, they will safely
9
11
  * default to the dimensions of the provided mask to prevent out-of-bounds memory access.
10
12
  *
11
- * @param target - The destination {@link IPixelData32} buffer to modify.
13
+ * @param target - The destination {@link PixelData32} buffer to modify.
12
14
  * @param color - The solid color to apply.
13
15
  * @param mask - The mask defining the per-pixel opacity of the target area.
14
16
  * @param opts - Configuration options including placement coordinates, bounds, global alpha, and mask offsets.
15
17
  * @returns true if any pixels were actually modified.
16
18
  */
17
19
  export function blendColorPixelDataAlphaMask(
18
- target: IPixelData32,
20
+ target: PixelData32,
19
21
  color: Color32,
20
22
  mask: AlphaMask,
21
23
  opts?: ColorBlendMaskOptions,
@@ -52,16 +54,16 @@ export function blendColorPixelDataAlphaMask(
52
54
  y = 0
53
55
  }
54
56
 
55
- actualW = Math.min(actualW, target.width - x)
56
- actualH = Math.min(actualH, target.height - y)
57
+ actualW = Math.min(actualW, target.w - x)
58
+ actualH = Math.min(actualH, target.h - y)
57
59
 
58
60
  if (actualW <= 0 || actualH <= 0) return false
59
61
 
60
62
  const dx = (x - targetX) | 0
61
63
  const dy = (y - targetY) | 0
62
64
 
63
- const dst32 = target.data32
64
- const dw = target.width
65
+ const dst32 = target.data
66
+ const dw = target.w
65
67
  const mPitch = mask.w
66
68
  const maskData = mask.data
67
69
 
@@ -1,5 +1,7 @@
1
- import type { BinaryMask, Color32, ColorBlendMaskOptions, IPixelData32 } from '../_types'
1
+ import type { Color32, ColorBlendMaskOptions } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
+ import type { BinaryMask } from '../Mask/_mask-types'
4
+ import type { PixelData32 } from './_pixelData-types'
3
5
 
4
6
  /**
5
7
  * Blends a solid color into a target pixel buffer using a binary mask.
@@ -8,14 +10,14 @@ import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
8
10
  * If the width (`w`) or height (`h`) are omitted from the options, they will safely
9
11
  * default to the dimensions of the provided mask to prevent out-of-bounds memory access.
10
12
  *
11
- * @param target - The destination {@link IPixelData32} buffer to modify.
13
+ * @param target - The destination {@link PixelData32} buffer to modify.
12
14
  * @param color - The solid color to apply.
13
15
  * @param mask - The mask defining the per-pixel opacity of the target area.
14
16
  * @param opts - Configuration options including placement coordinates, bounds, global alpha, and mask offsets.
15
17
  * @returns true if any pixels were actually modified.
16
18
  */
17
19
  export function blendColorPixelDataBinaryMask(
18
- target: IPixelData32,
20
+ target: PixelData32,
19
21
  color: Color32,
20
22
  mask: BinaryMask,
21
23
  opts?: ColorBlendMaskOptions,
@@ -50,8 +52,8 @@ export function blendColorPixelDataBinaryMask(
50
52
  y = 0
51
53
  }
52
54
 
53
- const actualW = Math.min(w, target.width - x)
54
- const actualH = Math.min(h, target.height - y)
55
+ const actualW = Math.min(w, target.w - x)
56
+ const actualH = Math.min(h, target.h - y)
55
57
 
56
58
  if (actualW <= 0 || actualH <= 0) return false
57
59
 
@@ -65,8 +67,8 @@ export function blendColorPixelDataBinaryMask(
65
67
 
66
68
  const dx = (x - targetX) | 0
67
69
  const dy = (y - targetY) | 0
68
- const dst32 = target.data32
69
- const dw = target.width
70
+ const dst32 = target.data
71
+ const dw = target.w
70
72
  const mPitch = mask.w
71
73
  const maskData = mask.data
72
74
  let dIdx = (y * dw + x) | 0
@@ -1,9 +1,11 @@
1
- import { type Color32, type ColorBlendMaskOptions, type IPixelData32, type Mask, MaskType } from '../_types'
1
+ import { type Color32, type ColorBlendMaskOptions } from '../_types'
2
+ import { type Mask, MaskType } from '../Mask/_mask-types'
3
+ import type { PixelData32 } from './_pixelData-types'
2
4
  import { blendColorPixelDataAlphaMask } from './blendColorPixelDataAlphaMask'
3
5
  import { blendColorPixelDataBinaryMask } from './blendColorPixelDataBinaryMask'
4
6
 
5
7
  export function blendColorPixelDataMask(
6
- dst: IPixelData32,
8
+ dst: PixelData32,
7
9
  color: Color32,
8
10
  mask: Mask,
9
11
  opts?: ColorBlendMaskOptions,
@@ -1,5 +1,7 @@
1
- import { type Color32, type IPixelData32, type PaintAlphaMask } from '../_types'
1
+ import { type Color32 } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
+ import type { PaintAlphaMask } from '../Paint/_paint-types'
4
+ import type { PixelData32 } from './_pixelData-types'
3
5
  import { blendColorPixelDataAlphaMask } from './blendColorPixelDataAlphaMask'
4
6
 
5
7
  const SCRATCH_OPTS = {
@@ -10,7 +12,7 @@ const SCRATCH_OPTS = {
10
12
  }
11
13
 
12
14
  export function blendColorPixelDataPaintAlphaMask(
13
- dst: IPixelData32,
15
+ dst: PixelData32,
14
16
  color: Color32,
15
17
  mask: PaintAlphaMask,
16
18
  x: number,
@@ -1,5 +1,7 @@
1
- import { type Color32, type IPixelData32, type PaintBinaryMask } from '../_types'
1
+ import { type Color32 } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
+ import type { PaintBinaryMask } from '../Paint/_paint-types'
4
+ import type { PixelData32 } from './_pixelData-types'
3
5
  import { blendColorPixelDataBinaryMask } from './blendColorPixelDataBinaryMask'
4
6
 
5
7
  const SCRATCH_OPTS = {
@@ -10,7 +12,7 @@ const SCRATCH_OPTS = {
10
12
  }
11
13
 
12
14
  export function blendColorPixelDataPaintBinaryMask(
13
- dst: IPixelData32,
15
+ dst: PixelData32,
14
16
  color: Color32,
15
17
  mask: PaintBinaryMask,
16
18
  x: number,
@@ -1,5 +1,8 @@
1
- import { type Color32, type IPixelData32, MaskType, type PaintMask } from '../_types'
1
+ import { type Color32 } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
+ import { MaskType } from '../Mask/_mask-types'
4
+ import type { PaintMask } from '../Paint/_paint-types'
5
+ import type { PixelData32 } from './_pixelData-types'
3
6
  import { blendColorPixelDataAlphaMask } from './blendColorPixelDataAlphaMask'
4
7
  import { blendColorPixelDataBinaryMask } from './blendColorPixelDataBinaryMask'
5
8
 
@@ -11,7 +14,7 @@ const SCRATCH_OPTS = {
11
14
  }
12
15
 
13
16
  export function blendColorPixelDataPaintMask(
14
- dst: IPixelData32,
17
+ dst: PixelData32,
15
18
  color: Color32,
16
19
  mask: PaintMask,
17
20
  x: number,
@@ -1,8 +1,9 @@
1
- import type { BlendColor32, Color32, IPixelData32 } from '../_types'
1
+ import type { BlendColor32, Color32 } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
+ import type { PixelData32 } from './_pixelData-types'
3
4
 
4
5
  export function blendPixel(
5
- target: IPixelData32,
6
+ target: PixelData32,
6
7
  x: number,
7
8
  y: number,
8
9
  color: Color32,
@@ -11,8 +12,8 @@ export function blendPixel(
11
12
  ): boolean {
12
13
  if (alpha === 0) return false
13
14
 
14
- let width = target.width
15
- let height = target.height
15
+ let width = target.w
16
+ let height = target.h
16
17
 
17
18
  if (x < 0 || x >= width || y < 0 || y >= height) return false
18
19
 
@@ -22,7 +23,7 @@ export function blendPixel(
22
23
  // Early exit for transparent source unless we are in an overwrite mode
23
24
  if (srcAlpha === 0 && !isOverwrite) return false
24
25
 
25
- let dst32 = target.data32
26
+ let dst32 = target.data
26
27
  let index = y * width + x
27
28
  let finalColor = color
28
29
 
@@ -1,5 +1,6 @@
1
- import { type Color32, type IPixelData32, type PixelBlendOptions } from '../_types'
1
+ import { type Color32, type PixelBlendOptions } from '../_types'
2
2
  import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
3
+ import type { PixelData32 } from './_pixelData-types'
3
4
 
4
5
  /**
5
6
  * Blits source PixelData into a destination PixelData using 32-bit integer bitwise blending.
@@ -16,16 +17,16 @@ import { sourceOverPerfect } from '../BlendModes/blend-modes-perfect'
16
17
  * });
17
18
  */
18
19
  export function blendPixelData(
19
- target: IPixelData32,
20
- src: IPixelData32,
20
+ target: PixelData32,
21
+ src: PixelData32,
21
22
  opts?: PixelBlendOptions,
22
23
  ): boolean {
23
24
  const targetX = opts?.x ?? 0
24
25
  const targetY = opts?.y ?? 0
25
26
  const sourceX = opts?.sx ?? 0
26
27
  const sourceY = opts?.sy ?? 0
27
- const width = opts?.w ?? src.width
28
- const height = opts?.h ?? src.height
28
+ const width = opts?.w ?? src.w
29
+ const height = opts?.h ?? src.h
29
30
  const globalAlpha = opts?.alpha ?? 255
30
31
  const blendFn = opts?.blendFn ?? sourceOverPerfect
31
32
 
@@ -48,8 +49,8 @@ export function blendPixelData(
48
49
  h += sy
49
50
  sy = 0
50
51
  }
51
- w = Math.min(w, src.width - sx)
52
- h = Math.min(h, src.height - sy)
52
+ w = Math.min(w, src.w - sx)
53
+ h = Math.min(h, src.h - sy)
53
54
  if (x < 0) {
54
55
  sx -= x
55
56
  w += x
@@ -61,14 +62,14 @@ export function blendPixelData(
61
62
  y = 0
62
63
  }
63
64
 
64
- const actualW = Math.min(w, target.width - x)
65
- const actualH = Math.min(h, target.height - y)
65
+ const actualW = Math.min(w, target.w - x)
66
+ const actualH = Math.min(h, target.h - y)
66
67
  if (actualW <= 0 || actualH <= 0) return false
67
68
 
68
- const dst32 = target.data32
69
- const src32 = src.data32
70
- const dw = target.width
71
- const sw = src.width
69
+ const dst32 = target.data
70
+ const src32 = src.data
71
+ const dw = target.w
72
+ const sw = src.w
72
73
 
73
74
  let dIdx = (y * dw + x) | 0
74
75
  let sIdx = (sy * sw + sx) | 0