imagescript 1.3.1 → 3.0.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 (117) hide show
  1. package/LICENSE +4 -1
  2. package/README.md +64 -26
  3. package/THIRD_PARTY_NOTICES.md +74 -0
  4. package/dist/codecs/crc.d.ts +9 -0
  5. package/dist/codecs/crc.js +29 -0
  6. package/dist/codecs/exif.d.ts +11 -0
  7. package/dist/codecs/exif.js +27 -0
  8. package/dist/codecs/gif.d.ts +44 -0
  9. package/dist/codecs/gif.js +401 -0
  10. package/dist/codecs/jpeg.d.ts +35 -0
  11. package/dist/codecs/jpeg.js +980 -0
  12. package/dist/codecs/png.d.ts +44 -0
  13. package/dist/codecs/png.js +442 -0
  14. package/dist/codecs/quantize.d.ts +25 -0
  15. package/dist/codecs/quantize.js +302 -0
  16. package/dist/codecs/tiff.d.ts +6 -0
  17. package/dist/codecs/tiff.js +546 -0
  18. package/dist/codecs/zlib.d.ts +22 -0
  19. package/dist/codecs/zlib.js +607 -0
  20. package/dist/frame.d.ts +57 -0
  21. package/dist/frame.js +65 -0
  22. package/dist/gif.d.ts +44 -0
  23. package/dist/gif.js +93 -0
  24. package/dist/image-type.d.ts +20 -0
  25. package/dist/image-type.js +49 -0
  26. package/dist/image.d.ts +521 -0
  27. package/dist/image.js +1118 -0
  28. package/dist/index.d.ts +19 -0
  29. package/dist/index.js +13 -0
  30. package/dist/package.json +1 -0
  31. package/dist/render/font.d.ts +63 -0
  32. package/dist/render/font.js +857 -0
  33. package/dist/render/svg.d.ts +11 -0
  34. package/dist/render/svg.js +1717 -0
  35. package/dist/render/text.d.ts +61 -0
  36. package/dist/render/text.js +317 -0
  37. package/dist/text-layout.d.ts +46 -0
  38. package/dist/text-layout.js +35 -0
  39. package/dist/util/blur.d.ts +13 -0
  40. package/dist/util/blur.js +146 -0
  41. package/dist/util/mem.d.ts +10 -0
  42. package/dist/util/mem.js +23 -0
  43. package/dist/util/resample.d.ts +12 -0
  44. package/dist/util/resample.js +99 -0
  45. package/dist/util/utf8.d.ts +5 -0
  46. package/dist/util/utf8.js +55 -0
  47. package/dist/version.d.ts +1 -0
  48. package/dist/version.js +1 -0
  49. package/licenses/Apache-2.0.txt +202 -0
  50. package/licenses/README.ijg +260 -0
  51. package/package.json +31 -7
  52. package/ImageScript.d.ts +0 -954
  53. package/ImageScript.js +0 -1669
  54. package/bench/_.mjs +0 -166
  55. package/bench/all.mjs +0 -4
  56. package/bench/blur.mjs +0 -59
  57. package/bench/flip.mjs +0 -63
  58. package/bench/overlay.mjs +0 -35
  59. package/bench/package.json +0 -7
  60. package/bench/readme.md +0 -64
  61. package/bench/resize.mjs +0 -52
  62. package/codecs/LICENSE +0 -21
  63. package/codecs/lib.d.ts +0 -50
  64. package/codecs/lib.js +0 -6
  65. package/codecs/lib.mjs +0 -1
  66. package/codecs/node/bin/arm64-darwin.node +0 -0
  67. package/codecs/node/bin/arm64-linux.node +0 -0
  68. package/codecs/node/bin/x64-darwin.node +0 -0
  69. package/codecs/node/bin/x64-linux.node +0 -0
  70. package/codecs/node/bin/x64-win32.node +0 -0
  71. package/codecs/node/index.js +0 -3
  72. package/codecs/node/index.mjs +0 -6
  73. package/codecs/package.json +0 -14
  74. package/codecs/readme.md +0 -38
  75. package/codecs/wasm/bin/codecs.wasm +0 -0
  76. package/codecs/wasm/bin/simd.wasm +0 -0
  77. package/codecs/wasm/bundle/browser.js +0 -1
  78. package/codecs/wasm/index.js +0 -1
  79. package/codecs/wasm/index.mjs +0 -1
  80. package/png/README.md +0 -1
  81. package/png/node.js +0 -1137
  82. package/png/src/crc.mjs +0 -49
  83. package/png/src/mem.mjs +0 -24
  84. package/png/src/png.mjs +0 -254
  85. package/png/src/zlib.mjs +0 -618
  86. package/tsconfig.json +0 -21
  87. package/utils/mem.js +0 -26
  88. package/v2/codecs/magic.js +0 -25
  89. package/v2/framebuffer.d.ts +0 -67
  90. package/v2/framebuffer.js +0 -2352
  91. package/v2/framebuffer.mjs +0 -126
  92. package/v2/framebuffer.rs +0 -1264
  93. package/v2/index.d.ts +0 -84
  94. package/v2/index.js +0 -261
  95. package/v2/ops/blur.mjs +0 -303
  96. package/v2/ops/color.mjs +0 -277
  97. package/v2/ops/crop.mjs +0 -64
  98. package/v2/ops/fill.mjs +0 -33
  99. package/v2/ops/flip.mjs +0 -33
  100. package/v2/ops/index.mjs +0 -9
  101. package/v2/ops/iterator.mjs +0 -34
  102. package/v2/ops/overlay.mjs +0 -63
  103. package/v2/ops/resize.mjs +0 -166
  104. package/v2/ops/rotate.mjs +0 -117
  105. package/v2/util/mem.mjs +0 -24
  106. package/wasm/any/font.wasm +0 -0
  107. package/wasm/any/gif.wasm +0 -0
  108. package/wasm/any/jpeg.wasm +0 -0
  109. package/wasm/any/png.wasm +0 -0
  110. package/wasm/any/svg.wasm +0 -0
  111. package/wasm/any/tiff.wasm +0 -0
  112. package/wasm/node/font.js +0 -142
  113. package/wasm/node/gif.js +0 -76
  114. package/wasm/node/jpeg.js +0 -92
  115. package/wasm/node/png.js +0 -49
  116. package/wasm/node/svg.js +0 -56
  117. package/wasm/node/tiff.js +0 -47
package/png/src/crc.mjs DELETED
@@ -1,49 +0,0 @@
1
- const table = new Uint32Array([
2
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832,
3
- 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
4
- 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A,
5
- 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
6
- 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,
7
- 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
8
- 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
9
- 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
10
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4,
11
- 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
12
- 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074,
13
- 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
14
- 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525,
15
- 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
16
- 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
17
- 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
18
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76,
19
- 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
20
- 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6,
21
- 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
22
- 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
23
- 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
24
- 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7,
25
- 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
26
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,
27
- 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
28
- 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330,
29
- 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
30
- 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D]);
31
-
32
- export function crc32(buffer) {
33
- let offset = 0 | 0;
34
- let crc = 0xFFFFFFFF | 0;
35
- const bl = (buffer.length - 4) | 0;
36
-
37
- while (bl > offset) {
38
- crc = table[(crc ^ buffer[offset++]) & 0xff] ^ (crc >>> 8);
39
- crc = table[(crc ^ buffer[offset++]) & 0xff] ^ (crc >>> 8);
40
- crc = table[(crc ^ buffer[offset++]) & 0xff] ^ (crc >>> 8);
41
- crc = table[(crc ^ buffer[offset++]) & 0xff] ^ (crc >>> 8);
42
- }
43
-
44
- while (offset < buffer.length) {
45
- crc = table[(crc ^ buffer[offset++]) & 0xff] ^ (crc >>> 8);
46
- }
47
-
48
- return (crc ^ 0xFFFFFFFF) >>> 0;
49
- }
package/png/src/mem.mjs DELETED
@@ -1,24 +0,0 @@
1
- export function view(buffer, shared = false) {
2
- if (buffer instanceof ArrayBuffer) return new Uint8Array(buffer);
3
- if (shared && buffer instanceof SharedArrayBuffer) return new Uint8Array(buffer);
4
- if (ArrayBuffer.isView(buffer)) return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
5
-
6
- throw new TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'");
7
- }
8
-
9
- export function from_parts(buffers, shared = false) {
10
- let length = 0;
11
- let offset = 0;
12
- buffers.forEach(buffer => length += (null == buffer.byteLength ? buffer.length : buffer.byteLength));
13
-
14
- const u8 = new Uint8Array(shared ? new SharedArrayBuffer(length) : length);
15
-
16
- buffers.forEach(buffer => {
17
- const ref = Array.isArray(buffer) ? buffer : view(buffer, true);
18
-
19
- u8.set(ref, offset);
20
- offset += ref.length;
21
- });
22
-
23
- return u8;
24
- }
package/png/src/png.mjs DELETED
@@ -1,254 +0,0 @@
1
- import { crc32 } from './crc.mjs';
2
- import { from_parts } from './mem.mjs';
3
- import { compress, decompress } from './zlib.mjs';
4
-
5
- const __IHDR__ = new Uint8Array([73, 72, 68, 82]);
6
- const __IDAT__ = new Uint8Array([73, 68, 65, 84]);
7
- const __IEND__ = new Uint8Array([73, 69, 78, 68]);
8
- const __IEND_CRC__ = crc32(new Uint8Array([73, 69, 78, 68]));
9
- const HEAD = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
10
-
11
- const color_types = {
12
- GREYSCALE: 0,
13
- TRUECOLOR: 2,
14
- INDEXED_COLOR: 3,
15
- GREYSCALE_ALPHA: 4,
16
- TRUECOLOR_ALPHA: 6
17
- };
18
-
19
- const channels_to_color_type = {
20
- 1: color_types.GREYSCALE,
21
- 2: color_types.GREYSCALE_ALPHA,
22
-
23
- 3: color_types.TRUECOLOR,
24
- 4: color_types.TRUECOLOR_ALPHA
25
- };
26
-
27
- const utf8encoder = new TextEncoder; // replace with latin1 encoder or iext
28
-
29
- export function encode(data, { text, width, height, channels, depth = 8, level = 0 }) {
30
- let offset = 0;
31
- let tmp_offset = 0;
32
- const row_length = width * channels;
33
- const tmp = new Uint8Array(height + data.length);
34
-
35
- while (offset < data.length) {
36
- tmp[tmp_offset++] = 0;
37
- tmp.set(data.subarray(offset, (offset += row_length)), tmp_offset);
38
-
39
- tmp_offset += row_length;
40
- }
41
-
42
- if (text) {
43
- let chunks = [];
44
- for (const key in text) {
45
- if (!text[key]) continue;
46
- const kb = utf8encoder.encode(key);
47
- const tb = utf8encoder.encode(text[key]);
48
- const chunk = new Uint8Array(1 + 12 + kb.length + tb.length);
49
-
50
- const view = new DataView(chunk.buffer);
51
-
52
- chunk[4] = 0x74;
53
- chunk[5] = 0x45;
54
- chunk[6] = 0x58;
55
- chunk[7] = 0x74;
56
- chunk.set(kb, 8);
57
- chunks.push(chunk);
58
- chunk.set(tb, 9 + kb.length);
59
- view.setUint32(0, chunk.length - 12);
60
- view.setUint32(chunk.length - 4, crc32(chunk.subarray(4, chunk.length - 4)));
61
- }
62
-
63
- text = from_parts(chunks);
64
- }
65
-
66
- offset = text ? text.length : 0;
67
- const compressed = compress(tmp, level);
68
- const array = new Uint8Array(49 + offset + HEAD.length + compressed.length);
69
-
70
- array[26] = 0;
71
- array[27] = 0;
72
- array[28] = 0;
73
- array[24] = depth;
74
- array.set(HEAD, 0);
75
- array.set(__IHDR__, 12);
76
- array.set(__IDAT__, 37);
77
- array.set(compressed, 41);
78
- array[25] = channels_to_color_type[channels];
79
- if (text) array.set(text, 45 + compressed.length);
80
- array.set(__IEND__, 49 + offset + compressed.length);
81
-
82
- const view = new DataView(array.buffer);
83
-
84
- view.setUint32(8, 13);
85
- view.setUint32(16, width);
86
- view.setUint32(20, height);
87
- view.setUint32(33, compressed.length);
88
- view.setUint32(45 + offset + compressed.length, 0);
89
- view.setUint32(53 + offset + compressed.length, __IEND_CRC__);
90
- view.setUint32(29, crc32(new Uint8Array(array.buffer, 12, 17)));
91
- view.setUint32(41 + compressed.length, crc32(new Uint8Array(array.buffer, 37, 4 + compressed.length)));
92
-
93
- return array;
94
- }
95
-
96
- export function decode(array) {
97
- let view = new DataView(array.buffer, array.byteOffset, array.byteLength);
98
-
99
- const width = view.getUint32(16);
100
- const height = view.getUint32(20);
101
- const bpc = array[24];
102
- const pixel_type = array[25];
103
- let channels = ({ 3: 1, 0: 1, 4: 2, 2: 3, 6: 4 })[pixel_type];
104
- const bytespp = channels * bpc / 8;
105
-
106
- const row_length = width * bytespp;
107
- let pixels = new Uint8Array(height * row_length);
108
-
109
- let offset = 0;
110
- let p_offset = 0;
111
-
112
- let c_offset = 33;
113
- const chunks = [];
114
-
115
- let palette, alphaPalette;
116
-
117
- const maxSearchOffset = array.length - 5;
118
-
119
- let type;
120
- while ((type = view.getUint32(4 + c_offset)) !== 1229278788) { // IEND
121
- if (type === 1229209940) // IDAT
122
- chunks.push(array.subarray(8 + c_offset, 8 + c_offset + view.getUint32(c_offset)));
123
- else if (type === 1347179589) { // PLTE
124
- if (palette)
125
- throw new Error('PLTE can only occur once in an image');
126
- palette = new Uint32Array(view.getUint32(c_offset));
127
- for (let pxlOffset = 0; pxlOffset < palette.length * 8; pxlOffset += 3)
128
- palette[pxlOffset / 3] = array[8 + c_offset + pxlOffset] << 24 | array[8 + c_offset + pxlOffset + 1] << 16 | array[8 + c_offset + pxlOffset + 2] << 8 | 0xff;
129
- } else if (type === 1951551059) { // tRNS
130
- if (alphaPalette)
131
- throw new Error('tRNS can only occur once in an image');
132
- alphaPalette = new Uint8Array(view.getUint32(c_offset));
133
- for (let i = 0; i < alphaPalette.length; i++)
134
- alphaPalette[i] = array[8 + c_offset + i];
135
- }
136
-
137
- c_offset += 4 + 4 + 4 + view.getUint32(c_offset);
138
- if (c_offset > maxSearchOffset) // missing IEND
139
- break;
140
- }
141
-
142
- array = decompress(chunks.length === 1 ? chunks[0] : from_parts(chunks), height + height * row_length);
143
-
144
- while (offset < array.byteLength) {
145
- const filter = array[offset++];
146
- const slice = array.subarray(offset, offset += row_length);
147
-
148
- if (0 === filter) pixels.set(slice, p_offset);
149
- else if (1 === filter) filter_1(slice, pixels, p_offset, bytespp, row_length);
150
- else if (2 === filter) filter_2(slice, pixels, p_offset, bytespp, row_length);
151
- else if (3 === filter) filter_3(slice, pixels, p_offset, bytespp, row_length);
152
- else if (4 === filter) filter_4(slice, pixels, p_offset, bytespp, row_length);
153
-
154
- p_offset += row_length;
155
- }
156
-
157
- if (pixel_type === 3) {
158
- if (!palette)
159
- throw new Error('Indexed color PNG has no PLTE');
160
-
161
- if (alphaPalette)
162
- for (let i = 0; i < alphaPalette.length; i++)
163
- palette[i] &= 0xffffff00 | alphaPalette[i];
164
-
165
- channels = 4;
166
- const newPixels = new Uint8Array(width * height * 4);
167
- const pixelView = new DataView(newPixels.buffer, newPixels.byteOffset, newPixels.byteLength);
168
- for (let i = 0; i < pixels.length; i++)
169
- pixelView.setUint32(i * 4, palette[pixels[i]], false);
170
- pixels = newPixels;
171
- }
172
-
173
- if (bpc !== 8) {
174
- const newPixels = new Uint8Array(pixels.length / bpc * 8);
175
- for (let i = 0; i < pixels.length; i += 2)
176
- newPixels[i / 2] = pixels[i];
177
- pixels = newPixels;
178
- }
179
-
180
- if (channels !== 4) {
181
- const newPixels = new Uint8Array(width * height * 4);
182
- const view = new DataView(newPixels.buffer);
183
-
184
- if (channels === 1) {
185
- for (let i = 0; i < width * height; i++) {
186
- const pixel = pixels[i];
187
- view.setUint32(i * 4, pixel << 24 | pixel << 16 | pixel << 8 | 0xff, false);
188
- }
189
- } else if (channels === 2) {
190
- for (let i = 0; i < width * height * 2; i += 2) {
191
- const pixel = pixels[i];
192
- view.setUint32(i * 2, pixel << 24 | pixel << 16 | pixel << 8 | pixels[i + 1], false);
193
- }
194
- } else if (channels === 3) {
195
- newPixels.fill(0xff);
196
- for (let i = 0; i < width * height; i++)
197
- newPixels.set(pixels.subarray(i * 3, i * 3 + 3), i * 4);
198
- }
199
-
200
- pixels = newPixels;
201
- }
202
-
203
- return { width, height, buffer: pixels };
204
- }
205
-
206
- function filter_1(slice, pixels, p_offset, bytespp, row_length) {
207
- let i = 0;
208
- while (i < bytespp) pixels[i + p_offset] = slice[i++];
209
- while (i < row_length) pixels[i + p_offset] = slice[i] + pixels[i++ + p_offset - bytespp];
210
- }
211
-
212
- function filter_2(slice, pixels, p_offset, bytespp, row_length) {
213
- if (0 === p_offset) pixels.set(slice, p_offset);
214
- else {
215
- let i = 0;
216
- while (i < row_length) pixels[i + p_offset] = slice[i] + pixels[i++ + p_offset - row_length];
217
- }
218
- }
219
-
220
- function filter_3(slice, pixels, p_offset, bytespp, row_length) {
221
- let i = 0;
222
-
223
- if (0 === p_offset) {
224
- while (i < bytespp) pixels[i] = slice[i++];
225
- while (i < row_length) pixels[i] = slice[i] + (pixels[i++ - bytespp] >> 1);
226
- } else {
227
- while (i < bytespp) pixels[i + p_offset] = slice[i] + (pixels[i++ + p_offset - row_length] >> 1);
228
- while (i < row_length) pixels[i + p_offset] = slice[i] + (pixels[i + p_offset - bytespp] + pixels[i++ + p_offset - row_length] >> 1);
229
- }
230
- }
231
-
232
- function filter_4(slice, pixels, p_offset, bytespp, row_length) {
233
- let i = 0;
234
-
235
- if (0 === p_offset) {
236
- while (i < bytespp) pixels[i] = slice[i++];
237
- while (i < row_length) pixels[i] = slice[i] + pixels[i++ - bytespp];
238
- } else {
239
- while (i < bytespp) pixels[i + p_offset] = slice[i] + pixels[i++ + p_offset - row_length];
240
-
241
- while (i < row_length) {
242
- const a = pixels[i + p_offset - bytespp];
243
- const b = pixels[i + p_offset - row_length];
244
- const c = pixels[i + p_offset - bytespp - row_length];
245
-
246
- const p = a + b - c;
247
- const pa = Math.abs(p - a);
248
- const pb = Math.abs(p - b);
249
- const pc = Math.abs(p - c);
250
-
251
- pixels[i + p_offset] = slice[i++] + ((pa <= pb && pa <= pc) ? a : ((pb <= pc) ? b : c));
252
- }
253
- }
254
- }