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.
- package/README.md +12 -2
- package/dist/index.prod.cjs +2227 -1050
- package/dist/index.prod.cjs.map +1 -1
- package/dist/index.prod.d.ts +549 -424
- package/dist/index.prod.js +2171 -1028
- package/dist/index.prod.js.map +1 -1
- package/package.json +11 -11
- package/src/Algorithm/floodFillSelection.ts +8 -6
- package/src/Algorithm/forEachLinePoint.ts +6 -6
- package/src/{Internal/resample32.ts → Algorithm/resampleUint32Array.ts} +11 -21
- package/src/BlendModes/blend-modes-fast.ts +169 -0
- package/src/BlendModes/blend-modes-perfect.ts +207 -0
- package/src/BlendModes/blend-modes.ts +9 -0
- package/src/Canvas/CanvasFrameRenderer.ts +20 -28
- package/src/Canvas/CanvasPixelDataRenderer.ts +23 -0
- package/src/Canvas/PixelCanvas.ts +2 -7
- package/src/Canvas/ReusableCanvas.ts +4 -12
- package/src/Canvas/_canvas-types.ts +26 -0
- package/src/History/PixelAccumulator.ts +17 -17
- package/src/History/PixelEngineConfig.ts +3 -3
- package/src/History/PixelMutator/mutatorApplyAlphaMask.ts +4 -3
- package/src/History/PixelMutator/mutatorApplyBinaryMask.ts +4 -3
- package/src/History/PixelMutator/mutatorApplyMask.ts +4 -3
- package/src/History/PixelMutator/mutatorBlendAlphaMask.ts +6 -4
- package/src/History/PixelMutator/mutatorBlendBinaryMask.ts +6 -4
- package/src/History/PixelMutator/mutatorBlendColor.ts +2 -2
- package/src/History/PixelMutator/mutatorBlendColorPaintAlphaMask.ts +2 -1
- package/src/History/PixelMutator/mutatorBlendColorPaintBinaryMask.ts +2 -1
- package/src/History/PixelMutator/mutatorBlendColorPaintMask.ts +3 -1
- package/src/History/PixelMutator/{mutatorBlendPaintRect.ts → mutatorBlendColorPaintRect.ts} +5 -5
- package/src/History/PixelMutator/mutatorBlendMask.ts +6 -4
- package/src/History/PixelMutator/mutatorBlendPixelData.ts +5 -4
- package/src/History/PixelMutator/mutatorClear.ts +4 -3
- package/src/History/PixelMutator/mutatorFill.ts +5 -4
- package/src/History/PixelMutator/mutatorFillBinaryMask.ts +2 -1
- package/src/History/PixelMutator/mutatorInvert.ts +2 -2
- package/src/History/PixelMutator.ts +2 -2
- package/src/History/PixelPatchTiles.ts +7 -7
- package/src/History/PixelWriter.ts +12 -63
- package/src/ImageData/ImageDataLike.ts +1 -1
- package/src/ImageData/_ImageData-types.ts +13 -0
- package/src/ImageData/copyImageData.ts +1 -1
- package/src/ImageData/extractImageDataBuffer.ts +3 -2
- package/src/ImageData/imageDataToUint32Array.ts +18 -0
- package/src/ImageData/resampleImageData.ts +3 -3
- package/src/ImageData/resizeImageData.ts +1 -1
- package/src/ImageData/serialization.ts +1 -1
- package/src/ImageData/uInt32ArrayToImageData.ts +1 -1
- package/src/ImageData/writeImageData.ts +2 -2
- package/src/ImageData/writeImageDataBuffer.ts +2 -2
- package/src/IndexedImage/IndexedImage.ts +56 -98
- package/src/IndexedImage/_indexedImage-types.ts +18 -0
- package/src/IndexedImage/getIndexedImageColorCounts.ts +3 -3
- package/src/IndexedImage/indexedImageToAverageColor.ts +1 -1
- package/src/IndexedImage/indexedImageToImageData.ts +4 -6
- package/src/IndexedImage/resampleIndexedImage.ts +7 -15
- package/src/Input/fileToImageData.ts +1 -1
- package/src/Internal/_errors.ts +2 -0
- package/src/Internal/macros.ts +14 -0
- package/src/Mask/AlphaMask.ts +1 -1
- package/src/Mask/BinaryMask/makeBinaryMaskFromAlphaMask.ts +23 -0
- package/src/Mask/BinaryMask/makeBinaryMaskOutline.ts +88 -0
- package/src/Mask/BinaryMask/makeCircleBinaryMaskOutline.ts +104 -0
- package/src/Mask/BinaryMask/makeRectBinaryMaskOutline.ts +34 -0
- package/src/Mask/BinaryMask.ts +1 -1
- package/src/Mask/_mask-types.ts +73 -0
- package/src/Mask/applyBinaryMaskToAlphaMask.ts +2 -1
- package/src/Mask/copyMask.ts +1 -1
- package/src/Mask/extractMask.ts +2 -1
- package/src/Mask/extractMaskBuffer.ts +1 -1
- package/src/Mask/mergeAlphaMasks.ts +6 -3
- package/src/Mask/mergeBinaryMasks.ts +2 -1
- package/src/Mask/setMaskData.ts +1 -1
- package/src/MaskRect/merge2BinaryMaskRects.ts +2 -2
- package/src/MaskRect/mergeBinaryMaskRects.ts +1 -1
- package/src/MaskRect/subtractBinaryMaskRects.ts +1 -1
- package/src/Paint/AlphaMaskPaintBuffer.ts +339 -0
- package/src/Paint/AlphaMaskPaintBufferCanvasRenderer.ts +78 -0
- package/src/Paint/BinaryMaskPaintBuffer.ts +254 -0
- package/src/Paint/BinaryMaskPaintBufferCanvasRenderer.ts +67 -0
- package/src/Paint/{PaintBuffer.ts → ColorPaintBuffer.ts} +148 -77
- package/src/Paint/{PaintBufferCanvasRenderer.ts → ColorPaintBufferCanvasRenderer.ts} +6 -5
- package/src/Paint/PaintCursorRenderer.ts +117 -0
- package/src/Paint/_paint-types.ts +22 -0
- package/src/Paint/eachTileInBounds.ts +45 -0
- package/src/Paint/makeCirclePaintMask.ts +74 -0
- package/src/Paint/makePaintMask.ts +5 -2
- package/src/Paint/makeRectFalloffPaintAlphaMask.ts +4 -2
- package/src/PixelData/PixelData.ts +15 -19
- package/src/PixelData/ReusablePixelData.ts +36 -0
- package/src/PixelData/_pixelData-types.ts +17 -0
- package/src/PixelData/applyAlphaMaskToPixelData.ts +80 -43
- package/src/PixelData/applyBinaryMaskToPixelData.ts +10 -8
- package/src/PixelData/applyMaskToPixelData.ts +4 -9
- package/src/PixelData/blendColorPixelData.ts +9 -8
- package/src/PixelData/blendColorPixelDataAlphaMask.ts +9 -7
- package/src/PixelData/blendColorPixelDataBinaryMask.ts +9 -7
- package/src/PixelData/blendColorPixelDataMask.ts +4 -2
- package/src/PixelData/blendColorPixelDataPaintAlphaMask.ts +4 -2
- package/src/PixelData/blendColorPixelDataPaintBinaryMask.ts +4 -2
- package/src/PixelData/blendColorPixelDataPaintMask.ts +5 -2
- package/src/PixelData/blendPixel.ts +6 -5
- package/src/PixelData/blendPixelData.ts +14 -13
- package/src/PixelData/blendPixelDataAlphaMask.ts +15 -13
- package/src/PixelData/blendPixelDataBinaryMask.ts +15 -13
- package/src/PixelData/blendPixelDataMask.ts +5 -3
- package/src/PixelData/blendPixelDataPaintBuffer.ts +5 -4
- package/src/PixelData/clearPixelDataFast.ts +4 -2
- package/src/PixelData/copyPixelData.ts +14 -0
- package/src/PixelData/extractPixelData.ts +8 -7
- package/src/PixelData/extractPixelDataBuffer.ts +9 -8
- package/src/PixelData/fillPixelData.ts +16 -14
- package/src/PixelData/fillPixelDataBinaryMask.ts +10 -8
- package/src/PixelData/fillPixelDataFast.ts +16 -14
- package/src/PixelData/invertPixelData.ts +9 -8
- package/src/PixelData/pixelDataToAlphaMask.ts +9 -8
- package/src/PixelData/reflectPixelData.ts +9 -9
- package/src/PixelData/resamplePixelData.ts +20 -9
- package/src/PixelData/rotatePixelData.ts +8 -7
- package/src/PixelData/uInt32ArrayToPixelData.ts +15 -0
- package/src/PixelData/writePaintBufferToPixelData.ts +5 -5
- package/src/PixelData/writePixelDataBuffer.ts +10 -9
- package/src/Rect/_rect-types.ts +7 -0
- package/src/Rect/getRectsBounds.ts +1 -1
- package/src/Rect/trimMaskRectBounds.ts +2 -1
- package/src/Rect/trimRectBounds.ts +1 -1
- package/src/Tile/MaskTile.ts +40 -0
- package/src/Tile/PixelTile.ts +23 -0
- package/src/{PixelTile/PixelTilePool.ts → Tile/TilePool.ts} +9 -9
- package/src/Tile/_tile-types.ts +33 -0
- package/src/_errors.ts +1 -0
- package/src/_types.ts +2 -118
- package/src/index.ts +47 -22
- package/src/ImageData/imageDataToUInt32Array.ts +0 -13
- package/src/Internal/helpers.ts +0 -5
- package/src/Paint/makeCirclePaintAlphaMask.ts +0 -41
- package/src/Paint/makeCirclePaintBinaryMask.ts +0 -29
- package/src/PixelTile/PixelTile.ts +0 -21
- /package/src/{Internal → Rect}/resolveClipping.ts +0 -0
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Color32, type PixelBlendMaskOptions } 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
|
export function blendPixelDataAlphaMask(
|
|
5
|
-
target:
|
|
6
|
-
src:
|
|
7
|
+
target: PixelData32,
|
|
8
|
+
src: PixelData32,
|
|
7
9
|
alphaMask: AlphaMask,
|
|
8
10
|
opts?: PixelBlendMaskOptions,
|
|
9
11
|
): boolean {
|
|
@@ -11,8 +13,8 @@ export function blendPixelDataAlphaMask(
|
|
|
11
13
|
const targetY = opts?.y ?? 0
|
|
12
14
|
const sourceX = opts?.sx ?? 0
|
|
13
15
|
const sourceY = opts?.sy ?? 0
|
|
14
|
-
const width = opts?.w ?? src.
|
|
15
|
-
const height = opts?.h ?? src.
|
|
16
|
+
const width = opts?.w ?? src.w
|
|
17
|
+
const height = opts?.h ?? src.h
|
|
16
18
|
const globalAlpha = opts?.alpha ?? 255
|
|
17
19
|
const blendFn = opts?.blendFn ?? sourceOverPerfect
|
|
18
20
|
const mx = opts?.mx ?? 0
|
|
@@ -39,8 +41,8 @@ export function blendPixelDataAlphaMask(
|
|
|
39
41
|
h += sy
|
|
40
42
|
sy = 0
|
|
41
43
|
}
|
|
42
|
-
w = Math.min(w, src.
|
|
43
|
-
h = Math.min(h, src.
|
|
44
|
+
w = Math.min(w, src.w - sx)
|
|
45
|
+
h = Math.min(h, src.h - sy)
|
|
44
46
|
if (x < 0) {
|
|
45
47
|
sx -= x
|
|
46
48
|
w += x
|
|
@@ -52,13 +54,13 @@ export function blendPixelDataAlphaMask(
|
|
|
52
54
|
y = 0
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
const actualW = Math.min(w, target.
|
|
56
|
-
const actualH = Math.min(h, target.
|
|
57
|
+
const actualW = Math.min(w, target.w - x)
|
|
58
|
+
const actualH = Math.min(h, target.h - y)
|
|
57
59
|
if (actualW <= 0 || actualH <= 0) return false
|
|
58
60
|
|
|
59
61
|
// 2. Index Setup
|
|
60
|
-
const dw = target.
|
|
61
|
-
const sw = src.
|
|
62
|
+
const dw = target.w
|
|
63
|
+
const sw = src.w
|
|
62
64
|
const mPitch = alphaMask.w
|
|
63
65
|
const maskData = alphaMask.data
|
|
64
66
|
|
|
@@ -67,8 +69,8 @@ export function blendPixelDataAlphaMask(
|
|
|
67
69
|
const dx = (x - targetX) | 0
|
|
68
70
|
const dy = (y - targetY) | 0
|
|
69
71
|
|
|
70
|
-
const dst32 = target.
|
|
71
|
-
const src32 = src.
|
|
72
|
+
const dst32 = target.data
|
|
73
|
+
const src32 = src.data
|
|
72
74
|
|
|
73
75
|
let dIdx = (y * dw + x) | 0
|
|
74
76
|
let sIdx = (sy * sw + sx) | 0
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Color32, PixelBlendMaskOptions } 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
|
export function blendPixelDataBinaryMask(
|
|
5
|
-
target:
|
|
6
|
-
src:
|
|
7
|
+
target: PixelData32,
|
|
8
|
+
src: PixelData32,
|
|
7
9
|
binaryMask: BinaryMask,
|
|
8
10
|
opts?: PixelBlendMaskOptions,
|
|
9
11
|
): boolean {
|
|
@@ -11,8 +13,8 @@ export function blendPixelDataBinaryMask(
|
|
|
11
13
|
const targetY = opts?.y ?? 0
|
|
12
14
|
const sourceX = opts?.sx ?? 0
|
|
13
15
|
const sourceY = opts?.sy ?? 0
|
|
14
|
-
const width = opts?.w ?? src.
|
|
15
|
-
const height = opts?.h ?? src.
|
|
16
|
+
const width = opts?.w ?? src.w
|
|
17
|
+
const height = opts?.h ?? src.h
|
|
16
18
|
const globalAlpha = opts?.alpha ?? 255
|
|
17
19
|
const blendFn = opts?.blendFn ?? sourceOverPerfect
|
|
18
20
|
const mx = opts?.mx ?? 0
|
|
@@ -39,8 +41,8 @@ export function blendPixelDataBinaryMask(
|
|
|
39
41
|
h += sy
|
|
40
42
|
sy = 0
|
|
41
43
|
}
|
|
42
|
-
w = Math.min(w, src.
|
|
43
|
-
h = Math.min(h, src.
|
|
44
|
+
w = Math.min(w, src.w - sx)
|
|
45
|
+
h = Math.min(h, src.h - sy)
|
|
44
46
|
|
|
45
47
|
// 2. Destination Clipping
|
|
46
48
|
if (x < 0) {
|
|
@@ -54,8 +56,8 @@ export function blendPixelDataBinaryMask(
|
|
|
54
56
|
y = 0
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
const actualW = Math.min(w, target.
|
|
58
|
-
const actualH = Math.min(h, target.
|
|
59
|
+
const actualW = Math.min(w, target.w - x)
|
|
60
|
+
const actualH = Math.min(h, target.h - y)
|
|
59
61
|
|
|
60
62
|
if (actualW <= 0 || actualH <= 0) return false
|
|
61
63
|
|
|
@@ -65,10 +67,10 @@ export function blendPixelDataBinaryMask(
|
|
|
65
67
|
const dx = (x - targetX) | 0
|
|
66
68
|
const dy = (y - targetY) | 0
|
|
67
69
|
|
|
68
|
-
const dst32 = target.
|
|
69
|
-
const src32 = src.
|
|
70
|
-
const dw = target.
|
|
71
|
-
const sw = src.
|
|
70
|
+
const dst32 = target.data
|
|
71
|
+
const src32 = src.data
|
|
72
|
+
const dw = target.w
|
|
73
|
+
const sw = src.w
|
|
72
74
|
const mPitch = binaryMask.w
|
|
73
75
|
const maskData = binaryMask.data
|
|
74
76
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PixelBlendMaskOptions } from '../_types'
|
|
2
|
+
import { type Mask, MaskType } from '../Mask/_mask-types'
|
|
3
|
+
import type { PixelData32 } from './_pixelData-types'
|
|
2
4
|
import { blendPixelDataAlphaMask } from './blendPixelDataAlphaMask'
|
|
3
5
|
import { blendPixelDataBinaryMask } from './blendPixelDataBinaryMask'
|
|
4
6
|
|
|
5
7
|
export function blendPixelDataMask(
|
|
6
|
-
target:
|
|
7
|
-
src:
|
|
8
|
+
target: PixelData32,
|
|
9
|
+
src: PixelData32,
|
|
8
10
|
mask: Mask,
|
|
9
11
|
opts?: PixelBlendMaskOptions,
|
|
10
12
|
): boolean {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { BlendColor32
|
|
1
|
+
import type { BlendColor32 } from '../_types'
|
|
2
|
+
import type { ColorPaintBuffer } from '../Paint/ColorPaintBuffer'
|
|
3
|
+
import type { PixelData32 } from './_pixelData-types'
|
|
2
4
|
import { blendPixelData } from './blendPixelData'
|
|
3
|
-
import type { PaintBuffer } from '../Paint/PaintBuffer'
|
|
4
5
|
|
|
5
6
|
const SCRATCH_OPTS = {
|
|
6
7
|
x: 0,
|
|
@@ -10,8 +11,8 @@ const SCRATCH_OPTS = {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export function blendPixelDataPaintBuffer(
|
|
13
|
-
target:
|
|
14
|
-
paintBuffer:
|
|
14
|
+
target: PixelData32,
|
|
15
|
+
paintBuffer: ColorPaintBuffer,
|
|
15
16
|
alpha = 255,
|
|
16
17
|
blendFn?: BlendColor32,
|
|
17
18
|
blendPixelDataFn = blendPixelData,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Color32 } from '../_types'
|
|
2
|
+
import type { BinaryMaskRect } from '../Mask/_mask-types'
|
|
3
|
+
import type { PixelData32 } from './_pixelData-types'
|
|
2
4
|
import { fillPixelDataFast } from './fillPixelDataFast'
|
|
3
5
|
|
|
4
6
|
/**
|
|
@@ -6,7 +8,7 @@ import { fillPixelDataFast } from './fillPixelDataFast'
|
|
|
6
8
|
* Internally uses the optimized fillPixelDataFast.
|
|
7
9
|
*/
|
|
8
10
|
export function clearPixelDataFast(
|
|
9
|
-
dst:
|
|
11
|
+
dst: PixelData32,
|
|
10
12
|
rect?: Partial<BinaryMaskRect>,
|
|
11
13
|
): void {
|
|
12
14
|
fillPixelDataFast(dst, 0 as Color32, rect)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ImageDataLike } from '../ImageData/_ImageData-types'
|
|
2
|
+
import type { PixelData } from './_pixelData-types'
|
|
3
|
+
import { makePixelData } from './PixelData'
|
|
4
|
+
|
|
5
|
+
export function copyPixelData<T extends ImageDataLike = ImageData>(target: PixelData<T>): PixelData {
|
|
6
|
+
const data = target.imageData.data
|
|
7
|
+
const buffer = new Uint8ClampedArray(data)
|
|
8
|
+
|
|
9
|
+
return makePixelData(new ImageData(
|
|
10
|
+
buffer,
|
|
11
|
+
target.w,
|
|
12
|
+
target.h,
|
|
13
|
+
))
|
|
14
|
+
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Rect } from '../Rect/_rect-types'
|
|
2
|
+
import type { PixelData, PixelData32 } from './_pixelData-types'
|
|
2
3
|
import { extractPixelDataBuffer } from './extractPixelDataBuffer'
|
|
3
|
-
import {
|
|
4
|
+
import { makePixelData } from './PixelData'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* High-level extraction that returns a new PixelData instance.
|
|
7
8
|
* Leverages extractPixelDataBuffer for optimized 32-bit memory moves.
|
|
8
9
|
*/
|
|
9
|
-
export function extractPixelData(source:
|
|
10
|
-
export function extractPixelData(source:
|
|
10
|
+
export function extractPixelData(source: PixelData32, rect: Rect): PixelData
|
|
11
|
+
export function extractPixelData(source: PixelData32, x: number, y: number, w: number, h: number): PixelData
|
|
11
12
|
export function extractPixelData(
|
|
12
|
-
source:
|
|
13
|
+
source: PixelData32,
|
|
13
14
|
_x: Rect | number,
|
|
14
15
|
_y?: number,
|
|
15
16
|
_w?: number,
|
|
@@ -19,10 +20,10 @@ export function extractPixelData(
|
|
|
19
20
|
? _x
|
|
20
21
|
: { x: _x, y: _y!, w: _w!, h: _h! }
|
|
21
22
|
|
|
22
|
-
const result =
|
|
23
|
+
const result = makePixelData(new ImageData(w, h))
|
|
23
24
|
|
|
24
25
|
const buffer = extractPixelDataBuffer(source, x, y, w, h)
|
|
25
|
-
result.
|
|
26
|
+
result.data.set(buffer)
|
|
26
27
|
|
|
27
28
|
return result
|
|
28
29
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { makeClippedBlit, resolveBlitClipping } from '../
|
|
1
|
+
import type { Rect } from '../Rect/_rect-types'
|
|
2
|
+
import { makeClippedBlit, resolveBlitClipping } from '../Rect/resolveClipping'
|
|
3
|
+
import type { PixelData32 } from './_pixelData-types'
|
|
3
4
|
|
|
4
5
|
const SCRATCH_BLIT = makeClippedBlit()
|
|
5
6
|
|
|
@@ -7,10 +8,10 @@ const SCRATCH_BLIT = makeClippedBlit()
|
|
|
7
8
|
* Extracts a rectangular region of pixels from PixelData.
|
|
8
9
|
* Returns a new Uint32Array containing the extracted pixels.
|
|
9
10
|
*/
|
|
10
|
-
export function extractPixelDataBuffer(source:
|
|
11
|
-
export function extractPixelDataBuffer(source:
|
|
11
|
+
export function extractPixelDataBuffer(source: PixelData32, rect: Rect): Uint32Array
|
|
12
|
+
export function extractPixelDataBuffer(source: PixelData32, x: number, y: number, w: number, h: number): Uint32Array
|
|
12
13
|
export function extractPixelDataBuffer(
|
|
13
|
-
source:
|
|
14
|
+
source: PixelData32,
|
|
14
15
|
_x: Rect | number,
|
|
15
16
|
_y?: number,
|
|
16
17
|
_w?: number,
|
|
@@ -20,9 +21,9 @@ export function extractPixelDataBuffer(
|
|
|
20
21
|
? _x
|
|
21
22
|
: { x: _x, y: _y!, w: _w!, h: _h! }
|
|
22
23
|
|
|
23
|
-
const srcW = source.
|
|
24
|
-
const srcH = source.
|
|
25
|
-
const srcData = source.
|
|
24
|
+
const srcW = source.w
|
|
25
|
+
const srcH = source.h
|
|
26
|
+
const srcData = source.data
|
|
26
27
|
|
|
27
28
|
// Safety check for empty or invalid dimensions
|
|
28
29
|
if (w <= 0 || h <= 0) {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import type { Color32
|
|
2
|
-
import {
|
|
1
|
+
import type { Color32 } from '../_types'
|
|
2
|
+
import type { Rect } from '../Rect/_rect-types'
|
|
3
|
+
import { makeClippedRect, resolveRectClipping } from '../Rect/resolveClipping'
|
|
4
|
+
import type { PixelData32 } from './_pixelData-types'
|
|
3
5
|
|
|
4
6
|
const SCRATCH_RECT = makeClippedRect()
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
|
-
* Fills a region or the {@link
|
|
9
|
+
* Fills a region or the {@link PixelData32} buffer with a solid color.
|
|
8
10
|
*
|
|
9
11
|
* @param dst - The target to modify.
|
|
10
12
|
* @param color - The color to apply.
|
|
@@ -12,7 +14,7 @@ const SCRATCH_RECT = makeClippedRect()
|
|
|
12
14
|
* @returns true if any pixels were actually modified.
|
|
13
15
|
*/
|
|
14
16
|
export function fillPixelData(
|
|
15
|
-
dst:
|
|
17
|
+
dst: PixelData32,
|
|
16
18
|
color: Color32,
|
|
17
19
|
rect?: Partial<Rect>,
|
|
18
20
|
): boolean
|
|
@@ -25,7 +27,7 @@ export function fillPixelData(
|
|
|
25
27
|
* @param h - Height of the fill area.
|
|
26
28
|
*/
|
|
27
29
|
export function fillPixelData(
|
|
28
|
-
dst:
|
|
30
|
+
dst: PixelData32,
|
|
29
31
|
color: Color32,
|
|
30
32
|
x: number,
|
|
31
33
|
y: number,
|
|
@@ -33,7 +35,7 @@ export function fillPixelData(
|
|
|
33
35
|
h: number,
|
|
34
36
|
): boolean
|
|
35
37
|
export function fillPixelData(
|
|
36
|
-
dst:
|
|
38
|
+
dst: PixelData32,
|
|
37
39
|
color: Color32,
|
|
38
40
|
_x?: Partial<Rect> | number,
|
|
39
41
|
_y?: number,
|
|
@@ -48,8 +50,8 @@ export function fillPixelData(
|
|
|
48
50
|
if (typeof _x === 'object') {
|
|
49
51
|
x = _x.x ?? 0
|
|
50
52
|
y = _x.y ?? 0
|
|
51
|
-
w = _x.w ?? dst.
|
|
52
|
-
h = _x.h ?? dst.
|
|
53
|
+
w = _x.w ?? dst.w
|
|
54
|
+
h = _x.h ?? dst.h
|
|
53
55
|
} else if (typeof _x === 'number') {
|
|
54
56
|
x = _x
|
|
55
57
|
y = _y!
|
|
@@ -58,8 +60,8 @@ export function fillPixelData(
|
|
|
58
60
|
} else {
|
|
59
61
|
x = 0
|
|
60
62
|
y = 0
|
|
61
|
-
w = dst.
|
|
62
|
-
h = dst.
|
|
63
|
+
w = dst.w
|
|
64
|
+
h = dst.h
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
const clip = resolveRectClipping(
|
|
@@ -67,8 +69,8 @@ export function fillPixelData(
|
|
|
67
69
|
y,
|
|
68
70
|
w,
|
|
69
71
|
h,
|
|
70
|
-
dst.
|
|
71
|
-
dst.
|
|
72
|
+
dst.w,
|
|
73
|
+
dst.h,
|
|
72
74
|
SCRATCH_RECT,
|
|
73
75
|
)
|
|
74
76
|
|
|
@@ -81,8 +83,8 @@ export function fillPixelData(
|
|
|
81
83
|
h: actualH,
|
|
82
84
|
} = clip
|
|
83
85
|
|
|
84
|
-
const dst32 = dst.
|
|
85
|
-
const dw = dst.
|
|
86
|
+
const dst32 = dst.data
|
|
87
|
+
const dw = dst.w
|
|
86
88
|
let hasChanged = false
|
|
87
89
|
|
|
88
90
|
for (let iy = 0; iy < actualH; iy++) {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
1
|
+
import type { Color32 } from '../_types'
|
|
2
|
+
import type { BinaryMask } from '../Mask/_mask-types'
|
|
3
|
+
import { makeClippedRect, resolveRectClipping } from '../Rect/resolveClipping'
|
|
4
|
+
import type { PixelData32 } from './_pixelData-types'
|
|
3
5
|
|
|
4
6
|
const SCRATCH_RECT = makeClippedRect()
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
|
-
* Fills a region of the {@link
|
|
9
|
+
* Fills a region of the {@link PixelData32} buffer with a solid color using a mask.
|
|
8
10
|
* @param target - The target to modify.
|
|
9
11
|
* @param color - The color to apply.
|
|
10
12
|
* @param mask - The mask defining the area to fill.
|
|
@@ -12,7 +14,7 @@ const SCRATCH_RECT = makeClippedRect()
|
|
|
12
14
|
* @param y - Starting vertical coordinate for the mask placement.
|
|
13
15
|
*/
|
|
14
16
|
export function fillPixelDataBinaryMask(
|
|
15
|
-
target:
|
|
17
|
+
target: PixelData32,
|
|
16
18
|
color: Color32,
|
|
17
19
|
mask: BinaryMask,
|
|
18
20
|
x = 0,
|
|
@@ -27,8 +29,8 @@ export function fillPixelDataBinaryMask(
|
|
|
27
29
|
y,
|
|
28
30
|
maskW,
|
|
29
31
|
maskH,
|
|
30
|
-
target.
|
|
31
|
-
target.
|
|
32
|
+
target.w,
|
|
33
|
+
target.h,
|
|
32
34
|
SCRATCH_RECT,
|
|
33
35
|
)
|
|
34
36
|
|
|
@@ -42,8 +44,8 @@ export function fillPixelDataBinaryMask(
|
|
|
42
44
|
} = clip
|
|
43
45
|
|
|
44
46
|
const maskData = mask.data
|
|
45
|
-
const dst32 = target.
|
|
46
|
-
const dw = target.
|
|
47
|
+
const dst32 = target.data
|
|
48
|
+
const dw = target.w
|
|
47
49
|
|
|
48
50
|
let hasChanged = false
|
|
49
51
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import type { Color32
|
|
2
|
-
import {
|
|
1
|
+
import type { Color32 } from '../_types'
|
|
2
|
+
import type { Rect } from '../Rect/_rect-types'
|
|
3
|
+
import { makeClippedRect, resolveRectClipping } from '../Rect/resolveClipping'
|
|
4
|
+
import type { PixelData32 } from './_pixelData-types'
|
|
3
5
|
|
|
4
6
|
const SCRATCH_RECT = makeClippedRect()
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
|
-
* Fills a region or the {@link
|
|
9
|
+
* Fills a region or the {@link PixelData32} buffer with a solid color.
|
|
8
10
|
* This function is faster than {@link fillPixelData} but does not
|
|
9
11
|
* return a boolean value indicating changes were made.
|
|
10
12
|
*
|
|
@@ -14,7 +16,7 @@ const SCRATCH_RECT = makeClippedRect()
|
|
|
14
16
|
* buffer is filled.
|
|
15
17
|
*/
|
|
16
18
|
export function fillPixelDataFast(
|
|
17
|
-
target:
|
|
19
|
+
target: PixelData32,
|
|
18
20
|
color: Color32,
|
|
19
21
|
rect?: Partial<Rect>,
|
|
20
22
|
): void
|
|
@@ -27,7 +29,7 @@ export function fillPixelDataFast(
|
|
|
27
29
|
* @param h - Height of the fill area.
|
|
28
30
|
*/
|
|
29
31
|
export function fillPixelDataFast(
|
|
30
|
-
dst:
|
|
32
|
+
dst: PixelData32,
|
|
31
33
|
color: Color32,
|
|
32
34
|
x: number,
|
|
33
35
|
y: number,
|
|
@@ -35,7 +37,7 @@ export function fillPixelDataFast(
|
|
|
35
37
|
h: number,
|
|
36
38
|
): void
|
|
37
39
|
export function fillPixelDataFast(
|
|
38
|
-
dst:
|
|
40
|
+
dst: PixelData32,
|
|
39
41
|
color: Color32,
|
|
40
42
|
_x?: Partial<Rect> | number,
|
|
41
43
|
_y?: number,
|
|
@@ -50,8 +52,8 @@ export function fillPixelDataFast(
|
|
|
50
52
|
if (typeof _x === 'object') {
|
|
51
53
|
x = _x.x ?? 0
|
|
52
54
|
y = _x.y ?? 0
|
|
53
|
-
w = _x.w ?? dst.
|
|
54
|
-
h = _x.h ?? dst.
|
|
55
|
+
w = _x.w ?? dst.w
|
|
56
|
+
h = _x.h ?? dst.h
|
|
55
57
|
} else if (typeof _x === 'number') {
|
|
56
58
|
x = _x
|
|
57
59
|
y = _y!
|
|
@@ -60,11 +62,11 @@ export function fillPixelDataFast(
|
|
|
60
62
|
} else {
|
|
61
63
|
x = 0
|
|
62
64
|
y = 0
|
|
63
|
-
w = dst.
|
|
64
|
-
h = dst.
|
|
65
|
+
w = dst.w
|
|
66
|
+
h = dst.h
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
const clip = resolveRectClipping(x, y, w, h, dst.
|
|
69
|
+
const clip = resolveRectClipping(x, y, w, h, dst.w, dst.h, SCRATCH_RECT)
|
|
68
70
|
|
|
69
71
|
if (!clip.inBounds) return
|
|
70
72
|
|
|
@@ -76,11 +78,11 @@ export function fillPixelDataFast(
|
|
|
76
78
|
h: actualH,
|
|
77
79
|
} = clip
|
|
78
80
|
|
|
79
|
-
const dst32 = dst.
|
|
80
|
-
const dw = dst.
|
|
81
|
+
const dst32 = dst.data
|
|
82
|
+
const dw = dst.w
|
|
81
83
|
|
|
82
84
|
// Optimization: If filling the entire buffer, use the native .fill()
|
|
83
|
-
if (actualW === dw && actualH === dst.
|
|
85
|
+
if (actualW === dw && actualH === dst.h && finalX === 0 && finalY === 0) {
|
|
84
86
|
dst32.fill(color)
|
|
85
87
|
return
|
|
86
88
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { makeClippedRect, resolveRectClipping } from '../
|
|
1
|
+
import { type PixelMutateOptions } from '../_types'
|
|
2
|
+
import { makeClippedRect, resolveRectClipping } from '../Rect/resolveClipping'
|
|
3
|
+
import type { PixelData32 } from './_pixelData-types'
|
|
3
4
|
|
|
4
5
|
const SCRATCH_RECT = makeClippedRect()
|
|
5
6
|
|
|
6
7
|
export function invertPixelData(
|
|
7
|
-
target:
|
|
8
|
+
target: PixelData32,
|
|
8
9
|
opts?: PixelMutateOptions,
|
|
9
10
|
): boolean {
|
|
10
11
|
const mask = opts?.mask
|
|
@@ -12,11 +13,11 @@ export function invertPixelData(
|
|
|
12
13
|
const targetY = opts?.y ?? 0
|
|
13
14
|
const mx = opts?.mx ?? 0
|
|
14
15
|
const my = opts?.my ?? 0
|
|
15
|
-
const width = opts?.w ?? target.
|
|
16
|
-
const height = opts?.h ?? target.
|
|
16
|
+
const width = opts?.w ?? target.w
|
|
17
|
+
const height = opts?.h ?? target.h
|
|
17
18
|
const invertMask = opts?.invertMask ?? false
|
|
18
19
|
|
|
19
|
-
const clip = resolveRectClipping(targetX, targetY, width, height, target.
|
|
20
|
+
const clip = resolveRectClipping(targetX, targetY, width, height, target.w, target.h, SCRATCH_RECT)
|
|
20
21
|
|
|
21
22
|
if (!clip.inBounds) return false
|
|
22
23
|
|
|
@@ -27,8 +28,8 @@ export function invertPixelData(
|
|
|
27
28
|
h: actualH,
|
|
28
29
|
} = clip
|
|
29
30
|
|
|
30
|
-
const dst32 = target.
|
|
31
|
-
const dw = target.
|
|
31
|
+
const dst32 = target.data
|
|
32
|
+
const dw = target.w
|
|
32
33
|
const mPitch = mask?.w ?? width
|
|
33
34
|
|
|
34
35
|
const dx = x - targetX
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import type { AlphaMask
|
|
1
|
+
import type { AlphaMask } from '../Mask/_mask-types'
|
|
2
2
|
import { makeAlphaMask } from '../Mask/AlphaMask'
|
|
3
|
+
import type { PixelData32 } from './_pixelData-types'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Extracts the alpha channel from PixelData into a single-channel mask.
|
|
6
7
|
* Returns a Uint8Array branded as AlphaMask.
|
|
7
8
|
*/
|
|
8
9
|
export function pixelDataToAlphaMask(
|
|
9
|
-
pixelData:
|
|
10
|
+
pixelData: PixelData32,
|
|
10
11
|
): AlphaMask {
|
|
11
12
|
const {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
data,
|
|
14
|
+
w,
|
|
15
|
+
h,
|
|
15
16
|
} = pixelData
|
|
16
|
-
const len =
|
|
17
|
-
const mask = makeAlphaMask(
|
|
17
|
+
const len = data.length
|
|
18
|
+
const mask = makeAlphaMask(w, h)
|
|
18
19
|
const maskData = mask.data
|
|
19
20
|
|
|
20
21
|
for (let i = 0; i < len; i++) {
|
|
21
|
-
const val =
|
|
22
|
+
const val = data[i]
|
|
22
23
|
|
|
23
24
|
// Extract the Alpha byte (top 8 bits in ABGR / Little-Endian)
|
|
24
25
|
// Shift right by 24 moves the 4th byte to the 1st position
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PixelData32 } from './_pixelData-types'
|
|
2
2
|
|
|
3
|
-
export function reflectPixelDataHorizontal(pixelData:
|
|
4
|
-
const width = pixelData.
|
|
5
|
-
const height = pixelData.
|
|
6
|
-
const data = pixelData.
|
|
3
|
+
export function reflectPixelDataHorizontal(pixelData: PixelData32): void {
|
|
4
|
+
const width = pixelData.w
|
|
5
|
+
const height = pixelData.h
|
|
6
|
+
const data = pixelData.data
|
|
7
7
|
const halfWidth = Math.floor(width / 2)
|
|
8
8
|
|
|
9
9
|
for (let y = 0; y < height; y++) {
|
|
@@ -20,10 +20,10 @@ export function reflectPixelDataHorizontal(pixelData: IPixelData32): void {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export function reflectPixelDataVertical(pixelData:
|
|
24
|
-
const width = pixelData.
|
|
25
|
-
const height = pixelData.
|
|
26
|
-
const data = pixelData.
|
|
23
|
+
export function reflectPixelDataVertical(pixelData: PixelData32): void {
|
|
24
|
+
const width = pixelData.w
|
|
25
|
+
const height = pixelData.h
|
|
26
|
+
const data = pixelData.data
|
|
27
27
|
const halfHeight = Math.floor(height / 2)
|
|
28
28
|
|
|
29
29
|
for (let y = 0; y < halfHeight; y++) {
|
|
@@ -1,19 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { resampleUint32Array } from '../Algorithm/resampleUint32Array'
|
|
2
|
+
import { type MutablePixelData32, type PixelData, type PixelData32, uInt32ArrayToImageData } from '../index'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Resamples PixelData by a specific factor using nearest neighbor.
|
|
6
6
|
* Factor > 1 upscales, Factor < 1 downscales.
|
|
7
7
|
*/
|
|
8
8
|
export function resamplePixelData(
|
|
9
|
-
pixelData:
|
|
9
|
+
pixelData: PixelData32,
|
|
10
10
|
factor: number,
|
|
11
11
|
): PixelData {
|
|
12
|
-
const { data, width, height } = resample32(pixelData.data32, pixelData.width, pixelData.height, factor)
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
))
|
|
13
|
+
const output = {} as MutablePixelData32
|
|
14
|
+
|
|
15
|
+
const resampled = resampleUint32Array(pixelData.data, pixelData.w, pixelData.h, factor, output) as PixelData
|
|
16
|
+
|
|
17
|
+
(resampled as any).imageData = uInt32ArrayToImageData(resampled.data, resampled.w, resampled.h)
|
|
18
|
+
|
|
19
|
+
return resampled
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function resamplePixelDataInPlace(
|
|
23
|
+
pixelData: PixelData32,
|
|
24
|
+
factor: number,
|
|
25
|
+
): void {
|
|
26
|
+
|
|
27
|
+
const resampled = resampleUint32Array(pixelData.data, pixelData.w, pixelData.h, factor, pixelData) as PixelData
|
|
28
|
+
|
|
29
|
+
(resampled as any).imageData = uInt32ArrayToImageData(resampled.data, resampled.w, resampled.h)
|
|
19
30
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { PixelData } from './
|
|
1
|
+
import type { PixelData } from './_pixelData-types'
|
|
2
|
+
import { setPixelData } from './PixelData'
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Rotates pixel data 90 degrees clockwise.
|
|
@@ -6,9 +7,9 @@ import { PixelData } from './PixelData'
|
|
|
6
7
|
* If rectangular, it replaces the internal ImageData with a new rotated version.
|
|
7
8
|
*/
|
|
8
9
|
export function rotatePixelData(pixelData: PixelData): void {
|
|
9
|
-
const width = pixelData.
|
|
10
|
-
const height = pixelData.
|
|
11
|
-
const data = pixelData.
|
|
10
|
+
const width = pixelData.w
|
|
11
|
+
const height = pixelData.h
|
|
12
|
+
const data = pixelData.data
|
|
12
13
|
|
|
13
14
|
if (width === height) {
|
|
14
15
|
rotateSquareInPlace(pixelData)
|
|
@@ -38,12 +39,12 @@ export function rotatePixelData(pixelData: PixelData): void {
|
|
|
38
39
|
newHeight,
|
|
39
40
|
)
|
|
40
41
|
|
|
41
|
-
pixelData
|
|
42
|
+
setPixelData(pixelData, newImageData)
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
function rotateSquareInPlace(pixelData: PixelData): void {
|
|
45
|
-
const n = pixelData.
|
|
46
|
-
const data = pixelData.
|
|
46
|
+
const n = pixelData.w
|
|
47
|
+
const data = pixelData.data
|
|
47
48
|
|
|
48
49
|
for (let i = 0; i < n / 2; i++) {
|
|
49
50
|
for (let j = i; j < n - i - 1; j++) {
|