pixel-data-js 0.15.1 → 0.17.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 (36) hide show
  1. package/dist/index.dev.cjs +1884 -1203
  2. package/dist/index.dev.cjs.map +1 -1
  3. package/dist/index.dev.js +1858 -1190
  4. package/dist/index.dev.js.map +1 -1
  5. package/dist/index.prod.cjs +1884 -1203
  6. package/dist/index.prod.cjs.map +1 -1
  7. package/dist/index.prod.d.ts +320 -66
  8. package/dist/index.prod.js +1858 -1190
  9. package/dist/index.prod.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/BlendModes/BlendModeRegistry.ts +62 -0
  12. package/src/BlendModes/blend-modes-fast.ts +31 -84
  13. package/src/BlendModes/blend-modes-perfect.ts +343 -215
  14. package/src/BlendModes/blend-modes.ts +28 -30
  15. package/src/History/HistoryManager.ts +83 -0
  16. package/src/History/PixelAccumulator.ts +191 -0
  17. package/src/History/PixelEngineConfig.ts +18 -0
  18. package/src/History/PixelMutator/mutatorApplyMask.ts +20 -0
  19. package/src/History/PixelMutator/mutatorBlendColor.ts +22 -0
  20. package/src/History/PixelMutator/mutatorBlendPixel.ts +37 -0
  21. package/src/History/PixelMutator/mutatorBlendPixelData.ts +24 -0
  22. package/src/History/PixelMutator/mutatorFillPixelData.ts +21 -0
  23. package/src/History/PixelMutator/mutatorInvert.ts +18 -0
  24. package/src/History/PixelMutator.ts +18 -0
  25. package/src/History/PixelPatchTiles.ts +52 -0
  26. package/src/History/PixelWriter.ts +79 -0
  27. package/src/ImageData/{writeImageDataPixels.ts → writeImageDataBuffer.ts} +3 -3
  28. package/src/PixelData/applyCircleBrushToPixelData.ts +69 -0
  29. package/src/PixelData/applyMaskToPixelData.ts +1 -1
  30. package/src/PixelData/applyRectBrushToPixelData.ts +102 -0
  31. package/src/PixelData/blendPixelData.ts +2 -3
  32. package/src/PixelData/invertPixelData.ts +74 -7
  33. package/src/PixelData/writePixelDataBuffer.ts +65 -0
  34. package/src/_types.ts +31 -11
  35. package/src/index.ts +20 -10
  36. package/src/BlendModes/blend-mode-getters.ts +0 -14
@@ -1,38 +1,36 @@
1
- // The enum index IS the permanent ID.
2
- // do not change the order, Adding to it is ok.
3
1
  import type { BlendColor32 } from '../_types'
4
2
 
5
- export enum BlendMode {
6
- overwrite,
7
- sourceOver,
3
+ export const BaseBlendMode = {
4
+ overwrite: 0,
5
+ sourceOver: 1,
6
+ darken: 2,
7
+ multiply: 3,
8
+ colorBurn: 4,
9
+ linearBurn: 5,
10
+ darkerColor: 6,
11
+ lighten: 7,
12
+ screen: 8,
13
+ colorDodge: 9,
14
+ linearDodge: 10,
15
+ lighterColor: 11,
16
+ overlay: 12,
17
+ softLight: 13,
18
+ hardLight: 14,
19
+ vividLight: 15,
20
+ linearLight: 16,
21
+ pinLight: 17,
22
+ hardMix: 18,
23
+ difference: 19,
24
+ exclusion: 20,
25
+ subtract: 21,
26
+ divide: 22,
27
+ } as const
8
28
 
9
- darken,
10
- multiply,
11
- colorBurn,
12
- linearBurn,
13
- darkerColor,
14
-
15
- lighten,
16
- screen,
17
- colorDodge,
18
- linearDodge,
19
- lighterColor,
20
-
21
- overlay,
22
- softLight,
23
- hardLight,
24
- vividLight,
25
- linearLight,
26
- pinLight,
27
- hardMix,
28
-
29
- difference,
30
- exclusion,
31
- subtract,
32
- divide,
29
+ export interface RequiredBlendModes {
30
+ overwrite: 0;
33
31
  }
34
32
 
35
- export type BlendModeIndex = typeof BlendMode[keyof typeof BlendMode];
33
+ export type BaseBlendModes = RequiredBlendModes & Record<string, number>
36
34
 
37
35
  export const overwriteBase: BlendColor32 = (src, _dst) => src
38
36
  overwriteBase.isOverwrite = true
@@ -0,0 +1,83 @@
1
+ export interface HistoryAction {
2
+ undo: () => void
3
+ redo: () => void
4
+ dispose?: () => void
5
+ }
6
+
7
+ export class HistoryManager {
8
+ public undoStack: HistoryAction[]
9
+ public redoStack: HistoryAction[]
10
+ public listeners: Set<() => void>
11
+
12
+ constructor(
13
+ public maxSteps = 50,
14
+ ) {
15
+ this.undoStack = []
16
+ this.redoStack = []
17
+ this.listeners = new Set()
18
+ }
19
+
20
+ get canUndo() {
21
+ return this.undoStack.length > 0
22
+ }
23
+
24
+ get canRedo() {
25
+ return this.redoStack.length > 0
26
+ }
27
+
28
+ subscribe(fn: () => void) {
29
+ this.listeners.add(fn)
30
+ return () => this.listeners.delete(fn)
31
+ }
32
+
33
+ notify() {
34
+ this.listeners.forEach((fn) => fn())
35
+ }
36
+
37
+ commit(action: HistoryAction) {
38
+ this.undoStack.push(action)
39
+ this.clearRedoStack()
40
+
41
+ if (this.undoStack.length > this.maxSteps) {
42
+ this.undoStack.shift()?.dispose?.()
43
+ }
44
+
45
+ this.notify()
46
+ }
47
+
48
+ undo() {
49
+ let action = this.undoStack.pop()
50
+
51
+ if (!action) return
52
+
53
+ this.redoStack.push(action)
54
+ action.undo()
55
+
56
+ this.notify()
57
+ }
58
+
59
+ redo() {
60
+ let action = this.redoStack.pop()
61
+
62
+ if (!action) return
63
+
64
+ this.undoStack.push(action)
65
+ action.redo()
66
+
67
+ this.notify()
68
+ }
69
+
70
+ clearRedoStack() {
71
+ let length = this.redoStack.length
72
+
73
+ for (let i = 0; i < length; i++) {
74
+ let action = this.redoStack[i]
75
+
76
+ if (action) {
77
+ action.dispose?.()
78
+ }
79
+ }
80
+
81
+ this.redoStack.length = 0
82
+ }
83
+ }
@@ -0,0 +1,191 @@
1
+ import type { PixelData } from '../PixelData/PixelData'
2
+ import type { PixelEngineConfig } from './PixelEngineConfig'
3
+ import { type PixelPatchTiles, PixelTile } from './PixelPatchTiles'
4
+
5
+ export class PixelAccumulator {
6
+ public lookup: (PixelTile | undefined)[]
7
+ public beforeTiles: PixelTile[]
8
+ public pool: PixelTile[]
9
+
10
+ constructor(
11
+ public target: PixelData,
12
+ readonly config: PixelEngineConfig,
13
+ ) {
14
+ this.lookup = []
15
+ this.beforeTiles = []
16
+ this.pool = []
17
+ }
18
+
19
+ getTile(
20
+ id: number,
21
+ tx: number,
22
+ ty: number,
23
+ ): PixelTile {
24
+ let tile = this.pool.pop()
25
+
26
+ if (tile) {
27
+ tile.id = id
28
+ tile.tx = tx
29
+ tile.ty = ty
30
+
31
+ return tile
32
+ }
33
+
34
+ return new PixelTile(
35
+ id,
36
+ tx,
37
+ ty,
38
+ this.config.tileArea,
39
+ )
40
+ }
41
+
42
+ recyclePatch(patch: PixelPatchTiles) {
43
+ const before = patch.beforeTiles
44
+
45
+ for (let i = 0; i < before.length; i++) {
46
+ let tile = before[i]
47
+
48
+ if (tile) {
49
+ this.pool.push(tile)
50
+ }
51
+ }
52
+
53
+ const after = patch.afterTiles
54
+
55
+ for (let i = 0; i < after.length; i++) {
56
+ let tile = after[i]
57
+
58
+ if (tile) {
59
+ this.pool.push(tile)
60
+ }
61
+ }
62
+ }
63
+
64
+ /**
65
+ * @param x pixel x coordinate
66
+ * @param y pixel y coordinate
67
+ */
68
+ storeTileBeforeState(x: number, y: number): void {
69
+ let target = this.target
70
+ let shift = this.config.tileShift
71
+ let columns = (target.width + this.config.tileMask) >> shift
72
+ let tx = x >> shift
73
+ let ty = y >> shift
74
+ let id = ty * columns + tx
75
+
76
+ let tile = this.lookup[id]
77
+
78
+ if (!tile) {
79
+ tile = this.getTile(
80
+ id,
81
+ tx,
82
+ ty,
83
+ )
84
+
85
+ this.extractState(tile)
86
+ this.lookup[id] = tile
87
+ this.beforeTiles.push(tile)
88
+ }
89
+ }
90
+
91
+ /**
92
+ *
93
+ * @param x pixel x coordinate
94
+ * @param y pixel y coordinate
95
+ * @param w pixel width
96
+ * @param h pixel height
97
+ */
98
+ storeRegionBeforeState(
99
+ x: number,
100
+ y: number,
101
+ w: number,
102
+ h: number,
103
+ ) {
104
+ let target = this.target
105
+ let shift = this.config.tileShift
106
+ let columns = (target.width + this.config.tileMask) >> shift
107
+
108
+ let startX = x >> shift
109
+ let startY = y >> shift
110
+ let endX = (x + w - 1) >> shift
111
+ let endY = (y + h - 1) >> shift
112
+
113
+ for (let ty = startY; ty <= endY; ty++) {
114
+ for (let tx = startX; tx <= endX; tx++) {
115
+ let id = ty * columns + tx
116
+ let tile = this.lookup[id]
117
+
118
+ if (!tile) {
119
+ tile = this.getTile(
120
+ id,
121
+ tx,
122
+ ty,
123
+ )
124
+
125
+ this.extractState(tile)
126
+ this.lookup[id] = tile
127
+ this.beforeTiles.push(tile)
128
+ }
129
+ }
130
+ }
131
+ }
132
+
133
+ extractState(tile: PixelTile) {
134
+ let target = this.target
135
+ let TILE_SIZE = this.config.tileSize
136
+ let dst = tile.data32
137
+ let src = target.data32
138
+ let startX = tile.tx * TILE_SIZE
139
+ let startY = tile.ty * TILE_SIZE
140
+ let targetWidth = target.width
141
+ let targetHeight = target.height
142
+
143
+ let copyWidth = Math.max(0, Math.min(TILE_SIZE, targetWidth - startX))
144
+
145
+ for (let ly = 0; ly < TILE_SIZE; ly++) {
146
+ let globalY = startY + ly
147
+ let dstIndex = ly * TILE_SIZE
148
+
149
+ if (globalY < 0 || globalY >= targetHeight || copyWidth === 0) {
150
+ dst.fill(0, dstIndex, dstIndex + TILE_SIZE)
151
+ continue
152
+ }
153
+
154
+ let srcIndex = globalY * targetWidth + startX
155
+ let rowData = src.subarray(srcIndex, srcIndex + copyWidth)
156
+
157
+ dst.set(rowData, dstIndex)
158
+
159
+ if (copyWidth < TILE_SIZE) {
160
+ dst.fill(0, dstIndex + copyWidth, dstIndex + TILE_SIZE)
161
+ }
162
+ }
163
+ }
164
+
165
+ extractAfterTiles(): PixelTile[] {
166
+ let afterTiles: PixelTile[] = []
167
+ let length = this.beforeTiles.length
168
+
169
+ for (let i = 0; i < length; i++) {
170
+ let beforeTile = this.beforeTiles[i]
171
+
172
+ if (beforeTile) {
173
+ let afterTile = this.getTile(
174
+ beforeTile.id,
175
+ beforeTile.tx,
176
+ beforeTile.ty,
177
+ )
178
+
179
+ this.extractState(afterTile)
180
+ afterTiles.push(afterTile)
181
+ }
182
+ }
183
+
184
+ return afterTiles
185
+ }
186
+
187
+ reset() {
188
+ this.lookup = []
189
+ this.beforeTiles = []
190
+ }
191
+ }
@@ -0,0 +1,18 @@
1
+ export class PixelEngineConfig {
2
+ public readonly tileSize: number
3
+ public readonly tileShift: number
4
+ public readonly tileMask: number
5
+ public readonly tileArea: number
6
+
7
+ constructor(tileSize: number = 256) {
8
+ // Ensure it's a power of 2 to guarantee bitwise math works
9
+ if ((tileSize & (tileSize - 1)) !== 0) {
10
+ throw new Error('tileSize must be a power of 2')
11
+ }
12
+
13
+ this.tileSize = tileSize
14
+ this.tileShift = Math.log2(tileSize)
15
+ this.tileMask = tileSize - 1
16
+ this.tileArea = tileSize * tileSize
17
+ }
18
+ }
@@ -0,0 +1,20 @@
1
+ import { type AnyMask, type ApplyMaskOptions } from '../../_types'
2
+ import { applyMaskToPixelData } from '../../PixelData/applyMaskToPixelData'
3
+ import { PixelWriter } from '../PixelWriter'
4
+
5
+ export function mutatorApplyMask(writer: PixelWriter<any>) {
6
+ return {
7
+ applyMask: (mask: AnyMask, opts: ApplyMaskOptions = {}) => {
8
+ let target = writer.target
9
+ const {
10
+ x = 0,
11
+ y = 0,
12
+ w = writer.target.width,
13
+ h = writer.target.height,
14
+ } = opts
15
+
16
+ writer.accumulator.storeRegionBeforeState(x, y, w, h)
17
+ applyMaskToPixelData(target, mask, opts)
18
+ },
19
+ }
20
+ }
@@ -0,0 +1,22 @@
1
+ import type { Color32, ColorBlendOptions } from '../../_types'
2
+ import { blendColorPixelData } from '../../PixelData/blendColorPixelData'
3
+ import { PixelWriter } from '../PixelWriter'
4
+
5
+ export function mutatorBlendColor(writer: PixelWriter<any>) {
6
+ return {
7
+ blendColor(
8
+ color: Color32,
9
+ opts: ColorBlendOptions = {},
10
+ ) {
11
+
12
+ const {
13
+ x = 0,
14
+ y = 0,
15
+ w = writer.target.width,
16
+ h = writer.target.height,
17
+ } = opts
18
+ writer.accumulator.storeRegionBeforeState(x, y, w, h)
19
+ blendColorPixelData(writer.target, color, opts)
20
+ },
21
+ }
22
+ }
@@ -0,0 +1,37 @@
1
+ import type { BlendColor32, Color32 } from '../../_types'
2
+ import { overwriteFast } from '../../BlendModes/blend-modes-fast'
3
+ import { PixelWriter } from '../PixelWriter'
4
+
5
+ export function mutatorBlendPixel(writer: PixelWriter<any>) {
6
+ return {
7
+ blendPixel(
8
+ x: number,
9
+ y: number,
10
+ color: Color32,
11
+ alpha: number = 255,
12
+ blendFn: BlendColor32 = overwriteFast,
13
+ ) {
14
+ let target = writer.target
15
+ let width = target.width
16
+ let height = target.height
17
+
18
+ if (x < 0 || x >= width || y < 0 || y >= height) return
19
+
20
+ writer.accumulator.storeTileBeforeState(x, y)
21
+
22
+ let index = y * width + x
23
+ let bg = target.data32[index] as Color32
24
+
25
+ let finalColor = color
26
+
27
+ if (alpha < 255) {
28
+ let baseSrcAlpha = color >>> 24
29
+ let finalAlpha = (baseSrcAlpha * alpha + 128) >> 8
30
+
31
+ finalColor = (((color & 0x00ffffff) | (finalAlpha << 24)) >>> 0) as Color32
32
+ }
33
+
34
+ target.data32[index] = blendFn(finalColor, bg)
35
+ },
36
+ }
37
+ }
@@ -0,0 +1,24 @@
1
+ import type { PixelBlendOptions } from '../../_types'
2
+ import { blendPixelData } from '../../PixelData/blendPixelData'
3
+ import type { PixelData } from '../../PixelData/PixelData'
4
+ import { PixelWriter } from '../PixelWriter'
5
+
6
+ export function mutatorBlendPixelData(writer: PixelWriter<any>) {
7
+ return {
8
+ blendPixelData(
9
+ src: PixelData,
10
+ opts: PixelBlendOptions,
11
+ ) {
12
+ const {
13
+ x = 0,
14
+ y = 0,
15
+ w = src.width,
16
+ h = src.height,
17
+ } = opts
18
+ writer.accumulator.storeRegionBeforeState(x, y, w, h)
19
+
20
+ blendPixelData(writer.target, src, opts)
21
+ },
22
+ }
23
+ }
24
+
@@ -0,0 +1,21 @@
1
+ import type { Color32, Rect } from '../../_types'
2
+ import { fillPixelData } from '../../PixelData/fillPixelData'
3
+ import { PixelWriter } from '../PixelWriter'
4
+
5
+ export function mutatorFill(writer: PixelWriter<any>) {
6
+ return {
7
+ fill(
8
+ color: Color32,
9
+ rect: Partial<Rect> = {},
10
+ ) {
11
+ const {
12
+ x = 0,
13
+ y = 0,
14
+ w = writer.target.width,
15
+ h = writer.target.height,
16
+ } = rect
17
+ writer.accumulator.storeRegionBeforeState(x, y, w, h)
18
+ fillPixelData(writer.target, color, x, y, w, h)
19
+ },
20
+ }
21
+ }
@@ -0,0 +1,18 @@
1
+ import type { PixelMutateOptions } from '../../_types'
2
+ import { invertPixelData } from '../../PixelData/invertPixelData'
3
+ import { PixelWriter } from '../PixelWriter'
4
+
5
+ export function mutatorInvert(writer: PixelWriter<any>) {
6
+ return {
7
+ invert(opts: PixelMutateOptions = {}) {
8
+ const {
9
+ x = 0,
10
+ y = 0,
11
+ w = writer.target.width,
12
+ h = writer.target.height,
13
+ } = opts
14
+ writer.accumulator.storeRegionBeforeState(x, y, w, h)
15
+ invertPixelData(writer.target, opts)
16
+ },
17
+ }
18
+ }
@@ -0,0 +1,18 @@
1
+ import { mutatorApplyMask } from './PixelMutator/mutatorApplyMask'
2
+ import { mutatorBlendColor } from './PixelMutator/mutatorBlendColor'
3
+ import { mutatorBlendPixel } from './PixelMutator/mutatorBlendPixel'
4
+ import { mutatorBlendPixelData } from './PixelMutator/mutatorBlendPixelData'
5
+ import { mutatorFill } from './PixelMutator/mutatorFillPixelData'
6
+ import { mutatorInvert } from './PixelMutator/mutatorInvert'
7
+ import type { PixelWriter } from './PixelWriter'
8
+
9
+ export function makeFullPixelMutator(writer: PixelWriter<any>) {
10
+ return {
11
+ ...mutatorApplyMask(writer),
12
+ ...mutatorBlendPixelData(writer),
13
+ ...mutatorBlendColor(writer),
14
+ ...mutatorBlendPixel(writer),
15
+ ...mutatorFill(writer),
16
+ ...mutatorInvert(writer),
17
+ }
18
+ }
@@ -0,0 +1,52 @@
1
+ import type { PixelData } from '../PixelData/PixelData'
2
+
3
+ export type PixelPatchTiles = {
4
+ beforeTiles: PixelTile[]
5
+ afterTiles: PixelTile[]
6
+ }
7
+
8
+ export class PixelTile {
9
+ public data32: Uint32Array
10
+
11
+ constructor(
12
+ public id: number,
13
+ public tx: number,
14
+ public ty: number,
15
+ tileArea: number,
16
+ ) {
17
+ this.data32 = new Uint32Array(tileArea)
18
+ }
19
+ }
20
+
21
+ export function applyPatchTiles(target: PixelData, tiles: PixelTile[], tileSize: number = 256) {
22
+ for (let i = 0; i < tiles.length; i++) {
23
+ const tile = tiles[i]
24
+
25
+ if (!tile) continue
26
+
27
+ const dst = target.data32
28
+ const src = tile.data32
29
+ const dstWidth = target.width
30
+ const dstHeight = target.height
31
+ const startX = tile.tx * tileSize
32
+ const startY = tile.ty * tileSize
33
+
34
+ // Calculate clamping to prevent wrapping artifacts on image edges
35
+ const copyWidth = Math.max(0, Math.min(tileSize, dstWidth - startX))
36
+
37
+ if (copyWidth <= 0) return
38
+
39
+ for (let ly = 0; ly < tileSize; ly++) {
40
+ const globalY = startY + ly
41
+
42
+ // Stop if we go below the image
43
+ if (globalY >= dstHeight) break
44
+
45
+ const dstIndex = globalY * dstWidth + startX
46
+ const srcIndex = ly * tileSize
47
+ const rowData = src.subarray(srcIndex, srcIndex + copyWidth)
48
+
49
+ dst.set(rowData, dstIndex)
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,79 @@
1
+ import type { PixelData } from '../PixelData/PixelData'
2
+ import { type HistoryAction, HistoryManager } from './HistoryManager'
3
+ import { PixelAccumulator } from './PixelAccumulator'
4
+ import { PixelEngineConfig } from './PixelEngineConfig'
5
+ import { applyPatchTiles, type PixelPatchTiles } from './PixelPatchTiles'
6
+
7
+ export interface PixelWriterOptions {
8
+ maxHistorySteps?: number
9
+ tileSize?: number
10
+ historyManager?: HistoryManager
11
+ }
12
+
13
+ /**
14
+ * @example
15
+ * const targ = new PixelData(new ImageData(10, 10))
16
+ * const writer = new PixelWriter(targ, (writer) => {
17
+ * return {
18
+ * ...mutatorApplyMask(writer),
19
+ * ...mutatorBlendPixelData(writer),
20
+ * ...mutatorBlendColor(writer),
21
+ * ...mutatorBlendPixel(writer),
22
+ * ...mutatorFill(writer),
23
+ * }
24
+ * })
25
+ *
26
+ * // to import all mutator functions
27
+ * const writer = new PixelWriter(targ, makeFullPixelMutator)
28
+ *
29
+ * writer.withHistory((mutator) => {
30
+ * mutator.applyMask()
31
+ * mutator.blendPixelData()
32
+ * })
33
+ */
34
+ export class PixelWriter<M> {
35
+ public target: PixelData
36
+ public historyManager: HistoryManager
37
+ public accumulator: PixelAccumulator
38
+ protected config: PixelEngineConfig
39
+ private mutator: M
40
+
41
+ constructor(target: PixelData, mutatorFactory: (writer: PixelWriter<any>) => M, {
42
+ tileSize = 256,
43
+ maxHistorySteps = 50,
44
+ historyManager = new HistoryManager(maxHistorySteps),
45
+ }: PixelWriterOptions = {}) {
46
+ this.target = target
47
+ this.config = new PixelEngineConfig(tileSize)
48
+ this.historyManager = historyManager
49
+ this.accumulator = new PixelAccumulator(target, this.config)
50
+ this.mutator = mutatorFactory(this)
51
+ }
52
+
53
+ withHistory(cb: (mutator: M) => void) {
54
+ cb(this.mutator)
55
+
56
+ const beforeTiles = this.accumulator.beforeTiles
57
+ if (beforeTiles.length === 0) return
58
+
59
+ const afterTiles = this.accumulator.extractAfterTiles()
60
+
61
+ const patch: PixelPatchTiles = {
62
+ beforeTiles: beforeTiles,
63
+ afterTiles: afterTiles,
64
+ }
65
+
66
+ const target = this.target
67
+ const tileSize = this.config.tileSize
68
+ const accumulator = this.accumulator
69
+
70
+ const action: HistoryAction = {
71
+ undo: () => applyPatchTiles(target, patch.beforeTiles, tileSize),
72
+ redo: () => applyPatchTiles(target, patch.afterTiles, tileSize),
73
+ dispose: () => accumulator.recyclePatch(patch),
74
+ }
75
+
76
+ this.historyManager.commit(action)
77
+ this.accumulator.reset()
78
+ }
79
+ }
@@ -11,7 +11,7 @@ import type { Rect } from '../_types'
11
11
  * @param data - The source pixel data (RGBA).
12
12
  * @param rect - A {@link Rect} object defining the destination region.
13
13
  */
14
- export function writeImageDataPixels(
14
+ export function writeImageDataBuffer(
15
15
  imageData: ImageData,
16
16
  data: Uint8ClampedArray,
17
17
  rect: Rect,
@@ -24,7 +24,7 @@ export function writeImageDataPixels(
24
24
  * @param w - The width of the region to write.
25
25
  * @param h - The height of the region to write.
26
26
  */
27
- export function writeImageDataPixels(
27
+ export function writeImageDataBuffer(
28
28
  imageData: ImageData,
29
29
  data: Uint8ClampedArray,
30
30
  x: number,
@@ -32,7 +32,7 @@ export function writeImageDataPixels(
32
32
  w: number,
33
33
  h: number,
34
34
  ): void
35
- export function writeImageDataPixels(
35
+ export function writeImageDataBuffer(
36
36
  imageData: ImageData,
37
37
  data: Uint8ClampedArray,
38
38
  _x: Rect | number,