pixel-data-js 0.11.1 → 0.12.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.
@@ -27,6 +27,7 @@ __export(src_exports, {
27
27
  FAST_BLEND_TO_INDEX: () => FAST_BLEND_TO_INDEX,
28
28
  INDEX_TO_FAST_BLEND: () => INDEX_TO_FAST_BLEND,
29
29
  INDEX_TO_PERFECT_BLEND: () => INDEX_TO_PERFECT_BLEND,
30
+ IndexedImage: () => IndexedImage,
30
31
  MaskType: () => MaskType,
31
32
  PERFECT_BLENDER_REGISTRY: () => PERFECT_BLENDER_REGISTRY,
32
33
  PERFECT_BLEND_MODES: () => PERFECT_BLEND_MODES,
@@ -81,6 +82,7 @@ __export(src_exports, {
81
82
  imageDataToImgBlob: () => imageDataToImgBlob,
82
83
  imgBlobToImageData: () => imgBlobToImageData,
83
84
  indexedImageToAverageColor: () => indexedImageToAverageColor,
85
+ indexedImageToImageData: () => indexedImageToImageData,
84
86
  invertAlphaMask: () => invertAlphaMask,
85
87
  invertBinaryMask: () => invertBinaryMask,
86
88
  invertImageData: () => invertImageData,
@@ -97,7 +99,6 @@ __export(src_exports, {
97
99
  linearDodgePerfect: () => linearDodgePerfect,
98
100
  linearLightFast: () => linearLightFast,
99
101
  linearLightPerfect: () => linearLightPerfect,
100
- makeIndexedImage: () => makeIndexedImage,
101
102
  makePixelCanvas: () => makePixelCanvas,
102
103
  makeReusableCanvas: () => makeReusableCanvas,
103
104
  mergeMasks: () => mergeMasks,
@@ -138,6 +139,7 @@ __export(src_exports, {
138
139
  unpackRed: () => unpackRed,
139
140
  vividLightFast: () => vividLightFast,
140
141
  vividLightPerfect: () => vividLightPerfect,
142
+ writeImageData: () => writeImageData,
141
143
  writeImageDataPixels: () => writeImageDataPixels,
142
144
  writeImageDataToClipboard: () => writeImageDataToClipboard,
143
145
  writeImgBlobToClipboard: () => writeImgBlobToClipboard
@@ -1771,40 +1773,144 @@ function writeImageDataPixels(imageData, data, _x, _y, _w, _h) {
1771
1773
  }
1772
1774
  }
1773
1775
 
1774
- // src/IndexedImage/IndexedImage.ts
1775
- function makeIndexedImage(imageOrData, width, height) {
1776
- const isImageData = "width" in imageOrData;
1777
- const actualWidth = isImageData ? imageOrData.width : width;
1778
- const actualHeight = isImageData ? imageOrData.height : height;
1779
- const buffer = isImageData ? imageOrData.data.buffer : imageOrData.buffer;
1780
- const rawData = new Uint32Array(buffer);
1781
- const indexedData = new Int32Array(rawData.length);
1782
- const colorMap = /* @__PURE__ */ new Map();
1783
- const transparentColor = 0;
1784
- const transparentPalletIndex = 0;
1785
- colorMap.set(transparentColor, transparentPalletIndex);
1786
- for (let i = 0; i < rawData.length; i++) {
1787
- const pixel = rawData[i];
1788
- const alpha = pixel >>> 24 & 255;
1789
- const isTransparent = alpha === 0;
1790
- const colorKey = isTransparent ? transparentColor : pixel >>> 0;
1791
- let id = colorMap.get(colorKey);
1792
- if (id === void 0) {
1793
- id = colorMap.size;
1794
- colorMap.set(colorKey, id);
1776
+ // src/ImageData/writeImageData.ts
1777
+ function writeImageData(target, source, x, y, sx = 0, sy = 0, sw = source.width, sh = source.height, mask = null, maskType = 1 /* BINARY */) {
1778
+ const dstW = target.width;
1779
+ const dstH = target.height;
1780
+ const dstData = target.data;
1781
+ const srcW = source.width;
1782
+ const srcData = source.data;
1783
+ const x0 = Math.max(0, x);
1784
+ const y0 = Math.max(0, y);
1785
+ const x1 = Math.min(dstW, x + sw);
1786
+ const y1 = Math.min(dstH, y + sh);
1787
+ if (x1 <= x0 || y1 <= y0) {
1788
+ return;
1789
+ }
1790
+ const useMask = !!mask;
1791
+ const rowCount = y1 - y0;
1792
+ const rowLenPixels = x1 - x0;
1793
+ for (let row = 0; row < rowCount; row++) {
1794
+ const dstY = y0 + row;
1795
+ const srcY = sy + (dstY - y);
1796
+ const srcXBase = sx + (x0 - x);
1797
+ const dstStart = (dstY * dstW + x0) * 4;
1798
+ const srcStart = (srcY * srcW + srcXBase) * 4;
1799
+ if (useMask && mask) {
1800
+ for (let ix = 0; ix < rowLenPixels; ix++) {
1801
+ const mi = srcY * srcW + (srcXBase + ix);
1802
+ const alpha = mask[mi];
1803
+ if (alpha === 0) {
1804
+ continue;
1805
+ }
1806
+ const di = dstStart + ix * 4;
1807
+ const si = srcStart + ix * 4;
1808
+ if (maskType === 1 /* BINARY */ || alpha === 255) {
1809
+ dstData[di] = srcData[si];
1810
+ dstData[di + 1] = srcData[si + 1];
1811
+ dstData[di + 2] = srcData[si + 2];
1812
+ dstData[di + 3] = srcData[si + 3];
1813
+ } else {
1814
+ const a = alpha / 255;
1815
+ const invA = 1 - a;
1816
+ dstData[di] = srcData[si] * a + dstData[di] * invA;
1817
+ dstData[di + 1] = srcData[si + 1] * a + dstData[di + 1] * invA;
1818
+ dstData[di + 2] = srcData[si + 2] * a + dstData[di + 2] * invA;
1819
+ dstData[di + 3] = srcData[si + 3] * a + dstData[di + 3] * invA;
1820
+ }
1821
+ }
1822
+ } else {
1823
+ const byteLen = rowLenPixels * 4;
1824
+ const sub = srcData.subarray(srcStart, srcStart + byteLen);
1825
+ dstData.set(sub, dstStart);
1795
1826
  }
1796
- indexedData[i] = id;
1797
1827
  }
1798
- const palette = Uint32Array.from(colorMap.keys());
1799
- return {
1800
- width: actualWidth,
1801
- height: actualHeight,
1802
- data: indexedData,
1803
- transparentPalletIndex,
1804
- palette
1805
- };
1806
1828
  }
1807
1829
 
1830
+ // src/IndexedImage/IndexedImage.ts
1831
+ var IndexedImage = class _IndexedImage {
1832
+ /** The width of the image in pixels. */
1833
+ width;
1834
+ /** The height of the image in pixels. */
1835
+ height;
1836
+ /** Flat array of palette indices. Index = x + (y * width). */
1837
+ data;
1838
+ /** The palette of unique 32-bit colors (ABGR/RGBA packed) found in the image. */
1839
+ palette;
1840
+ /** The specific index in the palette reserved for fully transparent pixels. */
1841
+ transparentPalletIndex;
1842
+ /**
1843
+ * @param width - Image width.
1844
+ * @param height - Image height.
1845
+ * @param data - The indexed pixel data.
1846
+ * @param palette - The array of packed colors.
1847
+ * @param transparentPalletIndex - The index representing alpha 0.
1848
+ */
1849
+ constructor(width, height, data, palette, transparentPalletIndex) {
1850
+ this.width = width;
1851
+ this.height = height;
1852
+ this.data = data;
1853
+ this.palette = palette;
1854
+ this.transparentPalletIndex = transparentPalletIndex;
1855
+ }
1856
+ /**
1857
+ * Creates an IndexedImage from standard browser ImageData.
1858
+ * @param imageData - The source ImageData to convert.
1859
+ * @returns A new IndexedImage instance.
1860
+ */
1861
+ static fromImageData(imageData) {
1862
+ return _IndexedImage.fromRaw(imageData.data, imageData.width, imageData.height);
1863
+ }
1864
+ /**
1865
+ * Creates an IndexedImage from a raw byte buffer and dimensions.
1866
+ * Any pixel with an alpha channel of 0 is normalized to the transparent palette index.
1867
+ * @param data - Raw RGBA byte data.
1868
+ * @param width - Image width.
1869
+ * @param height - Image height.
1870
+ * @returns A new IndexedImage instance.
1871
+ */
1872
+ static fromRaw(data, width, height) {
1873
+ const buffer = data.buffer;
1874
+ const rawData = new Uint32Array(buffer);
1875
+ const indexedData = new Int32Array(rawData.length);
1876
+ const colorMap = /* @__PURE__ */ new Map();
1877
+ const transparentColor = 0;
1878
+ const transparentPalletIndex = 0;
1879
+ colorMap.set(transparentColor, transparentPalletIndex);
1880
+ for (let i = 0; i < rawData.length; i++) {
1881
+ const pixel = rawData[i];
1882
+ const alpha = pixel >>> 24 & 255;
1883
+ const isTransparent = alpha === 0;
1884
+ const colorKey = isTransparent ? transparentColor : pixel >>> 0;
1885
+ let id = colorMap.get(colorKey);
1886
+ if (id === void 0) {
1887
+ id = colorMap.size;
1888
+ colorMap.set(colorKey, id);
1889
+ }
1890
+ indexedData[i] = id;
1891
+ }
1892
+ const palette = Uint32Array.from(colorMap.keys());
1893
+ return new _IndexedImage(
1894
+ width,
1895
+ height,
1896
+ indexedData,
1897
+ palette,
1898
+ transparentPalletIndex
1899
+ );
1900
+ }
1901
+ /**
1902
+ * Retrieves the 32-bit packed color value at the given coordinates.
1903
+ * @param x - X coordinate.
1904
+ * @param y - Y coordinate.
1905
+ * @returns The packed color from the palette.
1906
+ */
1907
+ getColorAt(x, y) {
1908
+ const index = x + y * this.width;
1909
+ const paletteIndex = this.data[index];
1910
+ return this.palette[paletteIndex];
1911
+ }
1912
+ };
1913
+
1808
1914
  // src/IndexedImage/getIndexedImageColorCounts.ts
1809
1915
  function getIndexedImageColorCounts(indexedImage) {
1810
1916
  const data = indexedImage.data;
@@ -1867,13 +1973,26 @@ function resampleIndexedImage(source, factor) {
1867
1973
  source.height,
1868
1974
  factor
1869
1975
  );
1870
- return {
1976
+ return new IndexedImage(
1871
1977
  width,
1872
1978
  height,
1873
1979
  data,
1874
- palette: source.palette,
1875
- transparentPalletIndex: source.transparentPalletIndex
1876
- };
1980
+ source.palette,
1981
+ source.transparentPalletIndex
1982
+ );
1983
+ }
1984
+
1985
+ // src/IndexedImage/indexedImageToImageData.ts
1986
+ function indexedImageToImageData(indexedImage) {
1987
+ const { width, height, data, palette } = indexedImage;
1988
+ const result = new ImageData(width, height);
1989
+ const data32 = new Uint32Array(result.data.buffer);
1990
+ for (let i = 0; i < data.length; i++) {
1991
+ const paletteIndex = data[i];
1992
+ const color = palette[paletteIndex];
1993
+ data32[i] = color;
1994
+ }
1995
+ return result;
1877
1996
  }
1878
1997
 
1879
1998
  // src/Input/fileInputChangeToImageData.ts
@@ -2561,6 +2680,7 @@ function rotateSquareInPlace(pixelData) {
2561
2680
  FAST_BLEND_TO_INDEX,
2562
2681
  INDEX_TO_FAST_BLEND,
2563
2682
  INDEX_TO_PERFECT_BLEND,
2683
+ IndexedImage,
2564
2684
  MaskType,
2565
2685
  PERFECT_BLENDER_REGISTRY,
2566
2686
  PERFECT_BLEND_MODES,
@@ -2615,6 +2735,7 @@ function rotateSquareInPlace(pixelData) {
2615
2735
  imageDataToImgBlob,
2616
2736
  imgBlobToImageData,
2617
2737
  indexedImageToAverageColor,
2738
+ indexedImageToImageData,
2618
2739
  invertAlphaMask,
2619
2740
  invertBinaryMask,
2620
2741
  invertImageData,
@@ -2631,7 +2752,6 @@ function rotateSquareInPlace(pixelData) {
2631
2752
  linearDodgePerfect,
2632
2753
  linearLightFast,
2633
2754
  linearLightPerfect,
2634
- makeIndexedImage,
2635
2755
  makePixelCanvas,
2636
2756
  makeReusableCanvas,
2637
2757
  mergeMasks,
@@ -2672,6 +2792,7 @@ function rotateSquareInPlace(pixelData) {
2672
2792
  unpackRed,
2673
2793
  vividLightFast,
2674
2794
  vividLightPerfect,
2795
+ writeImageData,
2675
2796
  writeImageDataPixels,
2676
2797
  writeImageDataToClipboard,
2677
2798
  writeImgBlobToClipboard